[Qemu-devel] [PATCH] restore rw support for vvfat

2008-03-11 Thread Carlo Marcelo Arenas Belon
The attached patch, restores support for writable block devices using
Virtual FAT disk images.

RW support using a generated qcow base image was modified after qemu 0.8.2
was released; while adding AIO support to block-qcow.c in release 1.8; and
resulting in a broken qcow image based in an inexistent "fat:" base
when "fat:rw" was requested.

Carlo
Index: block-qcow.c
===
RCS file: /sources/qemu/qemu/block-qcow.c,v
retrieving revision 1.15
diff -u -r1.15 block-qcow.c
--- block-qcow.c11 Nov 2007 02:51:16 -  1.15
+++ block-qcow.c11 Mar 2008 07:29:00 -
@@ -752,11 +752,15 @@
 header_size = sizeof(header);
 backing_filename_len = 0;
 if (backing_file) {
-header.backing_file_offset = cpu_to_be64(header_size);
-backing_filename_len = strlen(backing_file);
-header.backing_file_size = cpu_to_be32(backing_filename_len);
-header_size += backing_filename_len;
-header.mtime = cpu_to_be32(0);
+if (strcmp(backing_file, "fat:")) {
+header.backing_file_offset = cpu_to_be64(header_size);
+backing_filename_len = strlen(backing_file);
+header.backing_file_size = cpu_to_be32(backing_filename_len);
+header_size += backing_filename_len;
+} else {
+/* special backing file for vvfat */
+backing_file = NULL;
+}
 header.cluster_bits = 9; /* 512 byte cluster to avoid copying
 unmodifyed sectors */
 header.l2_bits = 12; /* 32 KB L2 tables */


Re: [Qemu-devel] [PATCH] restore rw support for vvfat

2008-03-11 Thread Johannes Schindelin
Hi,

On Tue, 11 Mar 2008, Carlo Marcelo Arenas Belon wrote:

> The attached patch, restores support for writable block devices using 
> Virtual FAT disk images.
> 
> RW support using a generated qcow base image was modified after qemu 
> 0.8.2 was released; while adding AIO support to block-qcow.c in release 
> 1.8; and resulting in a broken qcow image based in an inexistent "fat:" 
> base when "fat:rw" was requested.

Acked-by: Johannes Schindelin <[EMAIL PROTECTED]>

Thanks,
Dscho




[Qemu-devel] Re: [PATCH] Slowdown SDL while minimized

2008-03-11 Thread Samuel Thibault
BTW, it would be good for power consumption to provide a virtual HPET
to the guest, and reprogram the host timer as appropriate.  10ms sleeps
kill kitten ;)

Samuel




[Qemu-devel] [PATCH] Slowdown SDL while minimized

2008-03-11 Thread Samuel Thibault
When SDL is invisible/minimized, there is no need to keep calling the
VGA refresh 33 times per second.  This patch reduces in that case the
rate to 2 times per second, which should be responsive enough for the
un-minimizing event.

Index: console.h
===
RCS file: /sources/qemu/qemu/console.h,v
retrieving revision 1.2
diff -u -p -r1.2 console.h
--- console.h   10 Feb 2008 16:33:13 -  1.2
+++ console.h   11 Mar 2008 11:05:08 -
@@ -71,6 +71,7 @@
 int height;
 void *opaque;
 struct QEMUTimer *gui_timer;
+uint64_t gui_timer_interval;
 
 void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
 void (*dpy_resize)(struct DisplayState *s, int w, int h);
Index: sdl.c
===
RCS file: /sources/qemu/qemu/sdl.c,v
retrieving revision 1.46
--- sdl.c   10 Mar 2008 19:34:27 -  1.46
+++ sdl.c   11 Mar 2008 11:05:08 -
@@ -506,6 +506,15 @@
 !ev->active.gain && !gui_fullscreen_initial_grab) {
 sdl_grab_end();
 }
+   if (ev->active.state & SDL_APPACTIVE) {
+   if (ev->active.gain) {
+   /* Back to default interval */
+   ds->gui_timer_interval = 0;
+   } else {
+   /* Sleeping interval */
+   ds->gui_timer_interval = 500;
+   }
+   }
 break;
 default:
 break;
Index: vl.c
===
RCS file: /sources/qemu/qemu/vl.c,v
retrieving revision 1.410
--- vl.c10 Mar 2008 19:34:27 -  1.410
+++ vl.c11 Mar 2008 11:05:09 -
@@ -7208,7 +7200,11 @@
 {
 DisplayState *ds = opaque;
 ds->dpy_refresh(ds);
-qemu_mod_timer(ds->gui_timer, GUI_REFRESH_INTERVAL + 
qemu_get_clock(rt_clock));
+qemu_mod_timer(ds->gui_timer,
+(ds->gui_timer_interval ?
+   ds->gui_timer_interval :
+   GUI_REFRESH_INTERVAL)
+   + qemu_get_clock(rt_clock));
 }
 
 struct vm_change_state_entry {




[Qemu-devel] qemu block-qcow.c block-qcow2.c block-vmdk.c bl...

2008-03-11 Thread Aurelien Jarno
CVSROOT:/sources/qemu
Module name:qemu
Changes by: Aurelien Jarno 08/03/11 17:17:59

Modified files:
.  : block-qcow.c block-qcow2.c block-vmdk.c block.c 
 block.h block_int.h 

Log message:
Fix CVE-2008-0928 - insufficient block device address range checking

Qemu 0.9.1 and earlier does not perform range checks for block device
read or write requests, which allows guest host users with root
privileges to access arbitrary memory and escape the virtual machine.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/block-qcow.c?cvsroot=qemu&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/qemu/block-qcow2.c?cvsroot=qemu&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/qemu/block-vmdk.c?cvsroot=qemu&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/qemu/block.c?cvsroot=qemu&r1=1.54&r2=1.55
http://cvs.savannah.gnu.org/viewcvs/qemu/block.h?cvsroot=qemu&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/qemu/block_int.h?cvsroot=qemu&r1=1.16&r2=1.17




Re: [Qemu-devel] qemu block-qcow.c block-qcow2.c block-vmdk.c bl...

2008-03-11 Thread Fabrice Bellard
IMHO it would be much simpler to do all the tests in the block format 
handlers.


Fabrice.

Aurelien Jarno wrote:

CVSROOT:/sources/qemu
Module name:qemu
Changes by: Aurelien Jarno   08/03/11 17:17:59

Modified files:
	.  : block-qcow.c block-qcow2.c block-vmdk.c block.c 
	 block.h block_int.h 


Log message:
Fix CVE-2008-0928 - insufficient block device address range checking

Qemu 0.9.1 and earlier does not perform range checks for block device
read or write requests, which allows guest host users with root
privileges to access arbitrary memory and escape the virtual machine.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/block-qcow.c?cvsroot=qemu&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/qemu/block-qcow2.c?cvsroot=qemu&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/qemu/block-vmdk.c?cvsroot=qemu&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/qemu/block.c?cvsroot=qemu&r1=1.54&r2=1.55
http://cvs.savannah.gnu.org/viewcvs/qemu/block.h?cvsroot=qemu&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/qemu/block_int.h?cvsroot=qemu&r1=1.16&r2=1.17









[Qemu-devel] qemu/target-sparc translate.c

2008-03-11 Thread Blue Swirl
CVSROOT:/cvsroot/qemu
Module name:qemu
Changes by: Blue Swirl   08/03/11 20:59:03

Modified files:
target-sparc   : translate.c 

Log message:
 Use a TCG global for regwptr

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sparc/translate.c?cvsroot=qemu&r1=1.100&r2=1.101




[Qemu-devel] qemu osdep.h tcg/tcg.c tcg/i386/tcg-target.c tc...

2008-03-11 Thread Blue Swirl
CVSROOT:/cvsroot/qemu
Module name:qemu
Changes by: Blue Swirl   08/03/11 21:01:03

Modified files:
.  : osdep.h 
tcg: tcg.c 
tcg/i386   : tcg-target.c 
tcg/sparc  : tcg-target.c 
tcg/x86_64 : tcg-target.c 

Log message:
 Remove blank elements in tcg_target_reg_alloc_order[] (Stuart Brady)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/osdep.h?cvsroot=qemu&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/qemu/tcg/tcg.c?cvsroot=qemu&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/qemu/tcg/i386/tcg-target.c?cvsroot=qemu&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/qemu/tcg/sparc/tcg-target.c?cvsroot=qemu&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/qemu/tcg/x86_64/tcg-target.c?cvsroot=qemu&r1=1.4&r2=1.5




Re: [Qemu-devel] qemu block-qcow.c block-qcow2.c block-vmdk.c bl...

2008-03-11 Thread Aurelien Jarno
Fabrice Bellard a écrit :
> IMHO it would be much simpler to do all the tests in the block format
> handlers.
> 

Do you mean move all the tests into block-{qcow,qcow2,vmdk}.c ?


> Aurelien Jarno wrote:
>> CVSROOT:/sources/qemu
>> Module name:qemu
>> Changes by:Aurelien Jarno 08/03/11 17:17:59
>>
>> Modified files:
>> .  : block-qcow.c block-qcow2.c block-vmdk.c block.c
>>  block.h block_int.h
>> Log message:
>> Fix CVE-2008-0928 - insufficient block device address range checking
>> 
>> Qemu 0.9.1 and earlier does not perform range checks for block device
>> read or write requests, which allows guest host users with root
>> privileges to access arbitrary memory and escape the virtual machine.
>>
>> CVSWeb URLs:
>> http://cvs.savannah.gnu.org/viewcvs/qemu/block-qcow.c?cvsroot=qemu&r1=1.15&r2=1.16
>>
>> http://cvs.savannah.gnu.org/viewcvs/qemu/block-qcow2.c?cvsroot=qemu&r1=1.10&r2=1.11
>>
>> http://cvs.savannah.gnu.org/viewcvs/qemu/block-vmdk.c?cvsroot=qemu&r1=1.19&r2=1.20
>>
>> http://cvs.savannah.gnu.org/viewcvs/qemu/block.c?cvsroot=qemu&r1=1.54&r2=1.55
>>
>> http://cvs.savannah.gnu.org/viewcvs/qemu/block.h?cvsroot=qemu&r1=1.6&r2=1.7
>>
>> http://cvs.savannah.gnu.org/viewcvs/qemu/block_int.h?cvsroot=qemu&r1=1.16&r2=1.17
>>
>>
>>
>>
> 
> 
> 
> 


-- 
  .''`.  Aurelien Jarno | GPG: 1024D/F1BCDB73
 : :' :  Debian developer   | Electrical Engineer
 `. `'   [EMAIL PROTECTED] | [EMAIL PROTECTED]
   `-people.debian.org/~aurel32 | www.aurel32.net




Re: [Qemu-devel] qemu block-qcow.c block-qcow2.c block-vmdk.c bl...

2008-03-11 Thread Fabrice Bellard
Aurelien Jarno wrote:
> Fabrice Bellard a écrit :
>> IMHO it would be much simpler to do all the tests in the block format
>> handlers.
>>
> 
> Do you mean move all the tests into block-{qcow,qcow2,vmdk}.c ?

I suggest reverting the patch and writing correct tests in
block-{qcow,qcow2,vmdk}.c. BTW, bs->total_sectors is not a good
indicator of the device size in case of removable devices for example.

Fabrice.




Re: [Qemu-devel] [PATCH] Modify qemu-img to mount locally disk image using NBD (v2)

2008-03-11 Thread Fabrice Bellard
Laurent Vivier wrote:
> This patch is a new version of qemu-img using NBD device to mount Qemu
> disk image.
> 
> To not hang on UP system, it needs following patch:
> http://article.gmane.org/gmane.linux.drivers.nbd.general/42
> If you want to use loop to see partitions, you need this patch:
> http://article.gmane.org/gmane.linux.kernel/651269
> otherwise use kpartx (see kpartx package of your distro).
> 
> This patch implements in qemu-img the client and the server of the nbd 
> protocol.
> Moreover, to avoid to specify a port to use, it creates a UNIX socket instead 
> of
> a INET socket.
> 
> It adds two actions to qemu-img:
> - bind, to bind a disk image to a NBD device,
> 
>   qemu-img bind [-d] [-f fmt] device filename
> 
>  ('-d' to daemonize)
> 
> - unbind, to unbind it.
> 
>   qemu-img unbind device
> [...]

Perhaps adding a new specialized tool would be better as there is no
direct relation with qemu-img.

Fabrice.




Re: [Qemu-devel] Re: [PATCH] e1000: fix endianness issues

2008-03-11 Thread Aurelien Jarno
On Sat, Mar 08, 2008 at 11:08:48AM -0600, Hollis Blanchard wrote:
> On Sat, 2008-03-08 at 14:59 +0100, Aurelien Jarno wrote: 
> > On Fri, Mar 07, 2008 at 11:23:51AM -0600, Hollis Blanchard wrote:
> > > Below is a patch I'm using to fix rtl8139.c for PowerPC/PowerPC
> > > target/host combination. It works enough for the target to send a DHCP
> > > request and get a response from slirp, but other unrelated bugs prevent
> > > me from testing it more thoroughly. (I'm only sending it now at
> > > Aurelien's request.) Other code that I know is broken (because I've
> > > tried to use it) include isa_mmio.c and pci_host.h, but I don't have
> > > patches for these at this time.
> > 
> > 
> > 
> > 
> > > Fix endianness conversion in rtl8139.c.
> > > 
> > > PCI data is always in LE format, so convert from LE at the interface to
> > > "qemu endianness" internally, then convert again on the way back out.
> > > 
> > > Signed-off-by: Hollis Blanchard <[EMAIL PROTECTED]>
> > > 
> > > diff --git a/qemu/hw/rtl8139.c b/qemu/hw/rtl8139.c
> > > --- a/qemu/hw/rtl8139.c
> > > +++ b/qemu/hw/rtl8139.c

[snip]
 
> > > @@ -3091,12 +3067,12 @@ static void rtl8139_mmio_writeb(void *op
> > >  
> > >  static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, 
> > > uint32_t val)
> > >  {
> > > -rtl8139_io_writew(opaque, addr & 0xFF, val);
> > > +rtl8139_io_writew(opaque, addr & 0xFF, le16_to_cpu(val));
> > >  }
> > >  
> > >  static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, 
> > > uint32_t val)
> > >  {
> > > -rtl8139_io_writel(opaque, addr & 0xFF, val);
> > > +rtl8139_io_writel(opaque, addr & 0xFF, le32_to_cpu(val));
> > >  }
> > >  
> > >  static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
> > > @@ -3106,12 +3082,12 @@ static uint32_t rtl8139_mmio_readb(void 
> > >  
> > >  static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
> > >  {
> > > -return rtl8139_io_readw(opaque, addr & 0xFF);
> > > +return cpu_to_le16(rtl8139_io_readw(opaque, addr & 0xFF));
> > >  }
> > >  
> > >  static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
> > >  {
> > > -return rtl8139_io_readl(opaque, addr & 0xFF);
> > > +return cpu_to_le32(rtl8139_io_readl(opaque, addr & 0xFF));
> > >  }
> > >  
> > 
> > Are those changes really necessary? The rtl8139 emulation works
> > correctly on a big endian host (tested with an i386 target). This part
> > of the patch would probably break it. Unless the Linux driver only does
> > byte accesses, which are not changed by this patch.

I have tested this part of the patch on a big endian host (PowerPC), and
I confirm it breaks the rtl8139 emulation (tested on i386 and mipsel
targets).

> Hmm, yes, there is a problem with this patch. In the "touching many
> 1-byte registers as a single 4-byte access" change to rtl8139_io_readl()
> above, we made sure that the result was LE. What we should have done is
> make it host-endianness like all the other return values from
> rtl8139_io_readl(). Then in rtl8139_mmio_readl(), we know we must swap
> host->LE.
> 
> I don't know why rtl8139 would work today with LE/BE target/host, but if
> it does, it must be due to swapping in another layer, because this patch
> is the right thing to do here. If qemu currently swaps 5 times and that
> comes out the same as swapping once, we still need to fix it... :)

I hope the discussion on IRC last week-end convinced you that you don't
need to swap the value depending on the host endianness. For those who
haven't followed the discussion, qemu does memory accesses with a couple
(address, value). The addresses and values are always stored in host 
endianness, and this does not need to be swapped depending on the host. 
It may have to be swapped depending on the target, if the value is 
swapped on the real hardware (bus connected backward, chipset, etc.)

Thanks to Paul Brook for all the explanations.

Basically that means that one part of my e1000 part is actually correct,
while the other is correct in the case of the MIPS Malta machine, but
may be wrong for other targets/machines. I am therefore planning to 
commit the correct part (see patch below), except if someone still have
some comments on it.


diff --git a/hw/e1000.c b/hw/e1000.c
index 1c77afc..e3dbef9 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -721,7 +721,7 @@ e1000_mmio_writel(void *opaque, target_phys_addr_t addr, 
uint32_t val)
 unsigned int index = ((addr - s->mmio_base) & 0x1) >> 2;
 
 if (index < NWRITEOPS && macreg_writeops[index])
-macreg_writeops[index](s, index, le32_to_cpu(val));
+macreg_writeops[index](s, index, val);
 else if (index < NREADOPS && macreg_readops[index])
 DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
 else
@@ -734,7 +734,7 @@ e1000_mmio_writew(void *opaque, target_phys_addr_t addr, 
uint32_t val)
 {
 // emulate hw without byte enables: no RMW
 e1000_mmio_writel(opaqu

Re: [Qemu-devel] qemu block-qcow.c block-qcow2.c block-vmdk.c bl...

2008-03-11 Thread Aurelien Jarno
On Tue, Mar 11, 2008 at 11:43:47PM +0100, Fabrice Bellard wrote:
> Aurelien Jarno wrote:
> > Fabrice Bellard a écrit :
> >> IMHO it would be much simpler to do all the tests in the block format
> >> handlers.
> >>
> > 
> > Do you mean move all the tests into block-{qcow,qcow2,vmdk}.c ?
> 
> I suggest reverting the patch and writing correct tests in
> block-{qcow,qcow2,vmdk}.c. BTW, bs->total_sectors is not a good
> indicator of the device size in case of removable devices for example.
> 

I see. I will work on writing a patch asap, probably tomorrow evening.

Aurelien

-- 
  .''`.  Aurelien Jarno | GPG: 1024D/F1BCDB73
 : :' :  Debian developer   | Electrical Engineer
 `. `'   [EMAIL PROTECTED] | [EMAIL PROTECTED]
   `-people.debian.org/~aurel32 | www.aurel32.net




Re: [PATCH][Qemu-devel] Single stepping for PPC broken!

2008-03-11 Thread Jason Wessel
Marius Groeger wrote:
> On Wed, 9 Jan 2008, Marius Groeger wrote:
>
>   
>> On Wed, 9 Jan 2008, Marius Groeger wrote:
>>
>> 
>>> I'm having problems with qemu's (-M prep, -cpu 604) handling of the 
>>> MSR_SE bit. My gdbstub can successfully step along regular code, but 
>>> qemu chokes when stepping over a branch instruction like "blr". 
>>> (Needless to say, that same gdbstub works fine on real hardware). I 
>>> tried older versions of qemu and found that the code base 8 months ago 
>>> worked fine.
>>>   
>> I have now verified with booting a Linux image into qemu-system-ppc - same
>> problem. When stepi'ing over the following sequence, the system chokes on a
>> "bl" instruction:
>> 
>
> The attached patch fixes the problem, but I have to admit I can't tell 
> for sure if this doesn't break other things (such as qemu's built-in 
> GDB server). Could some QEMU ppc expert please comment on this?
>
> Thanks
> Marius
>
>   

The patch you originally attached definitely breaks the back end
debugger connection for qemu.  It does point to the heart of the problem
though.  The back end debugger uses the same variable to control the
single stepping state as the MSR_SE uses.

Attached is a patch that fixes the issue, as well as a generic problem
in cvs latest where the backend debugger is occasionally missing debug
exceptions on all archs.


Jason.

- Fix generic single step problem in vl.c
  * Overwriting the ret code when there was
and interrupt pending causes the debugger
to miss exceptions

- For ppc, split run-time single stepping from the
  debugger stub single stepping
  * This fixes the hang problems when using single
stepping via the msr_se


Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>

---
 target-ppc/translate.c |   14 --
 vl.c   |4 ++--
 2 files changed, 14 insertions(+), 4 deletions(-)

--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -150,6 +150,7 @@ typedef struct DisasContext {
 int spe_enabled;
 ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
 int singlestep_enabled;
+int sys_sstep_enabled;
 int dcache_line_size;
 } DisasContext;
 
@@ -2802,8 +2803,10 @@ static always_inline void gen_goto_tb (D
 else
 #endif
 gen_op_b_T1();
-if (ctx->singlestep_enabled)
+   if (unlikely(ctx->sys_sstep_enabled)) {
+gen_update_nip(ctx, ctx->nip);
 gen_op_debug();
+}
 tcg_gen_exit_tb(0);
 }
 }
@@ -2984,8 +2987,10 @@ static always_inline void gen_bcond (Dis
 #endif
 gen_op_btest_T1(ctx->nip);
 no_test:
-if (ctx->singlestep_enabled)
+if (ctx->sys_sstep_enabled) {
+gen_update_nip(ctx, ctx->nip);
 gen_op_debug();
+}
 tcg_gen_exit_tb(0);
 }
  out:
@@ -6190,6 +6195,7 @@ static always_inline int gen_intermediat
 branch_step = 1;
 else
 branch_step = 0;
+ctx.sys_sstep_enabled = env->singlestep_enabled;
 ctx.singlestep_enabled = env->singlestep_enabled || single_step == 1;
 #if defined (DO_SINGLE_STEP) && 0
 /* Single step trace mode */
@@ -6306,6 +6312,10 @@ static always_inline int gen_intermediat
 if (ctx.exception == POWERPC_EXCP_NONE) {
 gen_goto_tb(&ctx, 0, ctx.nip);
 } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
+if (unlikely(ctx.sys_sstep_enabled)) {
+gen_update_nip(&ctx, ctx.nip);
+gen_op_debug();
+}
 /* Generate the return instruction */
 tcg_gen_exit_tb(0);
 }
--- a/vl.c
+++ b/vl.c
@@ -7523,7 +7523,7 @@ static int main_loop(void)
 qemu_time += profile_getclock() - ti;
 #endif
 next_cpu = env->next_cpu ?: first_cpu;
-if (event_pending) {
+if (event_pending && likely(ret != EXCP_DEBUG)) {
 ret = EXCP_INTERRUPT;
 event_pending = 0;
 break;
@@ -7555,7 +7555,7 @@ static int main_loop(void)
 		qemu_system_powerdown();
 ret = EXCP_INTERRUPT;
 }
-if (ret == EXCP_DEBUG) {
+if (unlikely(ret == EXCP_DEBUG)) {
 vm_stop(EXCP_DEBUG);
 }
 /* If all cpus are halted then wait until the next IRQ */


[Qemu-devel] qemu/target-sh4 op.c translate.c

2008-03-11 Thread Aurelien Jarno
CVSROOT:/sources/qemu
Module name:qemu
Changes by: Aurelien Jarno 08/03/11 23:22:37

Modified files:
target-sh4 : op.c translate.c 

Log message:
SH4, fix several instructions

fix instruction code for frchg, fschg, ocbp.
fix addressing mode handling for @Rn+, @-Rn, @(disp,gbr).
fix operation for div0s.
fix comments for mov imm, add imm, @(r0+,gbr), mac.l @Rm+,@Rn+.
fix ldb to ldub for or/tst/xor.b #imm,@(r0,gbr).
add fmov extended operations.
add fcmp/eq, fcmp/gt, fneg, fabs, fsqrt, fcnvsd, fcnvds.

(Takashi Yoshii)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sh4/op.c?cvsroot=qemu&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/qemu/target-sh4/translate.c?cvsroot=qemu&r1=1.22&r2=1.23




[Qemu-devel] qemu block-qcow.c block-qcow2.c block-vmdk.c bl...

2008-03-11 Thread Aurelien Jarno
CVSROOT:/sources/qemu
Module name:qemu
Changes by: Aurelien Jarno 08/03/11 23:30:22

Modified files:
.  : block-qcow.c block-qcow2.c block-vmdk.c block.c 
 block.h block_int.h 
linux-user : syscall.c 

Log message:
Revert fix for CVE-2008-0928. Will be fixed in a different way later.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/block-qcow.c?cvsroot=qemu&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/qemu/block-qcow2.c?cvsroot=qemu&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/qemu/block-vmdk.c?cvsroot=qemu&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/qemu/block.c?cvsroot=qemu&r1=1.55&r2=1.56
http://cvs.savannah.gnu.org/viewcvs/qemu/block.h?cvsroot=qemu&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/qemu/block_int.h?cvsroot=qemu&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/qemu/linux-user/syscall.c?cvsroot=qemu&r1=1.164&r2=1.165




Re: [Qemu-devel] [PATCH] x86 Multiboot support (extended)

2008-03-11 Thread Aurelien Jarno
On Thu, Jan 31, 2008 at 06:31:09PM +0100, Alexander Graf wrote:
>
> On Jan 31, 2008, at 10:58 AM, Kevin Wolf wrote:
>
>> Hi,
>>
>> I like this idea. When I just tried to load my multiboot kernel it
>> failed, though, because of the following piece of code:
>>
>>> +// XXX: multiboot header may be within the first 8192 bytes,  
>>> but header
>>> +//  is only the first 1024
>>> +
>>> +// Ok, let's see if it is a multiboot image
>>> +for(i=0; i<(256 - 12); i+=4) { // the header is 12x32bit long
>>> +if(ldl_p(header+i) == 0x1BADB002) {
>>
>> I wonder if there is any reason why you didn't just replace the 1024  
>> by
>> 8192 in load_linux but added an XXX. Would this cause any problems I
>> missed? With this change and replacing 256 by 8192 in the above code  
>> it
>> works for my kernel, too.
>>
>> Anyway, I think the for condition should be i < 4 * (256 - 12), even
>> without changing the 1024.
>
> This version should fix the long header issue. I made the linux loader  
> fetch the first 8kb as header, so multiboot can search through all  
> necessary data.
>
> I also implemented module parameters. Kevin needed this to boot a  
> homebrew kernel. You can now pass commandline parameters to the  
> multiboot modules by adding them after the filename, seperated through a 
> space. This is the very same approach grub takes.
>
> To boot a xen kernel you would give a command line like this:
>
> qemu -hda image -kernel xen -initrd "vmlinux-xen root=/dev/hda,initrd- 
> xen"
>
> This way the vmlinux module gets the command line parameter "root=/dev/ 
> hda".
>
> 
> diff --git a/elf_ops.h b/elf_ops.h
> index 6126565..ab5fd7b 100644
> --- a/elf_ops.h
> +++ b/elf_ops.h
> @@ -156,6 +156,10 @@ static int glue(load_elf, SZ)(int fd, int64_t 
> virt_to_phys_addend,
>  }
>  
>  if (ELF_MACHINE != ehdr.e_machine)
> +#if (ELF_MACHINE == EM_X86_64) && !CONFIG_USER_ONLY
> +  /* x86_64 systems can run i386 code as well */
> +  if(ehdr.e_machine != EM_386)
> +#endif
>  goto fail;
>  
>  if (pentry)
> diff --git a/hw/pc.c b/hw/pc.c
> index b4f0db7..4c5ee94 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -480,6 +480,416 @@ static long get_file_size(FILE *f)
>  return size;
>  }
>  
> +/* Generate an initial boot sector which sets state and jump to
> +   a specified vector */
> +static void generate_bootsect_multiboot(uint32_t mh_entry_addr, uint32_t 
> bootinfo)
> +{
> +uint8_t bootsect[512], *p, *pgdt, *pmmaploop;
> +uint32_t ip;
> +int i;
> +int hda;
> +int mmaploop;
> +
> +hda = drive_get_index(IF_IDE, 0, 0);
> +if (hda == -1) {
> + fprintf(stderr, "A disk image must be given for 'hda' when booting "
> + "a Multiboot kernel\n");
> + exit(1);
> +}
> +
> +memset(bootsect, 0, sizeof(bootsect));
> +
> +/* Copy the MSDOS partition table if possible */
> +bdrv_read(drives_table[hda].bdrv, 0, bootsect, 1);
> +
> +/* Make sure we have a partition signature */
> +bootsect[510] = 0x55;
> +bootsect[511] = 0xaa;
> +
> +/* Actual code */
> +p = bootsect;
> +*p++ = 0xfa;/* CLI */
> +*p++ = 0xfc;/* CLD */
> +
> +// 660f01152800   lgdt[0x28]
> +*p++ = 0x66;/* 32-bit operand size */
> +*p++ = 0x67;/* 32-bit addr size */
> +*p++ = 0x0f;/* LGDT [0x128] */
> +*p++ = 0x01;
> +*p++ = 0x15;
> +pgdt=p; /* we calculate the gdt position later */
> +p+=4;
> +
> +/* Initialize multiboot mmap structs using the 0x15(e820) */
> +*p++ = 0x31;/* XOR BX,BX */
> +*p++ = 0xdb;
> +
> +*p++ = 0x66;/* 32-bit operand size */
> +*p++ = 0x67;/* 32-bit addr size */
> +*p++ = 0xbf;/* MOV EDI,0x9004 */
> +*p++ = 0x04;
> +*p++ = 0x90;
> +*p++ = 0x00;
> +*p++ = 0x00;
> +
> +pmmaploop = p;
> +*p++ = 0x66;/* 32-bit operand size */
> +*p++ = 0x67;/* 32-bit addr size */
> +*p++ = 0xb8;/* MOV EAX,0x20 */
> +*p++ = 0x20;
> +*p++ = 0x00;
> +*p++ = 0x00;
> +*p++ = 0x00;
> +
> +*p++ = 0x66;/* 32-bit operand size */
> +*p++ = 0x67;/* 32-bit addr size */
> +*p++ = 0x89;/* MOV -4(EDI),EAX */
> +*p++ = 0x47;
> +*p++ = 0xfc;
> +
> +*p++ = 0x66;/* 32-bit operand size */
> +*p++ = 0x67;/* 32-bit addr size */
> +*p++ = 0xb8;/* MOV EAX,0xe820 */
> +*p++ = 0x20;
> +*p++ = 0xe8;
> +*p++ = 0x00;
> +*p++ = 0x00;
> +
> +*p++ = 0x66;/* 32-bit operand size */
> +*p++ = 0x67;/* 32-bit addr size */
> +*p++ = 0xba;/* MOV EDX,0x534d4150 */
> +*p++ = 0x50;
> +*p++ = 0x41;
> +*p++ = 0x4d;
> +*p++ = 0x53;
> +
> +*p++ = 0x66;

Re: [Qemu-devel] Re: 2.6.24 says "serial8250: too much work for irq4" a lot.

2008-03-11 Thread Aurelien Jarno
On Sun, Feb 10, 2008 at 11:26:06AM +, Paul Brook wrote:
> On Sunday 10 February 2008, Blue Swirl wrote:
> > On 2/9/08, H. Peter Anvin <[EMAIL PROTECTED]> wrote:
> > > Blue Swirl wrote:
> > > >> If you look at the patch, there are no timing dependencies; the only
> > > >> parameter is the depth of the virtual queue.  The exhaustion is
> > > >> completely controlled by target OS access patterns.
> > > >
> > > > Thanks, this clarified the difference. But I'll rephrase my original
> > > > comment:
> > > >
> > > > The patch looks OK, but the simulated FIFO exhaustion should benefit
> > > > all devices, as
> > > > discussed here:
> > > > http://lists.gnu.org/archive/html/qemu-devel/2007-12/msg00283.html
> > >
> > > The difference is you *can't* do that in a general layer.
> >
> > What makes you think that is impossible? 
> 
> IIUC the proposed patch makes the serial driver return an empty FIFO exactly 
> once, them immediately continue receiving data. Throughput should be 
> approximately the same, you've just got a bit of extra overhead to process 
> the additional interrupts.  This is very different to the previous patch 
> which did time-based throughput limiting.
> 
> You can't do this in generic code because there's no way to guess when the 
> guest os has seen the FIFO empty condition. The best you can do is pause for 
> some arbitrary length of time, which is both unreliable (the guest OS may not 
> have got to far enough yet, especially if the host machine is heavily 
> loaded), and has a significant negative impact on throughput.
> 
> > Also win2k install hack in ide.c seems to be related to this problem,
> > so even more generic solution would be desirable.
> 
> IIUC the win2k hack is an actual timing problem. The win2k IDE drivers are 
> buggy, and fall over if the drive responds too soon.
> 

Is everybody convinced about this patch now? I would really like to see
it in the CVS, as it greatly improves the usability of the serial 
consoles on targets running GNU/Linux (and probably OSes).

-- 
  .''`.  Aurelien Jarno | GPG: 1024D/F1BCDB73
 : :' :  Debian developer   | Electrical Engineer
 `. `'   [EMAIL PROTECTED] | [EMAIL PROTECTED]
   `-people.debian.org/~aurel32 | www.aurel32.net




Re: [Qemu-devel] [PATCH] Slowdown SDL while minimized

2008-03-11 Thread Anders

Samuel Thibault wrote:

When SDL is invisible/minimized, there is no need to keep calling the
VGA refresh 33 times per second.  This patch reduces in that case the
rate to 2 times per second, which should be responsive enough for the
un-minimizing event.
  


Is there any need to update at all, if the canvas is not visible? How 
about some infrastructure for pausing the update completely? I think 
that could also be used for VNC displays, when no client is connected.


Anders.





Re: [Qemu-devel] [PATCH] fix ncurses output

2008-03-11 Thread Aurelien Jarno
On Mon, Feb 25, 2008 at 06:48:06PM +0100, Bernhard Kauer wrote:
> The ncurses console uses mvwaddchnstr() to print a line of output
> to a ncurses pad. Unfortunately this routine stops to print further
> chars if a zero-char is seen in the line. This has the effect that
> parts of a line are never redraw.

Do you have a simple testcase (program to run, code, ...). I have been
unable to reproduce this problem here.

> The following patch puts spaces instead of the zeros into the line-buffer.
> Please note that this change affects other consoles as well and is
> perhaps undesirable. Comments?

I am not sure replacing zeros into spaces is correct. Zeros are not
supposed to be displayed, contrary to spaces.

Aurelien
 
> Index: console.h
> --- console.h 10 Feb 2008 16:33:13 -  1.2
> +++ console.h 25 Feb 2008 17:25:53 -
> @@ -104,7 +104,8 @@
>  typedef unsigned long console_ch_t;
>  static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
>  {
> -cpu_to_le32wu((uint32_t *) dest, ch);
> +  if (!(ch & 0xff))  ch = 0x20;
> +  cpu_to_le32wu((uint32_t *) dest, ch);
>  }
>  
>  typedef void (*vga_hw_update_ptr)(void *);


-- 
  .''`.  Aurelien Jarno | GPG: 1024D/F1BCDB73
 : :' :  Debian developer   | Electrical Engineer
 `. `'   [EMAIL PROTECTED] | [EMAIL PROTECTED]
   `-people.debian.org/~aurel32 | www.aurel32.net




Re: [Qemu-devel] [PATCH] Slowdown SDL while minimized

2008-03-11 Thread Samuel Thibault
Anders, le Wed 12 Mar 2008 00:56:42 +0100, a écrit :
> Samuel Thibault wrote:
> >When SDL is invisible/minimized, there is no need to keep calling the
> >VGA refresh 33 times per second.  This patch reduces in that case the
> >rate to 2 times per second, which should be responsive enough for the
> >un-minimizing event.
> >  
> 
> Is there any need to update at all, if the canvas is not visible?

Indeed not. We however still need to have a look at the SDL queue, to
detect the un-minimize event.

> How about some infrastructure for pausing the update completely? I
> think that could also be used for VNC displays, when no client is
> connected.

Actually in Xen it goes even further: when the client hasn't sent an
update request since a long time, the VNC server assumes the client is
minimized, and in pratice that is the case.

Samuel




[Qemu-devel] [patch 02/24] QEMU/KVM: add OperationRegion and GPE handler for add/removal notification

2008-03-11 Thread Marcelo Tosatti
Use GPE _L01 to notify OSPM.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
===
--- kvm-userspace.hotplug2.orig/bios/acpi-dsdt.dsl
+++ kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
@@ -407,6 +407,13 @@ DefinitionBlock (
 Package() {0x001f, 3, LNKB, 0},
 })
 
+OperationRegion(PCST, SystemIO, 0xae00, 0x08)
+Field (PCST, DWordAcc, NoLock, WriteAsZeros)
+   {
+   PCIU, 32,
+   PCID, 32,
+   }
+
 Device (S1) {  // Slot 1
Name (_ADR, 0x0001)
Method (_EJ0,1) { Return (0x0) }
@@ -1142,6 +1149,256 @@ DefinitionBlock (
 Return(0x01)
 }
 Method(_L01) {
+/* Up status */
+If (And(\_SB.PCI0.PCIU, 0x2)) {
+Notify(\_SB.PCI0.S1, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x4)) {
+Notify(\_SB.PCI0.S2, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x8)) {
+Notify(\_SB.PCI0.S3, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x10)) {
+Notify(\_SB.PCI0.S4, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x20)) {
+Notify(\_SB.PCI0.S5, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x40)) {
+Notify(\_SB.PCI0.S6, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x80)) {
+Notify(\_SB.PCI0.S7, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x0100)) {
+Notify(\_SB.PCI0.S8, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x0200)) {
+Notify(\_SB.PCI0.S9, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x0400)) {
+Notify(\_SB.PCI0.S10, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x0800)) {
+Notify(\_SB.PCI0.S11, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x1000)) {
+Notify(\_SB.PCI0.S12, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x2000)) {
+Notify(\_SB.PCI0.S13, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x4000)) {
+Notify(\_SB.PCI0.S14, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x8000)) {
+Notify(\_SB.PCI0.S15, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x1)) {
+Notify(\_SB.PCI0.S16, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x2)) {
+Notify(\_SB.PCI0.S17, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x4)) {
+Notify(\_SB.PCI0.S18, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x8)) {
+Notify(\_SB.PCI0.S19, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x10)) {
+Notify(\_SB.PCI0.S20, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x20)) {
+Notify(\_SB.PCI0.S21, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x40)) {
+Notify(\_SB.PCI0.S22, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x80)) {
+Notify(\_SB.PCI0.S23, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x100)) {
+Notify(\_SB.PCI0.S24, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x200)) {
+Notify(\_SB.PCI0.S25, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x400)) {
+Notify(\_SB.PCI0.S26, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x800)) {
+Notify(\_SB.PCI0.S27, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x1000)) {
+Notify(\_SB.PCI0.S28, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x2000)) {
+Notify(\_SB.PCI0.S29, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x4000)) {
+Notify(\_SB.PCI0.S30, 0x1)
+}
+
+If (And(\_SB.PCI0.PCIU, 0x8000)) {
+Notify(\_SB.PCI0.S31, 0x1)
+}
+
+/* Down status */
+If (And(\_SB.PCI0.PCID, 0x2)) {
+Notify(\_SB.PCI0.S1, 0x3)
+}
+
+If (And(\_SB.PCI0.PCID, 0x4)) {
+Notify(\_SB.PCI0.S2, 0x3)
+}
+
+If (And(\_SB.PCI0.PCID, 0x8)) {
+Notify(\_SB.PCI0.S3, 0x3)
+}
+
+If (And(\_SB.PCI0.PCID, 0x10)) {
+Notify(\_SB.PCI0.S4, 0x3)
+}
+
+If (And(\_SB.PCI0.PCID, 0x20)) {
+Notify(\_SB.PCI0.S5, 0x3)
+}
+
+If (And(\_SB.PCI0.PCID, 0x40)) {
+Notify(\_SB.PCI0.S6, 0x3)
+}
+
+If (And(\_SB.PCI0.PCID, 0x80)) {
+Not

[Qemu-devel] [patch 01/24] QEMU/KVM: add devices to represent PCI slots with _EJ0 method

2008-03-11 Thread Marcelo Tosatti
Presence of _EJ0 method indicates that slots are hot-pluggable.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
===
--- kvm-userspace.hotplug2.orig/bios/acpi-dsdt.dsl
+++ kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
@@ -407,6 +407,161 @@ DefinitionBlock (
 Package() {0x001f, 3, LNKB, 0},
 })
 
+Device (S1) {  // Slot 1
+   Name (_ADR, 0x0001)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S2) {  // Slot 2
+   Name (_ADR, 0x0002)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S3) {  // Slot 3
+   Name (_ADR, 0x0003)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S4) {  // Slot 4
+   Name (_ADR, 0x0004)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S5) {  // Slot 5
+   Name (_ADR, 0x0005)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S6) {  // Slot 6
+   Name (_ADR, 0x0006)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S7) {  // Slot 7
+   Name (_ADR, 0x0007)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S8) {  // Slot 8
+   Name (_ADR, 0x0008)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S9) {  // Slot 9
+   Name (_ADR, 0x0009)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S10) {  // Slot 10
+   Name (_ADR, 0x000A)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S11) {  // Slot 11
+   Name (_ADR, 0x000B)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S12) {  // Slot 12
+   Name (_ADR, 0x000C)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S13) {  // Slot 13
+   Name (_ADR, 0x000D)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S14) {  // Slot 14
+   Name (_ADR, 0x000E)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S15) {  // Slot 15
+   Name (_ADR, 0x000F)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S16) {  // Slot 16
+   Name (_ADR, 0x0010)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S17) {  // Slot 17
+   Name (_ADR, 0x0011)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S18) {  // Slot 18
+   Name (_ADR, 0x0012)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S19) {  // Slot 19
+   Name (_ADR, 0x0013)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S20) {  // Slot 20
+   Name (_ADR, 0x0014)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S21) {  // Slot 21
+   Name (_ADR, 0x0015)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S22) {  // Slot 22
+   Name (_ADR, 0x0016)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S23) {  // Slot 23
+   Name (_ADR, 0x0017)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S24) {  // Slot 24
+   Name (_ADR, 0x0018)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S25) {  // Slot 25
+   Name (_ADR, 0x0019)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S26) {  // Slot 26
+   Name (_ADR, 0x001A)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S27) {  // Slot 27
+   Name (_ADR, 0x001B)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S28) {  // Slot 28
+   Name (_ADR, 0x001C)
+   Method (_EJ0,1) { Return (0x0) }
+}
+
+Device (S29) {  // Slot 29
+   Name (_ADR, 0x001D)
+   Method (_EJ0,1) { Return (0x0) }
+ 

[Qemu-devel] [patch 00/24] QEMU ACPI PCI hotplug support

2008-03-11 Thread Marcelo Tosatti
The following patchset allows PCI hot add/remove through ACPI (handled
by the acpiphp driver on Linux guests).

Comments are welcome.

-- 





[Qemu-devel] [patch 03/24] QEMU/KVM: add pci_find_bus

2008-03-11 Thread Marcelo Tosatti
Return PCIBus pointer from bus number integer.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/hw/pci.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.c
+++ kvm-userspace.hotplug2/qemu/hw/pci.c
@@ -675,6 +675,16 @@ static void pci_bridge_write_config(PCID
 pci_default_write_config(d, address, val, len);
 }
 
+PCIBus *pci_find_bus(int bus_num)
+{
+PCIBus *bus = first_bus;
+
+while (bus && bus->bus_num != bus_num)
+bus = bus->next;
+
+return bus;
+}
+
 PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
 pci_map_irq_fn map_irq, const char *name)
 {
Index: kvm-userspace.hotplug2/qemu/hw/pci.h
===
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.h
+++ kvm-userspace.hotplug2/qemu/hw/pci.h
@@ -3,6 +3,7 @@
 
 /* PCI includes legacy ISA access.  */
 #include "isa.h"
+#include 
 
 /* PCI bus */
 
@@ -91,6 +92,7 @@ void pci_data_write(void *opaque, uint32
 uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
 int pci_bus_num(PCIBus *s);
 void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
+PCIBus *pci_find_bus(int bus_num);
 
 void pci_info(void);
 PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,

-- 





[Qemu-devel] [patch 05/24] QEMU/KVM: pci hotplug GPE support

2008-03-11 Thread Marcelo Tosatti
Enable the corresponding bit on the PCIST region and trigger the SCI.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/hw/acpi.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/acpi.c
+++ kvm-userspace.hotplug2/qemu/hw/acpi.c
@@ -538,6 +538,7 @@ void qemu_system_powerdown(void)
 #endif
 #define GPE_BASE 0xafe0
 #define PROC_BASE 0xaf00
+#define PCI_BASE 0xae00
 
 struct gpe_regs {
 uint16_t sts; /* status */
@@ -546,7 +547,13 @@ struct gpe_regs {
 uint8_t down;
 };
 
+struct pci_status {
+uint32_t up;
+uint32_t down;
+};
+
 static struct gpe_regs gpe;
+static struct pci_status pci0_status;
 
 static uint32_t gpe_readb(void *opaque, uint32_t addr)
 {
@@ -614,6 +621,45 @@ static void gpe_writeb(void *opaque, uin
 #endif
 }
 
+static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
+{
+uint32_t val = 0;
+struct pci_status *g = opaque;
+switch (addr) {
+case PCI_BASE:
+val = g->up;
+break;
+case PCI_BASE + 4:
+val = g->down;
+break;
+default:
+break;
+}
+
+#if defined(DEBUG)
+printf("pcihotplug read %lx == %lx\n", addr, val);
+#endif
+return val;
+}
+
+static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
+{
+struct pci_status *g = opaque;
+switch (addr) {
+case PCI_BASE:
+g->up = val;
+break;
+case PCI_BASE + 4:
+g->down = val;
+break;
+   }
+
+#if defined(DEBUG)
+printf("pcihotplug write %lx <== %d\n", addr, val);
+#endif
+}
+
+
 static char *model;
 
 void qemu_system_hot_add_init(char *cpu_model)
@@ -624,6 +670,9 @@ void qemu_system_hot_add_init(char *cpu_
 register_ioport_write(PROC_BASE, 4, 1, gpe_writeb, &gpe);
 register_ioport_read(PROC_BASE, 4, 1,  gpe_readb, &gpe);
 
+register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
+register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, &pci0_status);
+
 model = cpu_model;
 }
 
@@ -665,3 +714,29 @@ void qemu_system_cpu_hot_add(int cpu, in
 disable_processor(&gpe, cpu);
 qemu_set_irq(pm_state->irq, 0);
 }
+
+static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot)
+{
+g->sts |= 2;
+g->en |= 2;
+p->up |= (1 << slot);
+}
+
+static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
+{
+g->sts |= 2;
+g->en |= 2;
+p->down |= (1 << slot);
+}
+
+void qemu_system_device_hot_add(int slot, int state)
+{
+qemu_set_irq(pm_state->irq, 1);
+pci0_status.up = 0;
+pci0_status.down = 0;
+if (state)
+enable_device(&pci0_status, &gpe, slot);
+else
+disable_device(&pci0_status, &gpe, slot);
+qemu_set_irq(pm_state->irq, 0);
+}

-- 





[Qemu-devel] [patch 06/24] QEMU/KVM: dynamic drive/drive_opt index allocation

2008-03-11 Thread Marcelo Tosatti
Dynamically allocate drive options and drive table index, so to 
reused indexes when devices are removed.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/sysemu.h
===
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -139,6 +139,7 @@ typedef struct DriveInfo {
 BlockInterfaceType type;
 int bus;
 int unit;
+int used;
 } DriveInfo;
 
 #define MAX_IDE_DEVS   2
Index: kvm-userspace.hotplug2/qemu/vl.c
===
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -254,6 +254,7 @@ int nb_drives_opt;
 struct drive_opt {
 const char *file;
 char opt[1024];
+int used;
 } drives_opt[MAX_DRIVES];
 
 static CPUState *cur_cpu;
@@ -4952,22 +4953,50 @@ void do_info_network(void)
 #define MTD_ALIAS "if=mtd"
 #define SD_ALIAS "index=0,if=sd"
 
+static int drive_opt_get_free_idx(void)
+{
+int index;
+
+for (index = 0; index < MAX_DRIVES; index++)
+if (!drives_opt[index].used) {
+drives_opt[index].used = 1;
+return index;
+}
+
+return -1;
+}
+
+static int drive_get_free_idx(void)
+{
+int index;
+
+for (index = 0; index < MAX_DRIVES; index++)
+if (!drives_table[index].used) {
+drives_table[index].used = 1;
+return index;
+}
+
+return -1;
+}
+
 static int drive_add(const char *file, const char *fmt, ...)
 {
 va_list ap;
+int index = drive_opt_get_free_idx();
 
-if (nb_drives_opt >= MAX_DRIVES) {
+if (nb_drives_opt >= MAX_DRIVES || index == -1) {
 fprintf(stderr, "qemu: too many drives\n");
 exit(1);
 }
 
-drives_opt[nb_drives_opt].file = file;
+drives_opt[index].file = file;
 va_start(ap, fmt);
-vsnprintf(drives_opt[nb_drives_opt].opt,
+vsnprintf(drives_opt[index].opt,
   sizeof(drives_opt[0].opt), fmt, ap);
 va_end(ap);
 
-return nb_drives_opt++;
+nb_drives_opt++;
+return index;
 }
 
 int drive_get_index(BlockInterfaceType type, int bus, int unit)
@@ -4976,10 +5005,11 @@ int drive_get_index(BlockInterfaceType t
 
 /* seek interface, bus and unit */
 
-for (index = 0; index < nb_drives; index++)
+for (index = 0; index < MAX_DRIVES; index++)
 if (drives_table[index].type == type &&
drives_table[index].bus == bus &&
-   drives_table[index].unit == unit)
+   drives_table[index].unit == unit &&
+   drives_table[index].used)
 return index;
 
 return -1;
@@ -5015,6 +5045,7 @@ static int drive_init(struct drive_opt *
 int index;
 int cache;
 int bdrv_flags;
+int drives_table_idx;
 char *str = arg->opt;
 char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
"secs", "trans", "media", "snapshot", "file",
@@ -5266,10 +5297,11 @@ static int drive_init(struct drive_opt *
 snprintf(buf, sizeof(buf), "%s%s%i",
  devname, mediastr, unit_id);
 bdrv = bdrv_new(buf);
-drives_table[nb_drives].bdrv = bdrv;
-drives_table[nb_drives].type = type;
-drives_table[nb_drives].bus = bus_id;
-drives_table[nb_drives].unit = unit_id;
+drives_table_idx = drive_get_free_idx();
+drives_table[drives_table_idx].bdrv = bdrv;
+drives_table[drives_table_idx].type = type;
+drives_table[drives_table_idx].bus = bus_id;
+drives_table[drives_table_idx].unit = unit_id;
 nb_drives++;
 
 switch(type) {
@@ -9578,8 +9610,10 @@ int main(int argc, char **argv)
 if (nb_drives_opt < MAX_DRIVES)
 drive_add(NULL, SD_ALIAS);
 
-/* open the virtual block devices */
-
+/* open the virtual block devices
+ * note that migration with device
+ * hot add/remove is broken.
+ */
 for(i = 0; i < nb_drives_opt; i++)
 if (drive_init(&drives_opt[i], snapshot, machine) == -1)
exit(1);

-- 





[Qemu-devel] [patch 07/24] QEMU/KVM: dynamic nic info index allocation

2008-03-11 Thread Marcelo Tosatti
The same, but for nics.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/net.h
===
--- kvm-userspace.hotplug2.orig/qemu/net.h
+++ kvm-userspace.hotplug2/qemu/net.h
@@ -46,6 +46,7 @@ struct NICInfo {
 const char *model;
 VLANState *vlan;
 int devfn;
+int used;
 };
 
 extern int nb_nics;
Index: kvm-userspace.hotplug2/qemu/vl.c
===
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -4791,6 +4791,15 @@ static int check_params(char *buf, int b
 return 0;
 }
 
+static int nic_get_free_idx(void)
+{
+int index;
+
+for (index = 0; index < MAX_NICS; index++)
+if (!nd_table[index].used)
+return index;
+return -1;
+}
 
 static int net_client_init(const char *str)
 {
@@ -4823,19 +4832,20 @@ static int net_client_init(const char *s
 if (!strcmp(device, "nic")) {
 NICInfo *nd;
 uint8_t *macaddr;
+int idx = nic_get_free_idx();
 
-if (nb_nics >= MAX_NICS) {
+if (idx == -1 || nb_nics >= MAX_NICS) {
 fprintf(stderr, "Too Many NICs\n");
 return -1;
 }
-nd = &nd_table[nb_nics];
+nd = &nd_table[idx];
 macaddr = nd->macaddr;
 macaddr[0] = 0x52;
 macaddr[1] = 0x54;
 macaddr[2] = 0x00;
 macaddr[3] = 0x12;
 macaddr[4] = 0x34;
-macaddr[5] = 0x56 + nb_nics;
+macaddr[5] = 0x56 + idx;
 
 if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
 if (parse_macaddr(macaddr, buf) < 0) {
@@ -4847,6 +4857,7 @@ static int net_client_init(const char *s
 nd->model = strdup(buf);
 }
 nd->vlan = vlan;
+nd->used = 1;
 nb_nics++;
 vlan->nb_guest_devs++;
 ret = 0;

-- 





[Qemu-devel] [patch 04/24] QEMU/KVM: return PCIDevice on net device init and record devfn

2008-03-11 Thread Marcelo Tosatti
Change the PCI network drivers init functions to return the PCIDev, to
inform which slot has been hot-plugged.

Also record devfn on the NICInfo structure to locate for release
on hot-removal.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/hw/e1000.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/e1000.c
+++ kvm-userspace.hotplug2/qemu/hw/e1000.c
@@ -930,7 +930,7 @@ e1000_mmio_map(PCIDevice *pci_dev, int r
 cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
 }
 
-void
+PCIDevice *
 pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
 {
 E1000State *d;
@@ -994,4 +994,6 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd,
  d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]);
 
 register_savevm(info_str, d->instance, 1, nic_save, nic_load, d);
+
+return (PCIDevice *)d;
 }
Index: kvm-userspace.hotplug2/qemu/hw/eepro100.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/eepro100.c
+++ kvm-userspace.hotplug2/qemu/hw/eepro100.c
@@ -1742,7 +1742,7 @@ static void nic_save(QEMUFile * f, void 
 qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
 }
 
-static void nic_init(PCIBus * bus, NICInfo * nd,
+static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd,
  const char *name, uint32_t device)
 {
 PCIEEPRO100State *d;
@@ -1794,22 +1794,23 @@ static void nic_init(PCIBus * bus, NICIn
 
 /* XXX: instance number ? */
 register_savevm(name, 0, 3, nic_save, nic_load, s);
+return (PCIDevice *)d;
 }
 
-void pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn)
 {
-nic_init(bus, nd, "i82551", i82551);
+return nic_init(bus, nd, "i82551", i82551);
 //~ uint8_t *pci_conf = d->dev.config;
 }
 
-void pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn)
 {
-nic_init(bus, nd, "i82557b", i82557B);
+return nic_init(bus, nd, "i82557b", i82557B);
 }
 
-void pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn)
+PCIDevice *pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn)
 {
-nic_init(bus, nd, "i82559er", i82559ER);
+return nic_init(bus, nd, "i82559er", i82559ER);
 }
 
 /* eof */
Index: kvm-userspace.hotplug2/qemu/hw/ne2000.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/ne2000.c
+++ kvm-userspace.hotplug2/qemu/hw/ne2000.c
@@ -786,7 +786,7 @@ static void ne2000_map(PCIDevice *pci_de
 register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
 }
 
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
 {
 PCINE2000State *d;
 NE2000State *s;
@@ -827,4 +827,6 @@ void pci_ne2000_init(PCIBus *bus, NICInf
 
 /* XXX: instance number ? */
 register_savevm("ne2000", ne2000_id++, 3, ne2000_save, ne2000_load, s);
+
+return (PCIDevice *)d;
 }
Index: kvm-userspace.hotplug2/qemu/hw/pc.h
===
--- kvm-userspace.hotplug2.orig/qemu/hw/pc.h
+++ kvm-userspace.hotplug2/qemu/hw/pc.h
@@ -146,7 +146,7 @@ void isa_ne2000_init(int base, qemu_irq 
 
 /* virtio-net.c */
 
-void *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn);
+PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn);
 void virtio_net_poll(void);
 
 /* virtio-blk.h */
Index: kvm-userspace.hotplug2/qemu/hw/pci.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.c
+++ kvm-userspace.hotplug2/qemu/hw/pci.c
@@ -625,24 +625,26 @@ void pci_info(void)
 }
 
 /* Initialize a PCI NIC.  */
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)
+PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)
 {
+PCIDevice *pci_dev;
+
 if (strcmp(nd->model, "ne2k_pci") == 0) {
-pci_ne2000_init(bus, nd, devfn);
+pci_dev = pci_ne2000_init(bus, nd, devfn);
 } else if (strcmp(nd->model, "i82551") == 0) {
-pci_i82551_init(bus, nd, devfn);
+pci_dev = pci_i82551_init(bus, nd, devfn);
 } else if (strcmp(nd->model, "i82557b") == 0) {
-pci_i82557b_init(bus, nd, devfn);
+pci_dev = pci_i82557b_init(bus, nd, devfn);
 } else if (strcmp(nd->model, "i82559er") == 0) {
-pci_i82559er_init(bus, nd, devfn);
+pci_dev = pci_i82559er_init(bus, nd, devfn);
 } else if (strcmp(nd->model, "rtl8139") == 0) {
-pci_rtl8139_init(bus, nd, devfn);
+pci_dev = pci_rtl8139_init(bus, nd, devfn);
 } else if (strcmp(nd->model, "e1000") == 0) {
-pci_e1000_init(bus, nd, devfn);
+pci_dev = pci_e1000_init(bus, nd, devfn);
 } else if (strcmp(nd->model, "pcnet") == 0) {
-pci_pcnet_init(bus, nd, devfn);
+  

[Qemu-devel] [patch 09/24] QEMU/KVM: record devfn on block driver instance

2008-03-11 Thread Marcelo Tosatti
Record devfn on the BlockDriverState structure to locate for release 
on hot-removal.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/block_int.h
===
--- kvm-userspace.hotplug2.orig/qemu/block_int.h
+++ kvm-userspace.hotplug2/qemu/block_int.h
@@ -129,6 +129,8 @@ struct BlockDriverState {
 int cyls, heads, secs, translation;
 int type;
 char device_name[32];
+/* PCI devfn of parent */
+int devfn;
 BlockDriverState *next;
 };
 
Index: kvm-userspace.hotplug2/qemu/hw/lsi53c895a.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/lsi53c895a.c
+++ kvm-userspace.hotplug2/qemu/hw/lsi53c895a.c
@@ -13,6 +13,7 @@
 #include "hw.h"
 #include "pci.h"
 #include "scsi-disk.h"
+#include "block_int.h"
 
 //#define DEBUG_LSI
 //#define DEBUG_LSI_REG
@@ -1845,6 +1846,7 @@ void lsi_scsi_attach(void *opaque, Block
 s->scsi_dev[id] = scsi_generic_init(bd, 1, lsi_command_complete, s);
 if (s->scsi_dev[id] == NULL)
 s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s);
+bd->devfn = s->pci_dev.devfn;
 }
 
 void *lsi_scsi_init(PCIBus *bus, int devfn)
Index: kvm-userspace.hotplug2/qemu/hw/virtio-blk.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/virtio-blk.c
+++ kvm-userspace.hotplug2/qemu/hw/virtio-blk.c
@@ -13,6 +13,7 @@
 
 #include "virtio.h"
 #include "block.h"
+#include "block_int.h"
 #include "pc.h"
 
 /* from Linux's linux/virtio_blk.h */
@@ -156,6 +157,7 @@ void *virtio_blk_init(PCIBus *bus, uint1
 s->vdev.update_config = virtio_blk_update_config;
 s->vdev.get_features = virtio_blk_get_features;
 s->bs = bs;
+bs->devfn = s->vdev.pci_dev.devfn;
 
 virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
 
Index: kvm-userspace.hotplug2/qemu/hw/ide.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/ide.c
+++ kvm-userspace.hotplug2/qemu/hw/ide.c
@@ -28,6 +28,7 @@
 #include "scsi-disk.h"
 #include "pcmcia.h"
 #include "block.h"
+#include "block_int.h"
 #include "qemu-timer.h"
 #include "sysemu.h"
 #include "ppc_mac.h"
@@ -2938,6 +2939,7 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
 {
 PCIIDEState *d;
 uint8_t *pci_conf;
+int i;
 
 /* register a function 1 of PIIX3 */
 d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
@@ -2966,6 +2968,10 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
 ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
 ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
 
+for (i = 0; i < 4; i++)
+if (hd_table[i])
+hd_table[i]->devfn = d->dev.devfn;
+
 register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
 }
 

-- 





[Qemu-devel] [patch 13/24] QEMU/KVM: export get_param_value/check_params

2008-03-11 Thread Marcelo Tosatti
Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/sysemu.h
===
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -57,6 +57,10 @@ int qemu_live_loadvm_state(QEMUFile *f);
 
 void main_loop_wait(int timeout);
 
+int check_params(char *buf, int buf_size, char **params, const char *str);
+int get_param_value(char *buf, int buf_size, const char *tag,
+const char *str);
+
 /* Polling handling */
 
 /* return TRUE if no sleep should be done afterwards */
Index: kvm-userspace.hotplug2/qemu/vl.c
===
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -4737,8 +4737,8 @@ static const char *get_opt_value(char *b
 return p;
 }
 
-static int get_param_value(char *buf, int buf_size,
-   const char *tag, const char *str)
+int get_param_value(char *buf, int buf_size,
+const char *tag, const char *str)
 {
 const char *p;
 char option[128];
@@ -4762,8 +4762,8 @@ static int get_param_value(char *buf, in
 return 0;
 }
 
-static int check_params(char *buf, int buf_size,
-char **params, const char *str)
+int check_params(char *buf, int buf_size,
+ char **params, const char *str)
 {
 const char *p;
 int i;

-- 





[Qemu-devel] [patch 10/24] QEMU/KVM: move drives_opt for external use

2008-03-11 Thread Marcelo Tosatti
Device hotplug will use that structure from a separate
file.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/sysemu.h
===
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -157,6 +157,15 @@ extern int drive_get_max_bus(BlockInterf
 extern void drive_uninit(BlockDriverState *bdrv);
 extern void drive_remove(int index);
 
+struct drive_opt {
+const char *file;
+char opt[1024];
+int used;
+};
+
+extern struct drive_opt drives_opt[MAX_DRIVES];
+extern int nb_drives_opt;
+
 /* acpi */
 void qemu_system_cpu_hot_add(int cpu, int state);
 void qemu_system_hot_add_init(char *cpu_model);
Index: kvm-userspace.hotplug2/qemu/vl.c
===
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -251,11 +251,7 @@ unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
 #endif
 int nb_drives_opt;
-struct drive_opt {
-const char *file;
-char opt[1024];
-int used;
-} drives_opt[MAX_DRIVES];
+struct drive_opt drives_opt[MAX_DRIVES];
 
 static CPUState *cur_cpu;
 static CPUState *next_cpu;

-- 





[Qemu-devel] [patch 12/24] QEMU/KVM: add net_client_uninit

2008-03-11 Thread Marcelo Tosatti
Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/net.h
===
--- kvm-userspace.hotplug2.orig/qemu/net.h
+++ kvm-userspace.hotplug2/qemu/net.h
@@ -38,6 +38,7 @@ void do_info_network(void);
 int hack_around_tap(void *opaque);
 
 int net_client_init(const char *str);
+void net_client_uninit(NICInfo *nd);
 
 /* NIC info */
 
Index: kvm-userspace.hotplug2/qemu/vl.c
===
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -4937,6 +4937,14 @@ int net_client_init(const char *str)
 return ret;
 }
 
+void net_client_uninit(NICInfo *nd)
+{
+nd->vlan->nb_guest_devs--; /* XXX: free vlan on last reference */
+nb_nics--;
+nd->used = 0;
+free(nd->model);
+}
+
 void do_info_network(void)
 {
 VLANState *vlan;

-- 





[Qemu-devel] [patch 14/24] QEMU/KVM: add pci_find_device

2008-03-11 Thread Marcelo Tosatti
Return PCIDevice from bus number and slot.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug/qemu/hw/pci.c
===
--- kvm-userspace.hotplug.orig/qemu/hw/pci.c
+++ kvm-userspace.hotplug/qemu/hw/pci.c
@@ -689,6 +689,23 @@ PCIBus *pci_find_bus(int bus_num)
 return bus;
 }
 
+PCIDevice *pci_find_device(int bus_num, int slot)
+{
+int devfn;
+PCIDevice *d;
+PCIBus *bus = pci_find_bus(bus_num);
+
+if (!bus)
+return NULL;
+
+for(devfn = 0; devfn < 256; devfn++) {
+d = bus->devices[devfn];
+if (d && PCI_SLOT(devfn) == slot)
+return d;
+}
+return NULL;
+}
+
 PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
 pci_map_irq_fn map_irq, const char *name)
 {
Index: kvm-userspace.hotplug/qemu/hw/pci.h
===
--- kvm-userspace.hotplug.orig/qemu/hw/pci.h
+++ kvm-userspace.hotplug/qemu/hw/pci.h
@@ -93,6 +93,7 @@ uint32_t pci_data_read(void *opaque, uin
 int pci_bus_num(PCIBus *s);
 void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
 PCIBus *pci_find_bus(int bus_num);
+PCIDevice *pci_find_device(int bus_num, int slot);
 
 void pci_info(void);
 PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,

-- 





[Qemu-devel] [patch 11/24] QEMU/KVM: net/drive add/remove tweaks

2008-03-11 Thread Marcelo Tosatti
Export net/drive add/remove functions for device hotplug usage.

Return the table index on add.

Return failure instead of exiting if limit has been reached 
on drive_add.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/vl.c
===
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -4797,7 +4797,7 @@ static int nic_get_free_idx(void)
 return -1;
 }
 
-static int net_client_init(const char *str)
+int net_client_init(const char *str)
 {
 const char *p;
 char *q;
@@ -4856,7 +4856,7 @@ static int net_client_init(const char *s
 nd->used = 1;
 nb_nics++;
 vlan->nb_guest_devs++;
-ret = 0;
+ret = idx;
 } else
 if (!strcmp(device, "none")) {
 /* does nothing. It is needed to signal that no network cards
@@ -4986,14 +4986,14 @@ static int drive_get_free_idx(void)
 return -1;
 }
 
-static int drive_add(const char *file, const char *fmt, ...)
+int drive_add(const char *file, const char *fmt, ...)
 {
 va_list ap;
 int index = drive_opt_get_free_idx();
 
 if (nb_drives_opt >= MAX_DRIVES || index == -1) {
 fprintf(stderr, "qemu: too many drives\n");
-exit(1);
+return -1;
 }
 
 drives_opt[index].file = file;
@@ -5056,9 +5056,10 @@ void drive_uninit(BlockDriverState *bdrv
 }
 }
 
-static int drive_init(struct drive_opt *arg, int snapshot,
-  QEMUMachine *machine)
+int drive_init(struct drive_opt *arg, int snapshot,
+  void *opaque)
 {
+QEMUMachine *machine = opaque;
 char buf[128];
 char file[1024];
 char devname[128];
@@ -5311,7 +5312,7 @@ static int drive_init(struct drive_opt *
  */
 
 if (drive_get_index(type, bus_id, unit_id) != -1)
-return 0;
+return -2;
 
 /* init */
 
@@ -5359,7 +5360,7 @@ static int drive_init(struct drive_opt *
 break;
 }
 if (!file[0])
-return 0;
+return -2;
 bdrv_flags = 0;
 if (snapshot)
 bdrv_flags |= BDRV_O_SNAPSHOT;
@@ -5370,7 +5371,7 @@ static int drive_init(struct drive_opt *
 file);
 return -1;
 }
-return 0;
+return drives_table_idx;
 }
 
 /***/
Index: kvm-userspace.hotplug2/qemu/net.h
===
--- kvm-userspace.hotplug2.orig/qemu/net.h
+++ kvm-userspace.hotplug2/qemu/net.h
@@ -37,6 +37,8 @@ void do_info_network(void);
 /* virtio hack for zero copy receive */
 int hack_around_tap(void *opaque);
 
+int net_client_init(const char *str);
+
 /* NIC info */
 
 #define MAX_NICS 8
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -166,6 +166,9 @@ struct drive_opt {
 extern struct drive_opt drives_opt[MAX_DRIVES];
 extern int nb_drives_opt;
 
+extern int drive_add(const char *file, const char *fmt, ...);
+extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);
+
 /* acpi */
 void qemu_system_cpu_hot_add(int cpu, int state);
 void qemu_system_hot_add_init(char *cpu_model);

-- 





[Qemu-devel] [patch 15/24] QEMU/KVM: virtio_blk_init return PCIDevice pointer

2008-03-11 Thread Marcelo Tosatti
Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/hw/virtio-blk.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/virtio-blk.c
+++ kvm-userspace.hotplug2/qemu/hw/virtio-blk.c
@@ -161,5 +161,5 @@ void *virtio_blk_init(PCIBus *bus, uint1
 
 virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
 
-return &s->vdev;
+return s;
 }

-- 





[Qemu-devel] [patch 17/24] QEMU/KVM: add cpu_unregister_io_memory and make io mem table index dynamic

2008-03-11 Thread Marcelo Tosatti
So drivers can clear their mem io table entries on exit back to unassigned 
state.

Also make the io mem index allocation dynamic. 

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/cpu-all.h
===
--- kvm-userspace.hotplug2.orig/qemu/cpu-all.h
+++ kvm-userspace.hotplug2/qemu/cpu-all.h
@@ -837,6 +837,7 @@ int cpu_register_io_memory(int io_index,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
+void cpu_unregister_io_memory(int table_address);
 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
 CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
 
Index: kvm-userspace.hotplug2/qemu/exec.c
===
--- kvm-userspace.hotplug2.orig/qemu/exec.c
+++ kvm-userspace.hotplug2/qemu/exec.c
@@ -158,7 +158,7 @@ PhysPageDesc **l1_phys_map;
 CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-static int io_mem_nb;
+char io_mem_used[IO_MEM_NB_ENTRIES];
 #if defined(CONFIG_SOFTMMU)
 static int io_mem_watch;
 #endif
@@ -2498,12 +2498,28 @@ static void *subpage_init (target_phys_a
 return mmio;
 }
 
+static int get_free_io_mem_idx(void)
+{
+int i;
+
+for (i = 0; i> IO_MEM_SHIFT, error_mem_read, 
unassigned_mem_write, NULL);
 cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, 
unassigned_mem_read, unassigned_mem_write, NULL);
 cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, 
notdirty_mem_write, NULL);
-io_mem_nb = 5;
+for (i=0; i<5; i++)
+io_mem_used[i] = 0;
 
 #if defined(CONFIG_SOFTMMU)
 io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
@@ -2530,9 +2546,9 @@ int cpu_register_io_memory(int io_index,
 int i, subwidth = 0;
 
 if (io_index <= 0) {
-if (io_mem_nb >= IO_MEM_NB_ENTRIES)
-return -1;
-io_index = io_mem_nb++;
+io_index = get_free_io_mem_idx();
+if (io_index == -1)
+return io_index;
 } else {
 if (io_index >= IO_MEM_NB_ENTRIES)
 return -1;
@@ -2548,6 +2564,19 @@ int cpu_register_io_memory(int io_index,
 return (io_index << IO_MEM_SHIFT) | subwidth;
 }
 
+void cpu_unregister_io_memory(int io_table_address)
+{
+int i;
+int io_index = io_table_address >> IO_MEM_SHIFT;
+
+for (i=0;i < 3; i++) {
+io_mem_read[io_index][i] = unassigned_mem_read[i];
+io_mem_write[io_index][i] = unassigned_mem_write[i];
+}
+io_mem_opaque[io_index] = NULL;
+io_mem_used[io_index] = 0;
+}
+
 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
 {
 return io_mem_write[io_index >> IO_MEM_SHIFT];

-- 





[Qemu-devel] [patch 19/24] QEMU/KVM: handle SEJ notifications

2008-03-11 Thread Marcelo Tosatti
Handle the _EJ0 notifications.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/hw/acpi.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/acpi.c
+++ kvm-userspace.hotplug2/qemu/hw/acpi.c
@@ -26,6 +26,7 @@
 #ifdef USE_KVM
 #include "qemu-kvm.h"
 #endif
+#include "string.h"
 
 //#define DEBUG
 
@@ -539,6 +540,7 @@ void qemu_system_powerdown(void)
 #define GPE_BASE 0xafe0
 #define PROC_BASE 0xaf00
 #define PCI_BASE 0xae00
+#define PCI_EJ_BASE 0xae08
 
 struct gpe_regs {
 uint16_t sts; /* status */
@@ -659,6 +661,23 @@ static void pcihotplug_write(void *opaqu
 #endif
 }
 
+static uint32_t pciej_read(void *opaque, uint32_t addr)
+{
+#if defined(DEBUG)
+printf("pciej read %lx == %lx\n", addr, val);
+#endif
+return 0;
+}
+
+static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
+{
+int slot = ffs(val) - 1;
+
+#if defined(DEBUG)
+printf("pciej write %lx <== %d\n", addr, val);
+#endif
+}
+
 
 static char *model;
 
@@ -673,6 +692,9 @@ void qemu_system_hot_add_init(char *cpu_
 register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
 register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, &pci0_status);
 
+register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, NULL);
+register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, NULL);
+
 model = cpu_model;
 }
 

-- 





[Qemu-devel] [patch 20/24] QEMU/KVM: add qemu_free_irqs

2008-03-11 Thread Marcelo Tosatti
Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/hw/irq.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/irq.c
+++ kvm-userspace.hotplug2/qemu/hw/irq.c
@@ -56,6 +56,12 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_ha
 return s;
 }
 
+void qemu_free_irqs(qemu_irq *s)
+{
+qemu_free(s[0]);
+qemu_free(s);
+}
+
 static void qemu_notirq(void *opaque, int line, int level)
 {
 struct IRQState *irq = opaque;
Index: kvm-userspace.hotplug2/qemu/hw/irq.h
===
--- kvm-userspace.hotplug2.orig/qemu/hw/irq.h
+++ kvm-userspace.hotplug2/qemu/hw/irq.h
@@ -28,6 +28,8 @@ static inline void qemu_irq_pulse(qemu_i
 /* Returns an array of N IRQs.  */
 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
 
+void qemu_free_irqs(qemu_irq *s);
+
 /* Returns a new IRQ with opposite polarity.  */
 qemu_irq qemu_irq_invert(qemu_irq irq);
 

-- 





[Qemu-devel] [patch 22/24] QEMU/KVM: LSI SCSI and e1000 unregister callbacks

2008-03-11 Thread Marcelo Tosatti
Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/hw/lsi53c895a.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/lsi53c895a.c
+++ kvm-userspace.hotplug2/qemu/hw/lsi53c895a.c
@@ -1849,6 +1849,18 @@ void lsi_scsi_attach(void *opaque, Block
 bd->devfn = s->pci_dev.devfn;
 }
 
+int lsi_scsi_uninit(PCIDevice *d)
+{
+LSIState *s = (LSIState *) d;
+
+cpu_unregister_io_memory(s->mmio_io_addr);
+cpu_unregister_io_memory(s->ram_io_addr);
+
+qemu_free(s->queue);
+
+return 0;
+}
+
 void *lsi_scsi_init(PCIBus *bus, int devfn)
 {
 LSIState *s;
@@ -1881,6 +1893,7 @@ void *lsi_scsi_init(PCIBus *bus, int dev
 s->queue = qemu_malloc(sizeof(lsi_queue));
 s->queue_len = 1;
 s->active_commands = 0;
+s->pci_dev.unregister = lsi_scsi_uninit;
 
 lsi_soft_reset(s);
 
Index: kvm-userspace.hotplug2/qemu/hw/e1000.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/e1000.c
+++ kvm-userspace.hotplug2/qemu/hw/e1000.c
@@ -930,6 +930,16 @@ e1000_mmio_map(PCIDevice *pci_dev, int r
 cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
 }
 
+static int
+pci_e1000_uninit(PCIDevice *dev)
+{
+E1000State *d = (E1000State *) dev;
+
+cpu_unregister_io_memory(d->mmio_index);
+
+return 0;
+}
+
 PCIDevice *
 pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
 {
@@ -994,6 +1004,7 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd,
  d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]);
 
 register_savevm(info_str, d->instance, 1, nic_save, nic_load, d);
+d->dev.unregister = pci_e1000_uninit;
 
 return (PCIDevice *)d;
 }

-- 





[Qemu-devel] [patch 23/24] QEMU/KVM: zero ioport_opaque on isa_unassign_ioport

2008-03-11 Thread Marcelo Tosatti
If the io port is unassigned, the previous private pointer is 
meaningless.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/vl.c
===
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -399,6 +399,8 @@ void isa_unassign_ioport(int start, int 
 ioport_write_table[0][i] = default_ioport_writeb;
 ioport_write_table[1][i] = default_ioport_writew;
 ioport_write_table[2][i] = default_ioport_writel;
+
+ioport_opaque[i] = NULL;
 }
 }
 

-- 





[Qemu-devel] [patch 24/24] QEMU/KVM: device hot-remove

2008-03-11 Thread Marcelo Tosatti
Add monitor command to hot-remove devices.

Remove device data on _EJ0 notification.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/monitor.c
===
--- kvm-userspace.hotplug2.orig/qemu/monitor.c
+++ kvm-userspace.hotplug2/qemu/monitor.c
@@ -1365,6 +1365,7 @@ static term_cmd_t term_cmds[] = {
 "[snapshot=on|off][,cache=on|off]",
 "add drive to PCI storage controller" 
},
 { "pci_add", "iss", device_hot_add, "bus nic|storage 
[[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...", 
"hot-add PCI device" },
+{ "pci_del", "ii", device_hot_remove, "bus slot-number", "hot remove PCI 
device" },
 { NULL, NULL, },
 };
 
Index: kvm-userspace.hotplug2/qemu/hw/device-hotplug.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/device-hotplug.c
+++ kvm-userspace.hotplug2/qemu/hw/device-hotplug.c
@@ -5,6 +5,8 @@
 #include "sysemu.h"
 #include "pc.h"
 #include "console.h"
+#include "block_int.h"
+#include 
 
 static PCIDevice *qemu_system_hot_add_nic(const char *opts, int bus_nr)
 {
@@ -148,7 +150,7 @@ void device_hot_add(int pcibus, const ch
 term_printf("invalid type: %s\n", type);
 
 if (dev) {
-qemu_system_device_hot_add(PCI_SLOT(dev->devfn), 1);
+qemu_system_device_hot_add(pcibus, PCI_SLOT(dev->devfn), 1);
 term_printf("OK bus %d, slot %d, function %d (devfn %d)\n",
 pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
 PCI_FUNC(dev->devfn), dev->devfn);
@@ -156,3 +158,67 @@ void device_hot_add(int pcibus, const ch
 term_printf("failed to add %s\n", opts);
 }
 
+void device_hot_remove(int pcibus, int slot)
+{
+PCIDevice *d = pci_find_device(pcibus, slot);
+
+if (!d) {
+term_printf("invalid slot %d\n", slot);
+return;
+}
+
+qemu_system_device_hot_add(pcibus, slot, 0);
+}
+
+static void destroy_nic(int slot)
+{
+int i;
+
+for (i = 0; i < MAX_NICS; i++)
+if (nd_table[i].used &&
+PCI_SLOT(nd_table[i].devfn) == slot)
+net_client_uninit(&nd_table[i]);
+}
+
+static void destroy_bdrvs(int slot)
+{
+int i;
+struct BlockDriverState *bs;
+
+for (i = 0; i <= MAX_DRIVES; i++) {
+bs = drives_table[i].bdrv;
+if (bs && (PCI_SLOT(bs->devfn) == slot)) {
+drive_uninit(bs);
+bdrv_delete(bs);
+}
+}
+}
+
+/*
+ * OS has executed _EJ0 method, we now can remove the device
+ */
+void device_hot_remove_success(int pcibus, int slot)
+{
+PCIDevice *d = pci_find_device(pcibus, slot);
+int class_code;
+
+if (!d) {
+term_printf("invalid slot %d\n", slot);
+return;
+}
+
+class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
+
+pci_unregister_device(d);
+
+switch(class_code) {
+case PCI_BASE_CLASS_STORAGE:
+destroy_bdrvs(slot);
+break;
+case PCI_BASE_CLASS_NETWORK:
+destroy_nic(slot);
+break;
+}
+
+}
+
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -176,11 +176,13 @@ extern int drive_init(struct drive_opt *
 /* acpi */
 void qemu_system_cpu_hot_add(int cpu, int state);
 void qemu_system_hot_add_init(char *cpu_model);
-void qemu_system_device_hot_add(int slot, int state);
+void qemu_system_device_hot_add(int pcibus, int slot, int state);
 
 /* device-hotplug */
 void device_hot_add(int pcibus, const char *type, const char *opts);
 void drive_hot_add(int pcibus, const char *devfn_string, const char *opts);
+void device_hot_remove(int pcibus, int slot);
+void device_hot_remove_success(int pcibus, int slot);
 
 /* vmchannel devices */
 
Index: kvm-userspace.hotplug2/qemu/hw/acpi.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/acpi.c
+++ kvm-userspace.hotplug2/qemu/hw/acpi.c
@@ -673,6 +673,8 @@ static void pciej_write(void *opaque, ui
 {
 int slot = ffs(val) - 1;
 
+device_hot_remove_success(0, slot);
+
 #if defined(DEBUG)
 printf("pciej write %lx <== %d\n", addr, val);
 #endif
@@ -751,7 +753,7 @@ static void disable_device(struct pci_st
 p->down |= (1 << slot);
 }
 
-void qemu_system_device_hot_add(int slot, int state)
+void qemu_system_device_hot_add(int pcibus, int slot, int state)
 {
 qemu_set_irq(pm_state->irq, 1);
 pci0_status.up = 0;

-- 





[Qemu-devel] [patch 08/24] QEMU/KVM: drive removal support

2008-03-11 Thread Marcelo Tosatti
To be used by hot-remove.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/vl.c
===
--- kvm-userspace.hotplug2.orig/qemu/vl.c
+++ kvm-userspace.hotplug2/qemu/vl.c
@@ -5010,6 +5010,12 @@ static int drive_add(const char *file, c
 return index;
 }
 
+void drive_remove(int index)
+{
+drives_opt[index].used = 0;
+nb_drives_opt--;
+}
+
 int drive_get_index(BlockInterfaceType type, int bus, int unit)
 {
 int index;
@@ -5040,6 +5046,20 @@ int drive_get_max_bus(BlockInterfaceType
 return max_bus;
 }
 
+void drive_uninit(BlockDriverState *bdrv)
+{
+int i;
+
+for (i = 0; i < MAX_DRIVES; i++)
+if (drives_table[i].bdrv == bdrv) {
+drives_table[i].bdrv = NULL;
+drives_table[i].used = 0;
+drive_remove(drives_table[i].drive_opt_idx);
+nb_drives--;
+break;
+}
+}
+
 static int drive_init(struct drive_opt *arg, int snapshot,
   QEMUMachine *machine)
 {
@@ -5313,6 +5333,7 @@ static int drive_init(struct drive_opt *
 drives_table[drives_table_idx].type = type;
 drives_table[drives_table_idx].bus = bus_id;
 drives_table[drives_table_idx].unit = unit_id;
+drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
 nb_drives++;
 
 switch(type) {
Index: kvm-userspace.hotplug2/qemu/sysemu.h
===
--- kvm-userspace.hotplug2.orig/qemu/sysemu.h
+++ kvm-userspace.hotplug2/qemu/sysemu.h
@@ -140,6 +140,7 @@ typedef struct DriveInfo {
 int bus;
 int unit;
 int used;
+int drive_opt_idx;
 } DriveInfo;
 
 #define MAX_IDE_DEVS   2
@@ -153,6 +154,9 @@ int extboot_drive;
 extern int drive_get_index(BlockInterfaceType type, int bus, int unit);
 extern int drive_get_max_bus(BlockInterfaceType type);
 
+extern void drive_uninit(BlockDriverState *bdrv);
+extern void drive_remove(int index);
+
 /* acpi */
 void qemu_system_cpu_hot_add(int cpu, int state);
 void qemu_system_hot_add_init(char *cpu_model);

-- 





[Qemu-devel] [patch 16/24] QEMU/KVM: device and disk hot-add

2008-03-11 Thread Marcelo Tosatti
Add monitor command to hot-add PCI devices (nic and storage).

Syntax is:

pci_add pcibus nic|storage params

It returns the bus slot and function for the newly added device on success.

It is possible to attach a disk to a device after PCI initialization via
the drive_add command. If so, a manual scan of the SCSI bus on the guest 
is necessary.

Save QEMUMachine necessary for drive_init.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/Makefile.target
===
--- kvm-userspace.hotplug2.orig/qemu/Makefile.target
+++ kvm-userspace.hotplug2/qemu/Makefile.target
@@ -579,6 +579,8 @@ OBJS+= hypercall.o
 # virtio devices
 OBJS += virtio.o virtio-net.o virtio-blk.o
 
+OBJS += device-hotplug.o
+
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
 OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
Index: kvm-userspace.hotplug2/qemu/hw/device-hotplug.c
===
--- /dev/null
+++ kvm-userspace.hotplug2/qemu/hw/device-hotplug.c
@@ -0,0 +1,158 @@
+#include "hw.h"
+#include "boards.h"
+#include "pci.h"
+#include "net.h"
+#include "sysemu.h"
+#include "pc.h"
+#include "console.h"
+
+static PCIDevice *qemu_system_hot_add_nic(const char *opts, int bus_nr)
+{
+int ret;
+char buf[4096];
+PCIBus *pci_bus;
+
+pci_bus = pci_find_bus (bus_nr);
+if (!pci_bus) {
+term_printf ("Can't find pci_bus %d\n", bus_nr);
+return NULL;
+}
+
+memset (buf, 0, sizeof (buf));
+
+strcpy (buf, "nic,");
+strncat (buf, opts, sizeof (buf) - strlen (buf) - 1);
+
+ret = net_client_init (buf);
+if (ret < 0 || !nd_table[ret].model)
+return NULL;
+return pci_nic_init (pci_bus, &nd_table[ret], -1);
+}
+
+static int add_init_drive(const char *opts)
+{
+int drive_opt_idx, drive_idx;
+int ret = -1;
+
+drive_opt_idx = drive_add(NULL, "%s", opts);
+if (!drive_opt_idx)
+return ret;
+
+drive_idx = drive_init(&drives_opt[drive_opt_idx], 0, current_machine);
+if (drive_idx == -1) {
+drive_remove(drive_opt_idx);
+return ret;
+}
+
+return drive_idx;
+}
+
+void drive_hot_add(int pcibus, const char *devfn_string, const char *opts)
+{
+int drive_idx, type, bus;
+int devfn;
+int success = 0;
+PCIDevice *dev;
+
+devfn = strtoul(devfn_string, NULL, 0);
+
+dev = pci_find_device(pcibus, PCI_SLOT(devfn));
+if (!dev) {
+term_printf("no pci device with devfn %d (slot %d)\n", devfn,
+PCI_SLOT(devfn));
+return;
+}
+
+drive_idx = add_init_drive(opts);
+if (drive_idx < 0)
+return;
+type = drives_table[drive_idx].type;
+bus = drive_get_max_bus (type);
+
+switch (type) {
+case IF_SCSI:
+success = 1;
+lsi_scsi_attach (dev, drives_table[drive_idx].bdrv,
+ drives_table[drive_idx].unit);
+break;
+default:
+term_printf("Can't hot-add drive to type %d\n", type);
+}
+
+if (success)
+term_printf("OK bus %d, unit %d\n", drives_table[drive_idx].bus,
+drives_table[drive_idx].unit);
+return;
+}
+
+static PCIDevice *qemu_system_hot_add_storage(const char *opts, int bus_nr)
+{
+void *opaque = NULL;
+PCIBus *pci_bus;
+int type = -1, drive_idx = -1;
+char buf[128];
+
+pci_bus = pci_find_bus(bus_nr);
+if (!pci_bus) {
+term_printf("Can't find pci_bus %d\n", bus_nr);
+return NULL;
+}
+
+if (get_param_value(buf, sizeof(buf), "if", opts)) {
+if (!strcmp(buf, "scsi"))
+type = IF_SCSI;
+else if (!strcmp(buf, "virtio")) {
+type = IF_VIRTIO;
+}
+} else {
+term_printf("no if= specified\n");
+return NULL;
+}
+
+if (get_param_value(buf, sizeof(buf), "file", opts)) {
+drive_idx = add_init_drive(opts);
+if (drive_idx < 0)
+return NULL;
+} else if (type == IF_VIRTIO) {
+term_printf("virtio requires a backing file/device.\n");
+return NULL;
+}
+
+switch (type) {
+case IF_SCSI:
+opaque = lsi_scsi_init (pci_bus, -1);
+if (drive_idx >= 0)
+lsi_scsi_attach (opaque, drives_table[drive_idx].bdrv,
+ drives_table[drive_idx].unit);
+break;
+case IF_VIRTIO:
+opaque = virtio_blk_init (pci_bus, 0x1AF4, 0x1001,
+  drives_table[drive_idx].bdrv);
+break;
+default:
+term_printf ("type %s not a hotpluggable PCI device.\n", buf);
+}
+
+return opaque;
+}
+
+void device_hot_add(int pcibus, const char *type, const char *opts)
+{
+PCIDevice *dev = NULL;
+
+if (strcmp(type, "nic") == 0)
+dev = qemu_system_hot_add_nic(opts, pcibus);
+else if (strcmp(type, "storage") == 0)
+dev = qemu_system_hot

[Qemu-devel] [patch 21/24] QEMU/KVM: add pci_unregister_device

2008-03-11 Thread Marcelo Tosatti
Unregister the pci device, unassign its IO and memory regions, and free
associated data.

Add a callback so drivers can free device state.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/qemu/hw/pci.c
===
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.c
+++ kvm-userspace.hotplug2/qemu/hw/pci.c
@@ -185,6 +185,48 @@ PCIDevice *pci_register_device(PCIBus *b
 return pci_dev;
 }
 
+static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
+{
+return addr + pci_mem_base;
+}
+
+static void pci_unregister_io_regions(PCIDevice *pci_dev)
+{
+PCIIORegion *r;
+int i;
+
+for(i = 0; i < PCI_NUM_REGIONS; i++) {
+r = &pci_dev->io_regions[i];
+if (!r->size)
+continue;
+if (r->type == PCI_ADDRESS_SPACE_IO) {
+isa_unassign_ioport(r->addr, r->size);
+} else {
+cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
+ r->size,
+ IO_MEM_UNASSIGNED);
+}
+}
+}
+
+int pci_unregister_device(PCIDevice *pci_dev)
+{
+int ret = 0;
+
+if (pci_dev->unregister)
+ret = pci_dev->unregister(pci_dev);
+if (ret)
+return ret;
+
+pci_unregister_io_regions(pci_dev);
+
+qemu_free_irqs(pci_dev->irq);
+pci_irq_index--;
+pci_dev->bus->devices[pci_dev->devfn] = NULL;
+qemu_free(pci_dev);
+return 0;
+}
+
 void pci_register_io_region(PCIDevice *pci_dev, int region_num,
 uint32_t size, int type,
 PCIMapIORegionFunc *map_func)
@@ -207,10 +249,6 @@ void pci_register_io_region(PCIDevice *p
 *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
 }
 
-static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
-{
-return addr + pci_mem_base;
-}
 
 static void pci_update_mappings(PCIDevice *d)
 {
Index: kvm-userspace.hotplug2/qemu/hw/pci.h
===
--- kvm-userspace.hotplug2.orig/qemu/hw/pci.h
+++ kvm-userspace.hotplug2/qemu/hw/pci.h
@@ -15,6 +15,7 @@ typedef uint32_t PCIConfigReadFunc(PCIDe
uint32_t address, int len);
 typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
 uint32_t addr, uint32_t size, int type);
+typedef int PCIUnregisterFunc(PCIDevice *pci_dev);
 
 #define PCI_ADDRESS_SPACE_MEM  0x00
 #define PCI_ADDRESS_SPACE_IO   0x01
@@ -56,6 +57,7 @@ struct PCIDevice {
 /* do not access the following fields */
 PCIConfigReadFunc *config_read;
 PCIConfigWriteFunc *config_write;
+PCIUnregisterFunc *unregister;
 /* ??? This is a PC-specific hack, and should be removed.  */
 int irq_index;
 
@@ -71,6 +73,8 @@ PCIDevice *pci_register_device(PCIBus *b
PCIConfigReadFunc *config_read,
PCIConfigWriteFunc *config_write);
 
+int pci_unregister_device(PCIDevice *pci_dev);
+
 void pci_register_io_region(PCIDevice *pci_dev, int region_num,
 uint32_t size, int type,
 PCIMapIORegionFunc *map_func);

-- 





[Qemu-devel] [patch 18/24] QEMU/KVM: notify _EJ0 through _SEJ OperationRegion

2008-03-11 Thread Marcelo Tosatti
The _EJ0 method is executed by the OS once it has successfully finished
device removal. Inform that event through IO port space so QEMU 
can free the associated data.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>

Index: kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
===
--- kvm-userspace.hotplug2.orig/bios/acpi-dsdt.dsl
+++ kvm-userspace.hotplug2/bios/acpi-dsdt.dsl
@@ -414,159 +414,258 @@ DefinitionBlock (
PCID, 32,
}
 
+OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
+Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
+{
+B0EJ, 32,
+}
+
 Device (S1) {  // Slot 1
Name (_ADR, 0x0001)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x2, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S2) {  // Slot 2
Name (_ADR, 0x0002)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x4, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S3) {  // Slot 3
Name (_ADR, 0x0003)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store (0x8, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S4) {  // Slot 4
Name (_ADR, 0x0004)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x10, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S5) {  // Slot 5
Name (_ADR, 0x0005)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x20, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S6) {  // Slot 6
Name (_ADR, 0x0006)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x40, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S7) {  // Slot 7
Name (_ADR, 0x0007)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x80, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S8) {  // Slot 8
Name (_ADR, 0x0008)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x100, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S9) {  // Slot 9
Name (_ADR, 0x0009)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x200, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S10) {  // Slot 10
Name (_ADR, 0x000A)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x400, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S11) {  // Slot 11
Name (_ADR, 0x000B)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x800, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S12) {  // Slot 12
Name (_ADR, 0x000C)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x1000, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S13) {  // Slot 13
Name (_ADR, 0x000D)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x2000, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S14) {  // Slot 14
Name (_ADR, 0x000E)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x4000, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S15) {  // Slot 15
Name (_ADR, 0x000F)
-   Method (_EJ0,1) { Return (0x0) }
+   Method (_EJ0,1) {
+Store(0x8000, B0EJ)
+Return (0x0)
+   }
 }
 
 Device (S16) {  // Slot 16
Na

Re: [Qemu-devel] [PATCH] Modify qemu-img to mount locally disk image using NBD (v2)

2008-03-11 Thread Anthony Liguori

Fabrice Bellard wrote:

Laurent Vivier wrote:
  

This patch is a new version of qemu-img using NBD device to mount Qemu
disk image.

To not hang on UP system, it needs following patch:
http://article.gmane.org/gmane.linux.drivers.nbd.general/42
If you want to use loop to see partitions, you need this patch:
http://article.gmane.org/gmane.linux.kernel/651269
otherwise use kpartx (see kpartx package of your distro).

This patch implements in qemu-img the client and the server of the nbd protocol.
Moreover, to avoid to specify a port to use, it creates a UNIX socket instead of
a INET socket.

It adds two actions to qemu-img:
- bind, to bind a disk image to a NBD device,

  qemu-img bind [-d] [-f fmt] device filename

 ('-d' to daemonize)

- unbind, to unbind it.

  qemu-img unbind device
[...]



Perhaps adding a new specialized tool would be better as there is no
direct relation with qemu-img.
  


I've been maintaining a separate tool for a while now (qemu-nbd) that 
uses the QEMU block driver code.  If there's interest in merging it, 
I'll happily submit patches.


Regards,

Anthony Liguori


Fabrice.


  






Re: [Qemu-devel] [PATCH] x86 Multiboot support (extended)

2008-03-11 Thread Anthony Liguori

Aurelien Jarno wrote:

On Thu, Jan 31, 2008 at 06:31:09PM +0100, Alexander Graf wrote:
  
Is it really necessary to have *that much* assembly code within hw/pc.c?


I would rather see multiboot support as a small image generated from
C and/or assembly code, loaded either with -hda or with a new option
having the same effect. This code could read the NVRAM to get the
variables it needs.
  


Better yet to package it as an option ROM and eliminate all the boot 
sector hacks.


Regards,

Anthony Liguori