[Qemu-devel] [PATCH] Don't zero out buffer in sched_getaffinity
The kernel doesn't fill the buffer provided to sched_getaffinity with zero bytes, so neither should QEMU. Depends on sched_getaffinity buffer overrun fix, but submitted separately to make rollback easier. --- linux-user/syscall.c | 13 + 1 files changed, 1 insertions(+), 12 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 19209a2..e2a5fd9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6382,20 +6382,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask)); if (!is_error(ret)) { -if (arg2 > ret) { -/* Zero out any extra space kernel didn't fill */ -unsigned long zero = arg2 - ret; -p = alloca(zero); -memset(p, 0, zero); -if (copy_to_user(arg3 + ret, p, zero)) { -goto efault; -} -arg2 = ret; -} -if (copy_to_user(arg3, mask, arg2)) { +if (copy_to_user(arg3, mask, ret)) { goto efault; } -ret = arg2; } } break; -- 1.7.0.4
Re: [Qemu-devel] [PATCH 24/26] acpi, acpi_piix: factor out GPE logic
On Sun, Apr 17, 2011 at 06:53:12PM +0300, Avi Kivity wrote: > On 04/17/2011 04:50 PM, Isaku Yamahata wrote: >> On Sun, Apr 17, 2011 at 04:17:51PM +0300, Avi Kivity wrote: >> > On 03/16/2011 11:29 AM, Isaku Yamahata wrote: >> >> factor out ACPI GPE logic. Later it will be used by ICH9 ACPI. >> >> >> > >> > I think this patch is causing qemu-kvm failures on migration: >> > (gdb) bt >> > #0 0x0049aff4 in qemu_put_be16s (f=0x1a74490, pv=0x2c02580, >> > size=2) at hw/hw.h:108 >> > #1 put_uint16 (f=0x1a74490, pv=0x2c02580, size=2) at savevm.c:855 >> > #2 0x0049c3e4 in vmstate_save_state (f=0x1a74490, >> > vmsd=0x6f0b00, opaque=0x1842ef0) at savevm.c:1436 >> > #3 0x0049c3b6 in vmstate_save_state (f=0x1a74490, >> > vmsd=0x6f0aa0, opaque=0x1842b90) at savevm.c:1434 >> > #4 0x0049c6f1 in vmstate_save (mon=, >> > f=0x1a74490) at savevm.c:1459 >> > #5 qemu_savevm_state_complete (mon=, f=0x1a74490) >> > at savevm.c:1600 >> > #6 0x0049455a in migrate_fd_put_ready (opaque=0x1847890) at >> > migration.c:383 >> > #7 0x004ce2eb in qemu_run_timers (clock=) >> > at qemu-timer.c:505 >> > #8 0x004ce806 in qemu_run_all_timers () at qemu-timer.c:619 >> > #9 0x00419463 in main_loop_wait (nonblocking=> > out>) at /build/home/tlv/akivity/qemu-kvm/vl.c:1339 >> > #10 0x00433927 in kvm_main_loop () at >> > /build/home/tlv/akivity/qemu-kvm/qemu-kvm.c:1590 >> > #11 0x0041a3a6 in main_loop (argc=, >> > argv=, envp=) >> > at /build/home/tlv/akivity/qemu-kvm/vl.c:1369 >> > #12 main (argc=, argv=, >> > envp=) at /build/home/tlv/akivity/qemu-kvm/vl.c:3257 >> > >> > The vmstate being migrated is "gpe". >> > >> > >> > >> >> >> >> +#define VMSTATE_GPE_ARRAY(_field, _state)\ >> >> + { \ >> >> + .name = (stringify(_field)), \ >> >> + .version_id = 0,\ >> >> + .num= GPE_LEN, \ >> >> + .info =&vmstate_info_uint16, \ >> >> + .size = sizeof(uint16_t), \ >> >> + .flags = VMS_ARRAY | VMS_POINTER, \ >> >> + .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ >> >> + } >> >> + >> >>static const VMStateDescription vmstate_gpe = { >> >>.name = "gpe", >> >>.version_id = 1, >> >>.minimum_version_id = 1, >> >>.minimum_version_id_old = 1, >> >>.fields = (VMStateField []) { >> >> -VMSTATE_UINT16(sts, struct gpe_regs), >> >> -VMSTATE_UINT16(en, struct gpe_regs), >> >> +VMSTATE_GPE_ARRAY(sts, ACPIGPE), >> >> +VMSTATE_GPE_ARRAY(en, ACPIGPE), >> >>VMSTATE_END_OF_LIST() >> >>} >> >>}; >> > >> > I'm no vmstate expert, but this does look odd. Why both VMS_ARRAY and >> > VMS_POINTER? aren't we trying to save/restore a simple 16-bit value? Or >> > at least we did before this patch. >> >> That's right. the difference is, the new member type became uint8_t*. >> Does the following help? >> > > Unforunately not. The core is very similar though: Hmm but it seems that there is another issue. With the previous patch, I confirmed sts and en are saved as expected. The related VMStateDescription are defined in acpi_piix.c in the following order. vmstate_acpi calls vmstate_gpe. and &vmstate_gpe < &vmstate_acpi. However, your call trace shows something different. (I'm assuming the stack trace is correct. gdb or compiler optimization?) static const VMStateDescription vmstate_gpe = { ... static const VMStateDescription vmstate_acpi = { .fields = (VMStateField []) { ... VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), > > #0 0x0049aff4 in qemu_put_be16s (f=0x2427490, pv=0x1ae7580, > size=2) at hw/hw.h:108 > #1 put_uint16 (f=0x2427490, pv=0x1ae7580, size=2) at savevm.c:855 > #2 0x0049c3e4 in vmstate_save_state (f=0x2427490, > vmsd=0x6f0b00, opaque=0x21f5ef0) at savevm.c:1436 vmsd = 0x6f0b00 = &vmstate_gpe << correct??? opaque = 0x21f5ef0 = &PIIX4PMState->gpe > #3 0x0049c3b6 in vmstate_save_state (f=0x2427490, > vmsd=0x6f0aa0, opaque=0x21f5b90) at savevm.c:1434 vmsd = 0x6f0aa0 = &vmstate_acpi < correct? opaque = 0x21f5b90 = &PIIX4PMState opaque seems correct as 0x21f5b90 - 0x21f5ef0 = 0x348 = offsetof(PIIX4PMState, gpe) On my environment the stack trace looks like (gdb) where #0 vmstate_save_state (f=0x25d16d0, vmsd=0x695940, opaque=0x283a218) at savevm.c:1374 #1 0x004bb4f7 in vmstate_save_state (f=0x25d16d0, vmsd=0x695a40, opaque=0x2839ed0) at savevm.c:1412 ... (gdb) print &vmstate_gpe $32 = (const VMStateDescription *) 0x695940 (gdb) print &vmstate_acpi $33 = (const
Re: [Qemu-devel] [PATCH 24/26] acpi, acpi_piix: factor out GPE logic
On 04/18/2011 10:47 AM, Isaku Yamahata wrote: Hmm but it seems that there is another issue. With the previous patch, I confirmed sts and en are saved as expected. The related VMStateDescription are defined in acpi_piix.c in the following order. vmstate_acpi calls vmstate_gpe. and&vmstate_gpe< &vmstate_acpi. (gdb) p &vmstate_gpe $1 = (const VMStateDescription *) 0x6f0b00 (gdb) p &vmstate_acpi $2 = (const VMStateDescription *) 0x6f0aa0 So no. However, your call trace shows something different. (I'm assuming the stack trace is correct. gdb or compiler optimization?) static const VMStateDescription vmstate_gpe = { ... static const VMStateDescription vmstate_acpi = { .fields = (VMStateField []) { ... VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), > > #0 0x0049aff4 in qemu_put_be16s (f=0x2427490, pv=0x1ae7580, > size=2) at hw/hw.h:108 > #1 put_uint16 (f=0x2427490, pv=0x1ae7580, size=2) at savevm.c:855 > #2 0x0049c3e4 in vmstate_save_state (f=0x2427490, > vmsd=0x6f0b00, opaque=0x21f5ef0) at savevm.c:1436 vmsd = 0x6f0b00 =&vmstate_gpe<< correct??? Correct. opaque = 0x21f5ef0 =&PIIX4PMState->gpe > #3 0x0049c3b6 in vmstate_save_state (f=0x2427490, > vmsd=0x6f0aa0, opaque=0x21f5b90) at savevm.c:1434 vmsd = 0x6f0aa0 =&vmstate_acpi< correct? Correct. opaque = 0x21f5b90 =&PIIX4PMState opaque seems correct as 0x21f5b90 - 0x21f5ef0 = 0x348 = offsetof(PIIX4PMState, gpe) On my environment the stack trace looks like (gdb) where #0 vmstate_save_state (f=0x25d16d0, vmsd=0x695940, opaque=0x283a218) at savevm.c:1374 #1 0x004bb4f7 in vmstate_save_state (f=0x25d16d0, vmsd=0x695a40, opaque=0x2839ed0) at savevm.c:1412 ... (gdb) print&vmstate_gpe $32 = (const VMStateDescription *) 0x695940 (gdb) print&vmstate_acpi $33 = (const VMStateDescription *) 0x695a40 Are you using qemu-kvm.git or qemu.git? I think there are indeed two issues, your patch fixes the first and there is another that is specific to qemu-kvm. -- I have a truly marvellous patch that fixes the bug which this signature is too narrow to contain.
Re: [Qemu-devel] [PATCH v3] hw/pc: Support system flash memory with -pflash parameter
On Thu, Mar 31, 2011 at 11:25:26AM -0700, Jordan Justen wrote: > If -pflash is specified and -bios is specified then pflash will > be mapped just below the system rom using hw/pflash_cfi01.c. > > If -pflash is specified on the command line, but -bios is > not specified, then 'bios.bin' will NOT be loaded, and > instead the -pflash flash image will be mapped just below > 4GB in place of the normal rom image. > > Signed-off-by: Jordan Justen > --- > default-configs/i386-softmmu.mak |1 + > default-configs/x86_64-softmmu.mak |1 + > hw/pc.c| 161 > +++- > 3 files changed, 125 insertions(+), 38 deletions(-) Reviewed-by: Aurelien Jarno > diff --git a/default-configs/i386-softmmu.mak > b/default-configs/i386-softmmu.mak > index 55589fa..8697cd4 100644 > --- a/default-configs/i386-softmmu.mak > +++ b/default-configs/i386-softmmu.mak > @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y > CONFIG_SOUND=y > CONFIG_HPET=y > CONFIG_APPLESMC=y > +CONFIG_PFLASH_CFI01=y > diff --git a/default-configs/x86_64-softmmu.mak > b/default-configs/x86_64-softmmu.mak > index 8895028..eca9284 100644 > --- a/default-configs/x86_64-softmmu.mak > +++ b/default-configs/x86_64-softmmu.mak > @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y > CONFIG_SOUND=y > CONFIG_HPET=y > CONFIG_APPLESMC=y > +CONFIG_PFLASH_CFI01=y > diff --git a/hw/pc.c b/hw/pc.c > index 6939c04..4812310 100644 > --- a/hw/pc.c > +++ b/hw/pc.c > @@ -41,6 +41,7 @@ > #include "sysemu.h" > #include "blockdev.h" > #include "ui/qemu-spice.h" > +#include "flash.h" > > /* output Bochs bios info messages */ > //#define DEBUG_BIOS > @@ -957,6 +958,124 @@ void pc_cpus_init(const char *cpu_model) > } > } > > +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size) > +{ > +int isa_bios_size; > + > +/* map the last 128KB of the BIOS in ISA space */ > +isa_bios_size = ram_size; > +if (isa_bios_size > (128 * 1024)) { > +isa_bios_size = 128 * 1024; > +} > +ram_offset = ram_offset + ram_size - isa_bios_size; > +cpu_register_physical_memory(0x10 - isa_bios_size, > + isa_bios_size, > + ram_offset | IO_MEM_ROM); > +} > + > +static int pc_system_rom_init(void) > +{ > +int ret; > +int bios_size; > +ram_addr_t bios_offset; > +char *filename; > + > +/* BIOS load */ > +if (bios_name == NULL) { > +bios_name = BIOS_FILENAME; > +} > +filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); > +if (filename) { > +bios_size = get_image_size(filename); > +} else { > +bios_size = -1; > +} > + > +if (bios_size <= 0 || (bios_size % 65536) != 0) { > +ret = -1; > +} else { > +bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size); > +ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); > +} > + > +if (ret != 0) { > +fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name); > +exit(1); > +} > + > +if (filename) { > +qemu_free(filename); > +} > + > +pc_isa_bios_init(bios_offset, bios_size); > + > +/* map all the bios at the top of memory */ > +cpu_register_physical_memory((uint32_t)(-bios_size), > + bios_size, bios_offset | IO_MEM_ROM); > + > +return bios_size; > +} > + > +static void pc_system_flash_init(DriveInfo *pflash_drv, int rom_size) > +{ > +BlockDriverState *bdrv; > +int64_t size; > +target_phys_addr_t phys_addr; > +ram_addr_t addr; > +int sector_bits, sector_size; > + > +bdrv = NULL; > + > +bdrv = pflash_drv->bdrv; > +size = bdrv_getlength(pflash_drv->bdrv); > +sector_bits = 12; > +sector_size = 1 << sector_bits; > + > +if ((size % sector_size) != 0) { > +fprintf(stderr, > +"qemu: -pflash size must be a multiple of 0x%x\n", > +sector_size); > +exit(1); > +} > + > +phys_addr = 0x1ULL - rom_size - size; > +addr = qemu_ram_alloc(NULL, "system.flash", size); > +DPRINTF("flash addr: 0x%lx\n", (int64_t)phys_addr); > +pflash_cfi01_register(phys_addr, addr, bdrv, > + sector_size, size >> sector_bits, > + 4, 0x, 0x, 0x, 0x, 0); > + > +if (rom_size == 0) { > +pc_isa_bios_init(addr, size); > +} > +} > + > +static void pc_system_firmware_init(void) > +{ > +int flash_present, rom_present; > +int rom_size; > +DriveInfo *pflash_drv; > + > +pflash_drv = drive_get(IF_PFLASH, 0, 0); > +flash_present = (pflash_drv != NULL); > + > +/* Load rom if -bios is used or if -pflash is not used */ > +rom_present = ((bios_name != NULL) || !flash_present); > + > +/* If rom is present, then it is mapped just below 4GB */ > +if (rom_present) { > +rom_size = pc_system_rom_init(); > +} else
Re: [Qemu-devel] [PATCH] Don't zero out buffer in sched_getaffinity
On Mon, Apr 18, 2011 at 8:03 AM, Mike McCormack wrote: > The kernel doesn't fill the buffer provided to sched_getaffinity > with zero bytes, so neither should QEMU. > > Depends on sched_getaffinity buffer overrun fix, but submitted > separately to make rollback easier. > > --- > linux-user/syscall.c | 13 + > 1 files changed, 1 insertions(+), 12 deletions(-) Reviewed-by: Stefan Hajnoczi
Re: [Qemu-devel] [PATCH 5/5] target-alpha: Emulate Alpha SX164.
On 17 April 2011 18:11, Richard Henderson wrote: > On 04/17/2011 10:03 AM, Peter Maydell wrote: >> On 17 April 2011 17:14, Richard Henderson wrote: >>> pc-bios/palcode-sx164 | Bin 0 -> 107781 bytes >> >> My personal opinion is that if we have the binary blob in qemu git >> we should also have its corresponding source code. > How does this differ from e.g. SeaBios? I think that ought to follow the same rule: 'git clone' and making a release tarball from a git repo should both either (a) not ship a binary blob or (b) include the sources which made up that binary blob I know this isn't exactly where we are today; to some extent I'm trying to see if anybody else agrees with this position... > We don't really have any configury for cross-compilation of the > bios bits. Yes, this is a difficult problem (which also holds for test cases); I'm not objecting to having the blobs in git and in tarballs, I just want the sources too. -- PMM
Re: [Qemu-devel] Question about vpc 004 testcase of qemu-iotests
On Sun, Apr 17, 2011 at 8:21 AM, Lyu Mitnick wrote: > write at image boundary > -write failed: Input/output error > +wrote 4096/4096 bytes at offset 134217728 > +4 KiB, 1 ops; 0. sec (28.678 KiB/sec and 7.1694 ops/sec) The point of this test is to check that I/O past the image boundary fails. vpc may be broken. Stefan
Re: [Qemu-devel] iPXE/Etherboot prompts twice for booting?
On Sat, Apr 16, 2011 at 8:41 PM, Michael Tokarev wrote: > I'm playing with iPXE ROM images again, and see > iPXE prompts two times during bootup. Once like > this: "Press Ctrl-B to configure", at early stage, > even if -boot n is not selected. And second time > when it actually tries to boot, like "Press Ctrl-B > for the command line". > > The same behavor happens with old Etherboot, with > the exception that during init stage it tries to > boot too but fails. > > Any idea how to get rid of that? IIRC you need to #define BANNER_TIMEOUT 0 in src/config/general.h. Stefan
[Qemu-devel] KVM call agenda for April 19th
Please, send in any agenda items you are interested in covering. Later, Juan.
[Qemu-devel] Enhancing qemu-img convert format compatibility
qemu-img is a pretty good Rosetta stone for image formats but it is missing support some format versions. In order to bring qemu-img up-to-date with the latest disk image formats we will need to find specific image files and/or software versions that produce image files that qemu-img cannot understand today. If you have image files that qemu-img is unable to manipulate, please respond with details of the software and version used to produce the image. If possible please include a link to a small example image file. Stefan
Re: [Qemu-devel] Enhancing qemu-img convert format compatibility
On Mon, Apr 18, 2011 at 11:18:42AM +0100, Stefan Hajnoczi wrote: > qemu-img is a pretty good Rosetta stone for image formats but it is > missing support some format versions. In order to bring qemu-img > up-to-date with the latest disk image formats we will need to find > specific image files and/or software versions that produce image files > that qemu-img cannot understand today. > > If you have image files that qemu-img is unable to manipulate, please > respond with details of the software and version used to produce the > image. If possible please include a link to a small example image > file. Stefan, We found that using the vSphere 4.x "Export to OVF" option would produce a VMDK file that qemu-img could not convert to raw. For older qemu-img the file would be converted to something that was not all zeroes, but nevertheless was certainly not a raw disk image. For current qemu-img, we get an "Operation not permitted" error which is at least better than silent corruption. Full details are in this bug report: https://bugzilla.redhat.com/show_bug.cgi?id=548723 Note the links at the top of that bug are broken. The disk image which failed is: http://oirase.annexia.org/tmp/TestLinux-disk1.vmdk SHA1: 2c81bae89210b075acc51da9d025935470149d55 http://oirase.annexia.org/tmp/TestLinux.ovf SHA1: 30831689b8c6f1b1a1fcbb728769b5f71056a580 Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/
Re: [Qemu-devel] Enhancing qemu-img convert format compatibility
On Mon, Apr 18, 2011 at 12:03 PM, Richard W.M. Jones wrote: > On Mon, Apr 18, 2011 at 11:18:42AM +0100, Stefan Hajnoczi wrote: >> qemu-img is a pretty good Rosetta stone for image formats but it is >> missing support some format versions. In order to bring qemu-img >> up-to-date with the latest disk image formats we will need to find >> specific image files and/or software versions that produce image files >> that qemu-img cannot understand today. >> >> If you have image files that qemu-img is unable to manipulate, please >> respond with details of the software and version used to produce the >> image. If possible please include a link to a small example image >> file. > > Stefan, > > We found that using the vSphere 4.x "Export to OVF" option would > produce a VMDK file that qemu-img could not convert to raw. Excellent, thanks for sharing this. I hope we can build a picture of where there is missing support and address this in the "Improved Image Format Compatiblity" project for Google Summer of Code: http://wiki.qemu.org/Google_Summer_of_Code_2011#Improved_image_format_compatibility Stefan
[Qemu-devel] [PATCH V13 00/17] Xen device model support
From: Anthony PERARD Hi all, Here is the few change made since the v12: - There are few changes in the xen init code. A xen_hvm_init function is new in this patch set and is call from xenfv:machine->init. -> So "-xen-create -M xenpv" will continue to work as before this patch series. - There is a new reset handler to set env->halted = 0 on the first vcpu. - One change have been made to pc_memory_init, the calculation of below/above_4g_mem_size have been moved to pc_init1. This is to remove a "random" "if (xen()) return;" in pc_memory_init. - xen_map_block is a new function to map RAMBlock that belong to a ROM/RAM of a device. - fix cpu_physical_memory_unmap with mapcache, Because qemu_get_ram_ptr can be called more than one time in cpu_physical_memory_map, qemu_put_ram_ptr need to be called the same amount of time. - Add some trace_* call. This series depends on the series "Introduce "machine" QemuOpts". You can find a git tree here: git://xenbits.xen.org/people/aperard/qemu-dm.git qemu-dm-v13 Anthony PERARD (13): xen: Replace some tab-indents with spaces (clean-up). xen: Make Xen build once. xen: Support new libxc calls from xen unstable. xen: Add initialisation of Xen pc_memory_init: Move memory calculation to the caller. xen: Add xenfv machine piix_pci: Introduces Xen specific call for irq. xen: Introduce Xen Interrupt Controller Introduce qemu_put_ram_ptr configure: Always use 64bits target physical addresses with xen enabled. vl.c: Introduce getter for shutdown_requested and reset_requested. xen: Set running state in xenstore. xen: Add Xen hypercall for sleep state in the cmos_s3 callback. Arun Sharma (1): xen: Initialize event channels and io rings John Baboval (2): xen: Adds a cap to the number of map cache entries. pci: Use of qemu_put_ram_ptr in pci_add_option_rom. Jun Nakajima (1): xen: Introduce the Xen mapcache Makefile.target | 14 +- configure| 71 ++- cpu-common.h |1 + exec.c | 86 +++- hw/pc.c | 14 +- hw/pc.h |5 +- hw/pc_piix.c | 70 ++- hw/pci.c |2 + hw/piix_pci.c| 47 - hw/xen.h | 41 hw/xen_backend.c | 421 +++ hw/xen_backend.h |6 +- hw/xen_common.h | 106 -- hw/xen_disk.c| 496 ++--- hw/xen_domainbuild.c |3 +- hw/xen_machine_pv.c |1 + hw/xen_nic.c | 265 -- sysemu.h |2 + trace-events | 13 + vl.c | 12 + xen-all.c| 605 ++ xen-mapcache-stub.c | 44 xen-mapcache.c | 375 +++ xen-mapcache.h | 37 +++ xen-stub.c | 41 25 files changed, 2185 insertions(+), 593 deletions(-) create mode 100644 xen-all.c create mode 100644 xen-mapcache-stub.c create mode 100644 xen-mapcache.c create mode 100644 xen-mapcache.h create mode 100644 xen-stub.c -- Anthony PERARD
[Qemu-devel] [PATCH V13 02/17] xen: Make Xen build once.
From: Anthony PERARD xen_domainbuild and xen_machine_pv are built only for i386 targets. Signed-off-by: Anthony PERARD --- Makefile.target |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile.target b/Makefile.target index d5761b7..6ce6987 100644 --- a/Makefile.target +++ b/Makefile.target @@ -206,7 +206,7 @@ QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) QEMU_CFLAGS += $(VNC_PNG_CFLAGS) # xen backend driver support -obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o +obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o # Inter-VM PCI shared memory CONFIG_IVSHMEM = -- 1.7.2.3
[Qemu-devel] [PATCH V13 05/17] pc_memory_init: Move memory calculation to the caller.
From: Anthony PERARD This patch moves above_4g_mem_size and below_4g_mem_size calculation in the caller of pc_memory_init (pc_init1). And the prototype of pc_memory_init is changed because there is no need anymore to have variable pointer. Signed-off-by: Anthony PERARD --- hw/pc.c | 14 ++ hw/pc.h |4 ++-- hw/pc_piix.c | 11 +-- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 6939c04..18b96cc 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -961,25 +961,15 @@ void pc_memory_init(ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, -ram_addr_t *below_4g_mem_size_p, -ram_addr_t *above_4g_mem_size_p) +ram_addr_t below_4g_mem_size, +ram_addr_t above_4g_mem_size) { char *filename; int ret, linux_boot, i; ram_addr_t ram_addr, bios_offset, option_rom_offset; -ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; int bios_size, isa_bios_size; void *fw_cfg; -if (ram_size >= 0xe000 ) { -above_4g_mem_size = ram_size - 0xe000; -below_4g_mem_size = 0xe000; -} else { -below_4g_mem_size = ram_size; -} -*above_4g_mem_size_p = above_4g_mem_size; -*below_4g_mem_size_p = below_4g_mem_size; - linux_boot = (kernel_filename != NULL); /* allocate RAM */ diff --git a/hw/pc.h b/hw/pc.h index feb8a7a..35bb890 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -133,8 +133,8 @@ void pc_memory_init(ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, -ram_addr_t *below_4g_mem_size_p, -ram_addr_t *above_4g_mem_size_p); +ram_addr_t below_4g_mem_size, +ram_addr_t above_4g_mem_size); qemu_irq *pc_allocate_cpu_irq(void); void pc_vga_init(PCIBus *pci_bus); void pc_basic_device_init(qemu_irq *isa_irq, diff --git a/hw/pc_piix.c b/hw/pc_piix.c index a85214b..e487c38 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -72,7 +72,7 @@ static void pc_init1(ram_addr_t ram_size, int kvmclock_enabled) { int i; -ram_addr_t below_4g_mem_size, above_4g_mem_size; +ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; PCIBus *pci_bus; PCII440FXState *i440fx_state; int piix3_devfn = -1; @@ -92,9 +92,16 @@ static void pc_init1(ram_addr_t ram_size, kvmclock_create(); } +if (ram_size >= 0xe000 ) { +above_4g_mem_size = ram_size - 0xe000; +below_4g_mem_size = 0xe000; +} else { +below_4g_mem_size = ram_size; +} + /* allocate ram and load rom/bios */ pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename, - &below_4g_mem_size, &above_4g_mem_size); + below_4g_mem_size, above_4g_mem_size); cpu_irq = pc_allocate_cpu_irq(); i8259 = i8259_init(cpu_irq[0]); -- 1.7.2.3
[Qemu-devel] [PATCH V13 08/17] xen: Introduce Xen Interrupt Controller
From: Anthony PERARD Every set_irq call makes a Xen hypercall. Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini --- hw/pc_piix.c |8 ++-- hw/xen.h |2 ++ xen-all.c| 12 xen-stub.c |5 + 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index ed6df88..27d3253 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -109,8 +109,12 @@ static void pc_init1(ram_addr_t ram_size, initrd_filename, below_4g_mem_size, above_4g_mem_size); } -cpu_irq = pc_allocate_cpu_irq(); -i8259 = i8259_init(cpu_irq[0]); +if (!xen_enabled()) { +cpu_irq = pc_allocate_cpu_irq(); +i8259 = i8259_init(cpu_irq[0]); +} else { +i8259 = xen_interrupt_controller_init(); +} isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state)); isa_irq_state->i8259 = i8259; if (pci_enabled) { diff --git a/hw/xen.h b/hw/xen.h index a4096ca..9f00c0b 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -35,6 +35,8 @@ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num); void xen_piix3_set_irq(void *opaque, int irq_num, int level); void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len); +qemu_irq *xen_interrupt_controller_init(void); + int xen_init(void); int xen_hvm_init(void); void xen_vcpu_init(void); diff --git a/xen-all.c b/xen-all.c index acb051c..bb809ef 100644 --- a/xen-all.c +++ b/xen-all.c @@ -40,6 +40,18 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) } } +/* Xen Interrupt Controller */ + +static void xen_set_irq(void *opaque, int irq, int level) +{ +xc_hvm_set_isa_irq_level(xen_xc, xen_domid, irq, level); +} + +qemu_irq *xen_interrupt_controller_init(void) +{ +return qemu_allocate_irqs(xen_set_irq, NULL, 16); +} + /* VCPU Operations, MMIO, IO ring ... */ static void xen_reset_vcpu(void *opaque) diff --git a/xen-stub.c b/xen-stub.c index dc90f10..3a8449c 100644 --- a/xen-stub.c +++ b/xen-stub.c @@ -22,6 +22,11 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) { } +qemu_irq *xen_interrupt_controller_init(void) +{ +return NULL; +} + int xen_init(void) { return -ENOSYS; -- 1.7.2.3
[Qemu-devel] [PATCH V13 09/17] xen: Introduce the Xen mapcache
From: Jun Nakajima On IA32 host or IA32 PAE host, at present, generally, we can't create an HVM guest with more than 2G memory, because generally it's almost impossible for Qemu to find a large enough and consecutive virtual address space to map an HVM guest's whole physical address space. The attached patch fixes this issue using dynamic mapping based on little blocks of memory. Each call to qemu_get_ram_ptr makes a call to qemu_map_cache with the lock option, so mapcache will not unmap these ram_ptr. Blocks that do not belong to the RAM, but usually to a device ROM or to a framebuffer, are handled in a separate function. So the whole RAMBlock can be map. Signed-off-by: Jun Nakajima Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini --- Makefile.target |3 + configure |3 + exec.c | 48 +++- hw/xen.h| 13 ++ hw/xen_common.h |9 ++ trace-events| 10 ++ xen-all.c | 66 ++ xen-mapcache-stub.c | 44 +++ xen-mapcache.c | 349 +++ xen-mapcache.h | 37 ++ xen-stub.c |4 + 11 files changed, 582 insertions(+), 4 deletions(-) create mode 100644 xen-mapcache-stub.c create mode 100644 xen-mapcache.c create mode 100644 xen-mapcache.h diff --git a/Makefile.target b/Makefile.target index 6b2a41c..c964c0d 100644 --- a/Makefile.target +++ b/Makefile.target @@ -214,8 +214,11 @@ else CONFIG_NO_XEN = y endif # xen support +CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y) obj-i386-$(CONFIG_XEN) += xen-all.o obj-$(CONFIG_NO_XEN) += xen-stub.o +obj-i386-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o +obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o # Inter-VM PCI shared memory CONFIG_IVSHMEM = diff --git a/configure b/configure index 98b79e2..340a810 100755 --- a/configure +++ b/configure @@ -3283,6 +3283,9 @@ case "$target_arch2" in i386|x86_64) if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then echo "CONFIG_XEN=y" >> $config_target_mak + if test "$cpu" = "i386" -o "$cpu" = "x86_64"; then + echo "CONFIG_XEN_MAPCACHE=y" >> $config_target_mak + fi fi esac case "$target_arch2" in diff --git a/exec.c b/exec.c index b1ee52a..3f895eb 100644 --- a/exec.c +++ b/exec.c @@ -32,6 +32,7 @@ #include "hw/qdev.h" #include "osdep.h" #include "kvm.h" +#include "hw/xen.h" #include "qemu-timer.h" #if defined(CONFIG_USER_ONLY) #include @@ -51,6 +52,8 @@ #include #endif #endif +#else /* !CONFIG_USER_ONLY */ +#include "xen-mapcache.h" #endif //#define DEBUG_TB_INVALIDATE @@ -2872,6 +2875,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, } } +new_block->offset = find_ram_offset(size); if (host) { new_block->host = host; new_block->flags |= RAM_PREALLOC_MASK; @@ -2894,13 +2898,15 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); #else -new_block->host = qemu_vmalloc(size); +if (xen_mapcache_enabled()) { +xen_ram_alloc(new_block->offset, size); +} else { +new_block->host = qemu_vmalloc(size); +} #endif qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE); } } - -new_block->offset = find_ram_offset(size); new_block->length = size; QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next); @@ -2945,7 +2951,11 @@ void qemu_ram_free(ram_addr_t addr) #if defined(TARGET_S390X) && defined(CONFIG_KVM) munmap(block->host, block->length); #else -qemu_vfree(block->host); +if (xen_mapcache_enabled()) { +qemu_invalidate_entry(block->host); +} else { +qemu_vfree(block->host); +} #endif } qemu_free(block); @@ -3034,6 +3044,16 @@ void *qemu_get_ram_ptr(ram_addr_t addr) QLIST_REMOVE(block, next); QLIST_INSERT_HEAD(&ram_list.blocks, block, next); } +if (xen_mapcache_enabled()) { +/* We need to check if the requested address is in the RAM + * because we don't want to map the entire memory in QEMU. + */ +if (block->offset == 0) { +return qemu_map_cache(addr, 0, 1); +} else if (block->host == NULL) { +block->host = xen_map_block(block->offset, block->length); +} +} return block->host + (addr - block->offset); } } @@ -3053,6 +3073,16 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) QLIST_FOREACH(block, &ram_list.blocks, next) { if (addr - blo
[Qemu-devel] [PATCH V13 06/17] xen: Add xenfv machine
From: Anthony PERARD Introduce the Xen FV (Fully Virtualized) machine to Qemu, some more Xen specific call will be added in further patches. Signed-off-by: Anthony PERARD --- hw/pc_piix.c | 41 +++-- hw/xen.h |6 ++ xen-all.c| 24 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index e487c38..9c757c4 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -38,6 +38,10 @@ #include "arch_init.h" #include "blockdev.h" #include "smbus.h" +#include "xen.h" +#ifdef CONFIG_XEN +# include +#endif #define MAX_IDE_BUS 2 @@ -100,8 +104,10 @@ static void pc_init1(ram_addr_t ram_size, } /* allocate ram and load rom/bios */ -pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename, - below_4g_mem_size, above_4g_mem_size); +if (!xen_enabled()) { +pc_memory_init(ram_size, kernel_filename, kernel_cmdline, + initrd_filename, below_4g_mem_size, above_4g_mem_size); +} cpu_irq = pc_allocate_cpu_irq(); i8259 = i8259_init(cpu_irq[0]); @@ -220,6 +226,24 @@ static void pc_init_isa(ram_addr_t ram_size, initrd_filename, cpu_model, 0, 1); } +#ifdef CONFIG_XEN +static void pc_xen_hvm_init(ram_addr_t ram_size, +const char *boot_device, +const char *kernel_filename, +const char *kernel_cmdline, +const char *initrd_filename, +const char *cpu_model) +{ +if (xen_hvm_init() != 0) { +hw_error("xen hardware virtual machine initialisation failed"); +} +pc_init_pci_no_kvmclock(ram_size, boot_device, +kernel_filename, kernel_cmdline, +initrd_filename, cpu_model); +xen_vcpu_init(); +} +#endif + static QEMUMachine pc_machine = { .name = "pc-0.14", .alias = "pc", @@ -384,6 +408,16 @@ static QEMUMachine isapc_machine = { .max_cpus = 1, }; +#ifdef CONFIG_XEN +static QEMUMachine xenfv_machine = { +.name = "xenfv", +.desc = "Xen Fully-virtualized PC", +.init = pc_xen_hvm_init, +.max_cpus = HVM_MAX_VCPUS, +.default_machine_opts = "accel=xen", +}; +#endif + static void pc_machine_init(void) { qemu_register_machine(&pc_machine); @@ -392,6 +426,9 @@ static void pc_machine_init(void) qemu_register_machine(&pc_machine_v0_11); qemu_register_machine(&pc_machine_v0_10); qemu_register_machine(&isapc_machine); +#ifdef CONFIG_XEN +qemu_register_machine(&xenfv_machine); +#endif } machine_init(pc_machine_init); diff --git a/hw/xen.h b/hw/xen.h index 1fefe3a..bb4dcb5 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -30,5 +30,11 @@ static inline int xen_enabled(void) } int xen_init(void); +int xen_hvm_init(void); +void xen_vcpu_init(void); + +#if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400 +# define HVM_MAX_VCPUS 32 +#endif #endif /* QEMU_HW_XEN_H */ diff --git a/xen-all.c b/xen-all.c index e2872f9..0b984b2 100644 --- a/xen-all.c +++ b/xen-all.c @@ -9,6 +9,25 @@ #include "hw/xen_common.h" #include "hw/xen_backend.h" +/* VCPU Operations, MMIO, IO ring ... */ + +static void xen_reset_vcpu(void *opaque) +{ +CPUState *env = opaque; + +env->halted = 1; +} + +void xen_vcpu_init(void) +{ +CPUState *first_cpu; + +if ((first_cpu = qemu_get_cpu(0))) { +qemu_register_reset(xen_reset_vcpu, first_cpu); +xen_reset_vcpu(first_cpu); +} +} + /* Initialise Xen */ int xen_init(void) @@ -21,3 +40,8 @@ int xen_init(void) return 0; } + +int xen_hvm_init(void) +{ +return 0; +} -- 1.7.2.3
Re: [Qemu-devel] [PATCH 02/17] s390x: s390x-linux-user support
Hi, The patch looks OK, but I'd like to have a try with some s390x static binaries. Such binaries are also useful for me to test that new patches for linxu-user don't break targets I don't usually use. Riku On Fri, Apr 15, 2011 at 05:32:43PM +0200, Alexander Graf wrote: > From: Ulrich Hecht > > This patch adds support for running s390x binaries in the linux-user emulation > code. > > Signed-off-by: Ulrich Hecht > Signed-off-by: Alexander Graf > > --- > > v1 -> v2: > > - always set 64bit flag for s390x binaries in elf loader > - remove redundant EXECUTE_SVC > - advance psw.addr in syscall execution path > > v3 -> v4: > > - fix 32bit hosts > - fix coding style (except for header files shared with Linux) > --- > linux-user/elfload.c | 19 ++ > linux-user/main.c| 83 + > linux-user/s390x/syscall.h | 23 +++ > linux-user/s390x/syscall_nr.h| 349 > ++ > linux-user/s390x/target_signal.h | 26 +++ > linux-user/s390x/termbits.h | 283 ++ > linux-user/signal.c | 333 > linux-user/syscall.c | 16 ++- > linux-user/syscall_defs.h| 55 ++- > scripts/qemu-binfmt-conf.sh |4 +- > 10 files changed, 1184 insertions(+), 7 deletions(-) > create mode 100644 linux-user/s390x/syscall.h > create mode 100644 linux-user/s390x/syscall_nr.h > create mode 100644 linux-user/s390x/target_signal.h > create mode 100644 linux-user/s390x/termbits.h > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index 4c399f8..dcfeb7a 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -867,6 +867,25 @@ static inline void init_thread(struct target_pt_regs > *regs, > > #endif /* TARGET_ALPHA */ > > +#ifdef TARGET_S390X > + > +#define ELF_START_MMAP (0x200ULL) > + > +#define elf_check_arch(x) ( (x) == ELF_ARCH ) > + > +#define ELF_CLASSELFCLASS64 > +#define ELF_DATA ELFDATA2MSB > +#define ELF_ARCH EM_S390 > + > +static inline void init_thread(struct target_pt_regs *regs, struct > image_info *infop) > +{ > +regs->psw.addr = infop->entry; > +regs->psw.mask = PSW_MASK_64 | PSW_MASK_32; > +regs->gprs[15] = infop->start_stack; > +} > + > +#endif /* TARGET_S390X */ > + > #ifndef ELF_PLATFORM > #define ELF_PLATFORM (NULL) > #endif > diff --git a/linux-user/main.c b/linux-user/main.c > index a1e37e4..82aaf9d 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -2701,6 +2701,80 @@ void cpu_loop (CPUState *env) > } > #endif /* TARGET_ALPHA */ > > +#ifdef TARGET_S390X > +void cpu_loop(CPUS390XState *env) > +{ > +int trapnr; > +target_siginfo_t info; > + > +while (1) { > +trapnr = cpu_s390x_exec (env); > + > +switch (trapnr) { > +case EXCP_INTERRUPT: > +/* just indicate that signals should be handled asap */ > +break; > +case EXCP_DEBUG: > +{ > +int sig; > + > +sig = gdb_handlesig (env, TARGET_SIGTRAP); > +if (sig) { > +info.si_signo = sig; > +info.si_errno = 0; > +info.si_code = TARGET_TRAP_BRKPT; > +queue_signal(env, info.si_signo, &info); > +} > +} > +break; > +case EXCP_SVC: > +{ > +int n = env->int_svc_code; > +if (!n) { > +/* syscalls > 255 */ > +n = env->regs[1]; > +} > +env->psw.addr += env->int_svc_ilc; > +env->regs[2] = do_syscall(env, n, > + env->regs[2], > + env->regs[3], > + env->regs[4], > + env->regs[5], > + env->regs[6], > + env->regs[7]); > +} > +break; > +case EXCP_ADDR: > +{ > +info.si_signo = SIGSEGV; > +info.si_errno = 0; > +/* XXX: check env->error_code */ > +info.si_code = TARGET_SEGV_MAPERR; > +info._sifields._sigfault._addr = env->__excp_addr; > +queue_signal(env, info.si_signo, &info); > +} > +break; > +case EXCP_SPEC: > +{ > +fprintf(stderr,"specification exception insn 0x%08x%04x\n", > ldl(env->psw.addr), lduw(env->psw.addr + 4)); > +info.si_signo = SIGILL; > +info.si_errno = 0; > +info.si_code = TARGET_ILL_ILLOPC; > +info._sifields._sigfault._addr = env->__excp_addr; > +queue_signal(env, info.si_signo, &info); > +} > +break; > +default: > +printf ("Unhandled trap:
[Qemu-devel] [PATCH V13 10/17] xen: Adds a cap to the number of map cache entries.
From: John Baboval Adds a cap to the number of map cache entries. This prevents the map cache from overwhelming system memory. I also removed the bitmap macros and #included bitmap.h instead. Signed-off-By: John Baboval Signed-off-by: Anthony PERARD --- xen-mapcache.c | 37 +++-- 1 files changed, 15 insertions(+), 22 deletions(-) diff --git a/xen-mapcache.c b/xen-mapcache.c index a539358..2ca18ce 100644 --- a/xen-mapcache.c +++ b/xen-mapcache.c @@ -12,6 +12,7 @@ #include "hw/xen_backend.h" #include "blockdev.h" +#include "bitmap.h" #include #include @@ -32,15 +33,13 @@ #if defined(__i386__) # define MCACHE_BUCKET_SHIFT 16 +# define MCACHE_MAX_SIZE (1UL<<31) /* 2GB Cap */ #elif defined(__x86_64__) # define MCACHE_BUCKET_SHIFT 20 +# define MCACHE_MAX_SIZE (1UL<<35) /* 32GB Cap */ #endif #define MCACHE_BUCKET_SIZE (1UL << MCACHE_BUCKET_SHIFT) -#define BITS_PER_LONG (sizeof(long) * 8) -#define BITS_TO_LONGS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG) -#define DECLARE_BITMAP(name, bits) unsigned long name[BITS_TO_LONGS(bits)] - typedef struct MapCacheEntry { target_phys_addr_t paddr_index; uint8_t *vaddr_base; @@ -69,11 +68,6 @@ typedef struct MapCache { static MapCache *mapcache; -static inline int test_bit(unsigned int bit, const unsigned long *map) -{ -return !!((map)[(bit) / BITS_PER_LONG] & (1UL << ((bit) % BITS_PER_LONG))); -} - void qemu_map_cache_init(void) { unsigned long size; @@ -85,9 +79,14 @@ void qemu_map_cache_init(void) mapcache->last_address_index = -1; getrlimit(RLIMIT_AS, &rlimit_as); -rlimit_as.rlim_cur = rlimit_as.rlim_max; +if (rlimit_as.rlim_max < MCACHE_MAX_SIZE) { +rlimit_as.rlim_cur = rlimit_as.rlim_max; +} else { +rlimit_as.rlim_cur = MCACHE_MAX_SIZE; +} + setrlimit(RLIMIT_AS, &rlimit_as); -mapcache->max_mcache_size = rlimit_as.rlim_max; +mapcache->max_mcache_size = rlimit_as.rlim_cur; mapcache->nr_buckets = (((mapcache->max_mcache_size >> XC_PAGE_SHIFT) + @@ -107,7 +106,7 @@ static void qemu_remap_bucket(MapCacheEntry *entry, uint8_t *vaddr_base; xen_pfn_t *pfns; int *err; -unsigned int i, j; +unsigned int i; target_phys_addr_t nb_pfn = size >> XC_PAGE_SHIFT; trace_qemu_remap_bucket(address_index); @@ -136,17 +135,11 @@ static void qemu_remap_bucket(MapCacheEntry *entry, entry->vaddr_base = vaddr_base; entry->paddr_index = address_index; -for (i = 0; i < nb_pfn; i += BITS_PER_LONG) { -unsigned long word = 0; -if ((i + BITS_PER_LONG) > nb_pfn) { -j = nb_pfn % BITS_PER_LONG; -} else { -j = BITS_PER_LONG; -} -while (j > 0) { -word = (word << 1) | !err[i + --j]; +bitmap_zero(entry->valid_mapping, nb_pfn); +for (i = 0; i < nb_pfn; i++) { +if (!err[i]) { +bitmap_set(entry->valid_mapping, i, 1); } -entry->valid_mapping[i / BITS_PER_LONG] = word; } qemu_free(pfns); -- 1.7.2.3
[Qemu-devel] [PATCH V13 03/17] xen: Support new libxc calls from xen unstable.
From: Anthony PERARD This patch updates the libxenctrl calls in Qemu to use the new interface, otherwise Qemu wouldn't be able to build against new versions of the library. We check libxenctrl version in configure, from Xen 3.3.0 to Xen unstable. Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini Acked-by: Alexander Graf --- configure| 67 ++- hw/xen_backend.c | 21 ++- hw/xen_backend.h |6 ++-- hw/xen_common.h | 95 ++--- hw/xen_disk.c|4 +- hw/xen_domainbuild.c |3 +- 6 files changed, 164 insertions(+), 32 deletions(-) diff --git a/configure b/configure index da2da04..98b79e2 100755 --- a/configure +++ b/configure @@ -127,6 +127,7 @@ vnc_jpeg="" vnc_png="" vnc_thread="no" xen="" +xen_ctrl_version="" linux_aio="" attr="" vhost_net="" @@ -1180,20 +1181,81 @@ fi if test "$xen" != "no" ; then xen_libs="-lxenstore -lxenctrl -lxenguest" + + # Xen unstable cat > $TMPC < #include -int main(void) { xs_daemon_open(); xc_interface_open(); return 0; } +#include +#include +#if !defined(HVM_MAX_VCPUS) +# error HVM_MAX_VCPUS not defined +#endif +int main(void) { + xc_interface *xc; + xs_daemon_open(); + xc = xc_interface_open(0, 0, 0); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_gnttab_open(NULL, 0); + return 0; +} EOF if compile_prog "" "$xen_libs" ; then +xen_ctrl_version=410 xen=yes -libs_softmmu="$xen_libs $libs_softmmu" + + # Xen 4.0.0 + elif ( + cat > $TMPC < +#include +#include +#include +#if !defined(HVM_MAX_VCPUS) +# error HVM_MAX_VCPUS not defined +#endif +int main(void) { + xs_daemon_open(); + xc_interface_open(); + xc_gnttab_open(); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + return 0; +} +EOF + compile_prog "" "$xen_libs" +) ; then +xen_ctrl_version=400 +xen=yes + + # Xen 3.3.0, 3.4.0 + elif ( + cat > $TMPC < +#include +int main(void) { + xs_daemon_open(); + xc_interface_open(); + xc_gnttab_open(); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + return 0; +} +EOF + compile_prog "" "$xen_libs" +) ; then +xen_ctrl_version=330 +xen=yes + + # Xen not found or unsupported else if test "$xen" = "yes" ; then feature_not_found "xen" fi xen=no fi + + if test "$xen" = yes; then +libs_softmmu="$xen_libs $libs_softmmu" + fi fi ## @@ -2847,6 +2909,7 @@ if test "$bluez" = "yes" ; then fi if test "$xen" = "yes" ; then echo "CONFIG_XEN=y" >> $config_host_mak + echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak fi if test "$io_thread" = "yes" ; then echo "CONFIG_IOTHREAD=y" >> $config_host_mak diff --git a/hw/xen_backend.c b/hw/xen_backend.c index 9f4ec4b..5f58a3f 100644 --- a/hw/xen_backend.c +++ b/hw/xen_backend.c @@ -43,7 +43,8 @@ /* - */ /* public */ -int xen_xc; +XenXC xen_xc = XC_HANDLER_INITIAL_VALUE; +XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE; struct xs_handle *xenstore = NULL; const char *xen_protocol; @@ -214,8 +215,8 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, xendev->debug = debug; xendev->local_port = -1; -xendev->evtchndev = xc_evtchn_open(); -if (xendev->evtchndev < 0) { +xendev->evtchndev = xen_xc_evtchn_open(NULL, 0); +if (xendev->evtchndev == XC_HANDLER_INITIAL_VALUE) { xen_be_printf(NULL, 0, "can't open evtchn device\n"); qemu_free(xendev); return NULL; @@ -223,15 +224,15 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC); if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) { -xendev->gnttabdev = xc_gnttab_open(); -if (xendev->gnttabdev < 0) { +xendev->gnttabdev = xen_xc_gnttab_open(NULL, 0); +if (xendev->gnttabdev == XC_HANDLER_INITIAL_VALUE) { xen_be_printf(NULL, 0, "can't open gnttab device\n"); xc_evtchn_close(xendev->evtchndev); qemu_free(xendev); return NULL; } } else { -xendev->gnttabdev = -1; +xendev->gnttabdev = XC_HANDLER_INITIAL_VALUE; } QTAILQ_INSERT_TAIL(&xendevs, xendev, next); @@ -277,10 +278,10 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev) qemu_free(xendev->fe); } -if (xendev->evtchndev >= 0) { +if (xendev->evtchndev != XC_HANDLER_INITIAL_VALUE) { xc_evtchn_close(xendev->evtchndev); } -if (xendev->gnttabdev >= 0) { +if (xendev->gnttabdev != XC_HANDLER_INITIAL_VALUE) { xc_gnttab_close(xendev->gnttabdev); } @@ -664,8 +665,8 @@ int xen_be_init(void) goto err; } -xen_xc = xc_
[Qemu-devel] [PATCH V13 13/17] pci: Use of qemu_put_ram_ptr in pci_add_option_rom.
From: John Baboval Prevent a deadlock caused by leaving a map cache bucket locked by the preceding qemu_get_ram_ptr() call. Signed-off-By: John Baboval Signed-off-by: Anthony PERARD --- hw/pci.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 6b577e1..2b24dd4 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1897,6 +1897,8 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom) pci_patch_ids(pdev, ptr, size); } +qemu_put_ram_ptr(ptr); + pci_register_bar(pdev, PCI_ROM_SLOT, size, 0, pci_map_option_rom); -- 1.7.2.3
[Qemu-devel] [PATCH V13 04/17] xen: Add initialisation of Xen
From: Anthony PERARD The xenpv machine use the common init function. Signed-off-by: Anthony PERARD Acked-by: Alexander Graf --- Makefile.target |9 + hw/xen.h| 13 + hw/xen_backend.c|3 +-- hw/xen_machine_pv.c |1 + vl.c|2 ++ xen-all.c | 23 +++ xen-stub.c | 15 +++ 7 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 xen-all.c create mode 100644 xen-stub.c diff --git a/Makefile.target b/Makefile.target index 6ce6987..6b2a41c 100644 --- a/Makefile.target +++ b/Makefile.target @@ -208,6 +208,15 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS) # xen backend driver support obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o +ifeq ($(TARGET_BASE_ARCH), i386) + CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y) +else + CONFIG_NO_XEN = y +endif +# xen support +obj-i386-$(CONFIG_XEN) += xen-all.o +obj-$(CONFIG_NO_XEN) += xen-stub.o + # Inter-VM PCI shared memory CONFIG_IVSHMEM = ifeq ($(CONFIG_KVM), y) diff --git a/hw/xen.h b/hw/xen.h index 780dcf7..1fefe3a 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -18,4 +18,17 @@ enum xen_mode { extern uint32_t xen_domid; extern enum xen_mode xen_mode; +extern int xen_allowed; + +static inline int xen_enabled(void) +{ +#ifdef CONFIG_XEN +return xen_allowed; +#else +return 0; +#endif +} + +int xen_init(void); + #endif /* QEMU_HW_XEN_H */ diff --git a/hw/xen_backend.c b/hw/xen_backend.c index 5f58a3f..d881fa2 100644 --- a/hw/xen_backend.c +++ b/hw/xen_backend.c @@ -665,9 +665,8 @@ int xen_be_init(void) goto err; } -xen_xc = xen_xc_interface_open(0, 0, 0); if (xen_xc == XC_HANDLER_INITIAL_VALUE) { -xen_be_printf(NULL, 0, "can't open xen interface\n"); +/* Check if xen_init() have been called */ goto err; } return 0; diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c index 77a34bf..f77be7e 100644 --- a/hw/xen_machine_pv.c +++ b/hw/xen_machine_pv.c @@ -114,6 +114,7 @@ static QEMUMachine xenpv_machine = { .desc = "Xen Para-virtualized PC", .init = xen_init_pv, .max_cpus = 1, +.default_machine_opts = "accel=xen", }; static void xenpv_machine_init(void) diff --git a/vl.c b/vl.c index d06c1f9..b67068e 100644 --- a/vl.c +++ b/vl.c @@ -259,6 +259,7 @@ static NotifierList machine_init_done_notifiers = static int tcg_allowed = 1; int kvm_allowed = 0; +int xen_allowed = 0; uint32_t xen_domid; enum xen_mode xen_mode = XEN_EMULATE; @@ -1890,6 +1891,7 @@ static struct { int *allowed; } accel_list[] = { { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed }, +{ "xen", "Xen", xen_available, xen_init, &xen_allowed }, { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed }, }; diff --git a/xen-all.c b/xen-all.c new file mode 100644 index 000..e2872f9 --- /dev/null +++ b/xen-all.c @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2010 Citrix Ltd. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "hw/xen_common.h" +#include "hw/xen_backend.h" + +/* Initialise Xen */ + +int xen_init(void) +{ +xen_xc = xen_xc_interface_open(0, 0, 0); +if (xen_xc == XC_HANDLER_INITIAL_VALUE) { +xen_be_printf(NULL, 0, "can't open xen interface\n"); +return -1; +} + +return 0; +} diff --git a/xen-stub.c b/xen-stub.c new file mode 100644 index 000..beb982f --- /dev/null +++ b/xen-stub.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2010 Citrix Ltd. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "qemu-common.h" +#include "hw/xen.h" + +int xen_init(void) +{ +return -ENOSYS; +} -- 1.7.2.3
[Qemu-devel] [PATCH V13 17/17] xen: Add Xen hypercall for sleep state in the cmos_s3 callback.
From: Anthony PERARD Signed-off-by: Anthony PERARD --- hw/pc_piix.c |6 +- hw/xen.h |1 + xen-all.c|9 + xen-stub.c |4 4 files changed, 19 insertions(+), 1 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 27d3253..d2ecd19 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -178,7 +178,11 @@ static void pc_init1(ram_addr_t ram_size, if (pci_enabled && acpi_enabled) { i2c_bus *smbus; -cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); +if (!xen_enabled()) { +cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); +} else { +cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1); +} smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, diff --git a/hw/xen.h b/hw/xen.h index 6245b38..d435ca0 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -43,6 +43,7 @@ static inline int xen_mapcache_enabled(void) int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num); void xen_piix3_set_irq(void *opaque, int irq_num, int level); void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len); +void xen_cmos_set_s3_resume(void *opaque, int irq, int level); qemu_irq *xen_interrupt_controller_init(void); diff --git a/xen-all.c b/xen-all.c index 19c2fe1..0eac202 100644 --- a/xen-all.c +++ b/xen-all.c @@ -9,6 +9,7 @@ #include #include "hw/pci.h" +#include "hw/pc.h" #include "hw/xen_common.h" #include "hw/xen_backend.h" @@ -99,6 +100,14 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) } } +void xen_cmos_set_s3_resume(void *opaque, int irq, int level) +{ +pc_cmos_set_s3_resume(opaque, irq, level); +if (level) { +xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3); +} +} + /* Xen Interrupt Controller */ static void xen_set_irq(void *opaque, int irq, int level) diff --git a/xen-stub.c b/xen-stub.c index 8d2fa54..a4f35a1 100644 --- a/xen-stub.c +++ b/xen-stub.c @@ -22,6 +22,10 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) { } +void xen_cmos_set_s3_resume(void *opaque, int irq, int level) +{ +} + void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) { } -- 1.7.2.3
[Qemu-devel] [PATCH V13 07/17] piix_pci: Introduces Xen specific call for irq.
From: Anthony PERARD This patch introduces Xen specific call in piix_pci. The specific part for Xen is in write_config, set_irq and get_pirq. Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini Acked-by: Alexander Graf --- hw/pc.h |1 + hw/pc_piix.c |6 +- hw/piix_pci.c | 47 --- hw/xen.h |6 ++ xen-all.c | 31 +++ xen-stub.c| 13 + 6 files changed, 100 insertions(+), 4 deletions(-) diff --git a/hw/pc.h b/hw/pc.h index 35bb890..73778fe 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -176,6 +176,7 @@ struct PCII440FXState; typedef struct PCII440FXState PCII440FXState; PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size); +PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size); void i440fx_init_memory_mappings(PCII440FXState *d); /* piix4.c */ diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 9c757c4..ed6df88 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -119,7 +119,11 @@ static void pc_init1(ram_addr_t ram_size, isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); if (pci_enabled) { -pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); +if (!xen_enabled()) { +pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); +} else { +pci_bus = i440fx_xen_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); +} } else { pci_bus = NULL; i440fx_state = NULL; diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 358da58..c11a7f6 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -29,6 +29,7 @@ #include "isa.h" #include "sysbus.h" #include "range.h" +#include "xen.h" /* * I440FX chipset data sheet. @@ -151,6 +152,13 @@ static void i440fx_write_config(PCIDevice *dev, } } +static void i440fx_write_config_xen(PCIDevice *dev, +uint32_t address, uint32_t val, int len) +{ +xen_piix_pci_write_config_client(address, val, len); +i440fx_write_config(dev, address, val, len); +} + static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id) { PCII440FXState *d = opaque; @@ -216,7 +224,10 @@ static int i440fx_initfn(PCIDevice *dev) return 0; } -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size) +static PCIBus *i440fx_common_init(const char *device_name, + PCII440FXState **pi440fx_state, + int *piix3_devfn, + qemu_irq *pic, ram_addr_t ram_size) { DeviceState *dev; PCIBus *b; @@ -230,13 +241,13 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * s->bus = b; qdev_init_nofail(dev); -d = pci_create_simple(b, 0, "i440FX"); +d = pci_create_simple(b, 0, device_name); *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); piix3 = DO_UPCAST(PIIX3State, dev, pci_create_simple_multifunction(b, -1, true, "PIIX3")); piix3->pic = pic; -pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); + (*pi440fx_state)->piix3 = piix3; *piix3_devfn = piix3->dev.devfn; @@ -249,6 +260,28 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * return b; } +PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, +qemu_irq *pic, ram_addr_t ram_size) +{ +PCIBus *b; + +b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, ram_size); +pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, (*pi440fx_state)->piix3, 4); + +return b; +} + +PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn, +qemu_irq *pic, ram_addr_t ram_size) +{ +PCIBus *b; + +b = i440fx_common_init("i440FX-xen", pi440fx_state, piix3_devfn, pic, ram_size); +pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, (*pi440fx_state)->piix3, 4); + +return b; +} + /* PIIX3 PCI to ISA bridge */ static void piix3_set_irq(void *opaque, int irq_num, int level) @@ -352,6 +385,14 @@ static PCIDeviceInfo i440fx_info[] = { .init = i440fx_initfn, .config_write = i440fx_write_config, },{ +.qdev.name= "i440FX-xen", +.qdev.desc= "Host bridge", +.qdev.size= sizeof(PCII440FXState), +.qdev.vmsd= &vmstate_i440fx, +.qdev.no_user = 1, +.init = i440fx_initfn, +.config_write = i440fx_write_config_xen, +},{ .qdev.name= "PIIX3", .qdev.desc= "ISA bridge", .qdev.size= sizeof(PIIX3State), diff --git a/hw/xen.h b/hw/xen.h index bb4dcb5..a4096ca 100644 --- a/hw/xen.h +++ b/hw/xen.h @@
[Qemu-devel] [PATCH V13 15/17] xen: Initialize event channels and io rings
From: Arun Sharma Open and bind event channels; map ioreq and buffered ioreq rings. Signed-off-by: Arun Sharma Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini Acked-by: Alexander Graf --- hw/xen_common.h |2 + xen-all.c | 417 +++ 2 files changed, 419 insertions(+), 0 deletions(-) diff --git a/hw/xen_common.h b/hw/xen_common.h index dd3e896..a1958a0 100644 --- a/hw/xen_common.h +++ b/hw/xen_common.h @@ -107,4 +107,6 @@ static inline int xc_fd(xc_interface *xen_xc) } #endif +void destroy_hvm_domain(void); + #endif /* QEMU_HW_XEN_COMMON_H */ diff --git a/xen-all.c b/xen-all.c index cb01ab9..e849a38 100644 --- a/xen-all.c +++ b/xen-all.c @@ -6,6 +6,8 @@ * */ +#include + #include "hw/pci.h" #include "hw/xen_common.h" #include "hw/xen_backend.h" @@ -13,6 +15,58 @@ #include "xen-mapcache.h" #include "trace.h" +#include +#include + +//#define DEBUG_XEN + +#ifdef DEBUG_XEN +#define DPRINTF(fmt, ...) \ +do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ +do { } while (0) +#endif + +/* Compatibility with older version */ +#if __XEN_LATEST_INTERFACE_VERSION__ < 0x0003020a +static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i) +{ +return shared_page->vcpu_iodata[i].vp_eport; +} +static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu) +{ +return &shared_page->vcpu_iodata[vcpu].vp_ioreq; +} +# define FMT_ioreq_size PRIx64 +#else +static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i) +{ +return shared_page->vcpu_ioreq[i].vp_eport; +} +static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu) +{ +return &shared_page->vcpu_ioreq[vcpu]; +} +# define FMT_ioreq_size "u" +#endif + +#define BUFFER_IO_MAX_DELAY 100 + +typedef struct XenIOState { +shared_iopage_t *shared_page; +buffered_iopage_t *buffered_io_page; +QEMUTimer *buffered_io_timer; +/* the evtchn port for polling the notification, */ +evtchn_port_t *ioreq_local_port; +/* the evtchn fd for polling */ +XenEvtchn xce_handle; +/* which vcpu we are serving */ +int send_vcpu; + +Notifier exit; +} XenIOState; + /* Xen specific function for piix pci */ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) @@ -133,8 +187,304 @@ void xen_vcpu_init(void) } } +/* get the ioreq packets from share mem */ +static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu) +{ +ioreq_t *req = xen_vcpu_ioreq(state->shared_page, vcpu); + +if (req->state != STATE_IOREQ_READY) { +DPRINTF("I/O request not ready: " +"%x, ptr: %x, port: %"PRIx64", " +"data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n", +req->state, req->data_is_ptr, req->addr, +req->data, req->count, req->size); +return NULL; +} + +xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */ + +req->state = STATE_IOREQ_INPROCESS; +return req; +} + +/* use poll to get the port notification */ +/* ioreq_vec--out,the */ +/* retval--the number of ioreq packet */ +static ioreq_t *cpu_get_ioreq(XenIOState *state) +{ +int i; +evtchn_port_t port; + +port = xc_evtchn_pending(state->xce_handle); +if (port != -1) { +for (i = 0; i < smp_cpus; i++) { +if (state->ioreq_local_port[i] == port) { +break; +} +} + +if (i == smp_cpus) { +hw_error("Fatal error while trying to get io event!\n"); +} + +/* unmask the wanted port again */ +xc_evtchn_unmask(state->xce_handle, port); + +/* get the io packet from shared memory */ +state->send_vcpu = i; +return cpu_get_ioreq_from_shared_memory(state, i); +} + +/* read error or read nothing */ +return NULL; +} + +static uint32_t do_inp(pio_addr_t addr, unsigned long size) +{ +switch (size) { +case 1: +return cpu_inb(addr); +case 2: +return cpu_inw(addr); +case 4: +return cpu_inl(addr); +default: +hw_error("inp: bad size: %04"FMT_pioaddr" %lx", addr, size); +} +} + +static void do_outp(pio_addr_t addr, +unsigned long size, uint32_t val) +{ +switch (size) { +case 1: +return cpu_outb(addr, val); +case 2: +return cpu_outw(addr, val); +case 4: +return cpu_outl(addr, val); +default: +hw_error("outp: bad size: %04"FMT_pioaddr" %lx", addr, size); +} +} + +static void cpu_ioreq_pio(ioreq_t *req) +{ +int i, sign; + +sign = req->df ? -1 : 1; + +if (req->dir == IOREQ_READ) { +if (!req->data_is_ptr) { +req->data = do_inp(req->addr, req->size); +} else { +uint32_t tmp; + +
[Qemu-devel] [PATCH V13 11/17] Introduce qemu_put_ram_ptr
From: Anthony PERARD This function allows to unlock a ram_ptr give by qemu_get_ram_ptr. After a call to qemu_put_ram_ptr, the pointer may be unmap from QEMU when used with Xen. Signed-off-by: Anthony PERARD Acked-by: Alexander Graf --- cpu-common.h |1 + exec.c | 38 +++--- trace-events |3 +++ xen-mapcache.c | 33 + 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index 96c02ae..1d4fdbf 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -56,6 +56,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr); /* Same but slower, to use for migration, where the order of * RAMBlocks must not change. */ void *qemu_safe_ram_ptr(ram_addr_t addr); +void qemu_put_ram_ptr(void *addr); /* This should not be used by devices. */ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr); ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr); diff --git a/exec.c b/exec.c index 3f895eb..85553f4 100644 --- a/exec.c +++ b/exec.c @@ -3093,6 +3093,27 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) return NULL; } +void qemu_put_ram_ptr(void *addr) +{ +trace_qemu_put_ram_ptr(addr); + +if (xen_mapcache_enabled()) { +RAMBlock *block; + +QLIST_FOREACH(block, &ram_list.blocks, next) { +if (addr == block->host) { +break; +} +} +if (block && block->host) { +xen_unmap_block(block->host, block->length); +block->host = NULL; +} else { +qemu_map_cache_unlock(addr); +} +} +} + int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr) { RAMBlock *block; @@ -3808,6 +3829,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, cpu_physical_memory_set_dirty_flags( addr1, (0xff & ~CODE_DIRTY_FLAG)); } +qemu_put_ram_ptr(ptr); } } else { if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && @@ -3835,9 +3857,9 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, } } else { /* RAM case */ -ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + -(addr & ~TARGET_PAGE_MASK); -memcpy(buf, ptr, l); +ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK); +memcpy(buf, ptr + (addr & ~TARGET_PAGE_MASK), l); +qemu_put_ram_ptr(ptr); } } len -= l; @@ -3878,6 +3900,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, /* ROM/RAM case */ ptr = qemu_get_ram_ptr(addr1); memcpy(ptr, buf, l); +qemu_put_ram_ptr(ptr); } len -= l; buf += l; @@ -4019,6 +4042,15 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, access_len -= l; } } +if (xen_mapcache_enabled()) { +uint8_t *buffer1 = buffer; +uint8_t *end_buffer = buffer + len; + +while (buffer1 < end_buffer) { +qemu_put_ram_ptr(buffer1); +buffer1 += TARGET_PAGE_SIZE; +} +} return; } if (is_write) { diff --git a/trace-events b/trace-events index 27e5134..454ba89 100644 --- a/trace-events +++ b/trace-events @@ -370,3 +370,6 @@ disable qemu_remap_bucket(uint64_t index) "index %#"PRIx64"" disable qemu_map_cache_return(void* ptr) "%p" disable xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64"" disable xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx" + +# exec.c +disable qemu_put_ram_ptr(void* addr) "%p" diff --git a/xen-mapcache.c b/xen-mapcache.c index 2ca18ce..349cc62 100644 --- a/xen-mapcache.c +++ b/xen-mapcache.c @@ -196,6 +196,39 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u return mapcache->last_address_vaddr + address_offset; } +void qemu_map_cache_unlock(void *buffer) +{ +MapCacheEntry *entry = NULL, *pentry = NULL; +MapCacheRev *reventry; +target_phys_addr_t paddr_index; +int found = 0; + +QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) { +if (reventry->vaddr_req == buffer) { +paddr_index = reventry->paddr_index; +found = 1; +break; +} +} +if (!found) { +return; +} +QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next); +qemu_free(reventry); + +entry = &mapcache->entry[paddr_index % mapcache->nr_buckets]; +while (entry && entry->paddr_index != paddr_index) { +pentry = entry; +entry = entry->next; +} +if (!entry) { +return; +} +if (entry->lock > 0) { +entry->lock--; +} +} + ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
[Qemu-devel] [PATCH V13 16/17] xen: Set running state in xenstore.
From: Anthony PERARD This tells to the xen management tool that the machine can begin run. Signed-off-by: Anthony PERARD Acked-by: Alexander Graf --- xen-all.c | 23 +++ 1 files changed, 23 insertions(+), 0 deletions(-) diff --git a/xen-all.c b/xen-all.c index e849a38..19c2fe1 100644 --- a/xen-all.c +++ b/xen-all.c @@ -64,6 +64,8 @@ typedef struct XenIOState { /* which vcpu we are serving */ int send_vcpu; +struct xs_handle *xenstore; + Notifier exit; } XenIOState; @@ -450,6 +452,17 @@ static void cpu_handle_ioreq(void *opaque) } } +static void xenstore_record_dm_state(XenIOState *s, const char *state) +{ +char path[50]; + +snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", xen_domid); +if (!xs_write(s->xenstore, XBT_NULL, path, state, strlen(state))) { +fprintf(stderr, "error recording dm state\n"); +exit(1); +} +} + static void xen_main_loop_prepare(XenIOState *state) { int evtchn_fd = -1; @@ -465,6 +478,9 @@ static void xen_main_loop_prepare(XenIOState *state) if (evtchn_fd != -1) { qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state); } + +/* record state running */ +xenstore_record_dm_state(state, "running"); } @@ -483,6 +499,7 @@ static void xen_exit_notifier(Notifier *n) XenIOState *state = container_of(n, XenIOState, exit); xc_evtchn_close(state->xce_handle); +xs_daemon_close(state->xenstore); } int xen_init(void) @@ -510,6 +527,12 @@ int xen_hvm_init(void) return -errno; } +state->xenstore = xs_daemon_open(); +if (state->xenstore == NULL) { +perror("xen: xenstore open"); +return -errno; +} + state->exit.notify = xen_exit_notifier; qemu_add_exit_notifier(&state->exit); -- 1.7.2.3
[Qemu-devel] [PATCH V13 12/17] configure: Always use 64bits target physical addresses with xen enabled.
From: Anthony PERARD With MapCache, we can handle a 64b target, even with a 32b host/qemu. So, we need to have target_phys_addr_t to 64bits. Signed-off-by: Anthony PERARD Acked-by: Alexander Graf --- configure |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 340a810..ef8c488 100755 --- a/configure +++ b/configure @@ -3282,6 +3282,7 @@ echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak case "$target_arch2" in i386|x86_64) if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then + target_phys_bits=64 echo "CONFIG_XEN=y" >> $config_target_mak if test "$cpu" = "i386" -o "$cpu" = "x86_64"; then echo "CONFIG_XEN_MAPCACHE=y" >> $config_target_mak -- 1.7.2.3
[Qemu-devel] [PATCH V13 14/17] vl.c: Introduce getter for shutdown_requested and reset_requested.
From: Anthony PERARD Introduce two functions qemu_shutdown_requested_get and qemu_reset_requested_get to get the value of shutdown/reset_requested without reset it. Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini Acked-by: Alexander Graf --- sysemu.h |2 ++ vl.c | 10 ++ 2 files changed, 12 insertions(+), 0 deletions(-) diff --git a/sysemu.h b/sysemu.h index bbbd0fd..3d4be78 100644 --- a/sysemu.h +++ b/sysemu.h @@ -63,6 +63,8 @@ void qemu_system_shutdown_request(void); void qemu_system_powerdown_request(void); void qemu_system_debug_request(void); void qemu_system_vmstop_request(int reason); +int qemu_shutdown_requested_get(void); +int qemu_reset_requested_get(void); int qemu_shutdown_requested(void); int qemu_reset_requested(void); int qemu_powerdown_requested(void); diff --git a/vl.c b/vl.c index b67068e..d02a09e 100644 --- a/vl.c +++ b/vl.c @@ -1161,6 +1161,16 @@ static int powerdown_requested; static int debug_requested; static int vmstop_requested; +int qemu_shutdown_requested_get(void) +{ +return shutdown_requested; +} + +int qemu_reset_requested_get(void) +{ +return reset_requested; +} + int qemu_shutdown_requested(void) { int r = shutdown_requested; -- 1.7.2.3
[Qemu-devel] [PATCH] atapi: Add 'medium ready' to 'medium not ready' transition on cd change
MMC-5 Table F.1 lists errors that can be thrown for the TEST_UNIT_READY command. Going from medium not ready to medium ready states is communicated by throwing an error. This adds the missing 'tray opened' event that we fail to report to guests. After doing this, older Linux guests properly revalidate a disc on the change command. HSM violation errors, which caused Linux guests to do a soft-reset of the link, also go away: ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 sr 1:0:0:0: CDB: Test Unit Ready: 00 00 00 00 00 00 ata2.00: cmd a0/00:00:00:00:00/00:00:00:00:00/a0 tag 0 res 01/60:00:00:00:00/00:00:00:00:00/a0 Emask 0x3 (HSM violation) ata2.00: status: { ERR } ata2: soft resetting link ata2.00: configured for MWDMA2 ata2: EH complete Signed-off-by: Amit Shah --- hw/ide/core.c | 20 1 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index f028ddb..d8c613a 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -1248,12 +1248,19 @@ static void ide_atapi_cmd(IDEState *s) ide_atapi_cmd_check_status(s); return; } +if (bdrv_is_inserted(s->bs) && s->cdrom_changed) { +ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + +s->cdrom_changed = 0; +s->sense_key = SENSE_UNIT_ATTENTION; +s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED; +return; +} switch(s->io_buffer[0]) { case GPCMD_TEST_UNIT_READY: -if (bdrv_is_inserted(s->bs) && !s->cdrom_changed) { +if (bdrv_is_inserted(s->bs)) { ide_atapi_cmd_ok(s); } else { -s->cdrom_changed = 0; ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); } @@ -1734,8 +1741,13 @@ static void cdrom_change_cb(void *opaque, int reason) bdrv_get_geometry(s->bs, &nb_sectors); s->nb_sectors = nb_sectors; -s->sense_key = SENSE_UNIT_ATTENTION; -s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED; +/* + * First indicate to the guest that a CD has been removed. That's + * done on the next command the guest sends us. + * + * Then we set SENSE_UNIT_ATTENTION, by which the guest will + * detect a new CD in the drive. See ide_atapi_cmd() for details. + */ s->cdrom_changed = 1; s->events.new_media = true; ide_set_irq(s->bus); -- 1.7.4.4
Re: [Qemu-devel] [PATCH] atapi: Add 'medium ready' to 'medium not ready' transition on cd change
On 04/18/11 13:45, Amit Shah wrote: > MMC-5 Table F.1 lists errors that can be thrown for the TEST_UNIT_READY > command. Going from medium not ready to medium ready states is > communicated by throwing an error. > > This adds the missing 'tray opened' event that we fail to report to > guests. After doing this, older Linux guests properly revalidate a disc > on the change command. HSM violation errors, which caused Linux guests > to do a soft-reset of the link, also go away: > > ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 > sr 1:0:0:0: CDB: Test Unit Ready: 00 00 00 00 00 00 > ata2.00: cmd a0/00:00:00:00:00/00:00:00:00:00/a0 tag 0 > res 01/60:00:00:00:00/00:00:00:00:00/a0 Emask 0x3 (HSM violation) > ata2.00: status: { ERR } > ata2: soft resetting link > ata2.00: configured for MWDMA2 > ata2: EH complete > > Signed-off-by: Amit Shah > --- > hw/ide/core.c | 20 > 1 files changed, 16 insertions(+), 4 deletions(-) Looks good to me. Acked-by: Jes Sorensen
Re: [Qemu-devel] [PATCH 02/17] s390x: s390x-linux-user support
On 18.04.2011, at 13:38, Riku Voipio wrote: > Hi, > > The patch looks OK, but I'd like to have a try with some s390x static > binaries. Such binaries are also useful for me to test that new patches > for linxu-user don't break targets I don't usually use. Sure - what exactly would you like there? I can easily compile a few. Do you want to have them added to the tests/ directory? Alex
Re: [Qemu-devel] [PATCH V13 05/17] pc_memory_init: Move memory calculation to the caller.
On 2011-04-18 13:37, anthony.per...@citrix.com wrote: > From: Anthony PERARD > > This patch moves above_4g_mem_size and below_4g_mem_size calculation in > the caller of pc_memory_init (pc_init1). And the prototype of > pc_memory_init is changed because there is no need anymore to have > variable pointer. > > Signed-off-by: Anthony PERARD > --- > hw/pc.c | 14 ++ > hw/pc.h |4 ++-- > hw/pc_piix.c | 11 +-- > 3 files changed, 13 insertions(+), 16 deletions(-) > > diff --git a/hw/pc.c b/hw/pc.c > index 6939c04..18b96cc 100644 > --- a/hw/pc.c > +++ b/hw/pc.c > @@ -961,25 +961,15 @@ void pc_memory_init(ram_addr_t ram_size, > const char *kernel_filename, > const char *kernel_cmdline, > const char *initrd_filename, > -ram_addr_t *below_4g_mem_size_p, > -ram_addr_t *above_4g_mem_size_p) > +ram_addr_t below_4g_mem_size, > +ram_addr_t above_4g_mem_size) > { > char *filename; > int ret, linux_boot, i; > ram_addr_t ram_addr, bios_offset, option_rom_offset; > -ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; > int bios_size, isa_bios_size; > void *fw_cfg; > > -if (ram_size >= 0xe000 ) { > -above_4g_mem_size = ram_size - 0xe000; > -below_4g_mem_size = 0xe000; > -} else { > -below_4g_mem_size = ram_size; > -} > -*above_4g_mem_size_p = above_4g_mem_size; > -*below_4g_mem_size_p = below_4g_mem_size; > - This obsoletes the ram_size parameter. Please drop it. > linux_boot = (kernel_filename != NULL); > > /* allocate RAM */ > diff --git a/hw/pc.h b/hw/pc.h > index feb8a7a..35bb890 100644 > --- a/hw/pc.h > +++ b/hw/pc.h > @@ -133,8 +133,8 @@ void pc_memory_init(ram_addr_t ram_size, > const char *kernel_filename, > const char *kernel_cmdline, > const char *initrd_filename, > -ram_addr_t *below_4g_mem_size_p, > -ram_addr_t *above_4g_mem_size_p); > +ram_addr_t below_4g_mem_size, > +ram_addr_t above_4g_mem_size); > qemu_irq *pc_allocate_cpu_irq(void); > void pc_vga_init(PCIBus *pci_bus); > void pc_basic_device_init(qemu_irq *isa_irq, > diff --git a/hw/pc_piix.c b/hw/pc_piix.c > index a85214b..e487c38 100644 > --- a/hw/pc_piix.c > +++ b/hw/pc_piix.c > @@ -72,7 +72,7 @@ static void pc_init1(ram_addr_t ram_size, > int kvmclock_enabled) > { > int i; > -ram_addr_t below_4g_mem_size, above_4g_mem_size; > +ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; > PCIBus *pci_bus; > PCII440FXState *i440fx_state; > int piix3_devfn = -1; > @@ -92,9 +92,16 @@ static void pc_init1(ram_addr_t ram_size, > kvmclock_create(); > } > > +if (ram_size >= 0xe000 ) { > +above_4g_mem_size = ram_size - 0xe000; > +below_4g_mem_size = 0xe000; > +} else { > +below_4g_mem_size = ram_size; Let's initialize above_4g_mem_size here. > +} > + > /* allocate ram and load rom/bios */ > pc_memory_init(ram_size, kernel_filename, kernel_cmdline, > initrd_filename, > - &below_4g_mem_size, &above_4g_mem_size); > + below_4g_mem_size, above_4g_mem_size); > > cpu_irq = pc_allocate_cpu_irq(); > i8259 = i8259_init(cpu_irq[0]); Looks good otherwise. Thanks, Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 02/17] s390x: s390x-linux-user support
On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > > The patch looks OK, but I'd like to have a try with some s390x static > > binaries. Such binaries are also useful for me to test that new patches > > for linxu-user don't break targets I don't usually use. > > Sure - what exactly would you like there? I can easily compile a few. Do you > want to have them added to the tests/ directory? busybox has so far been most useful. Riku
Re: [Qemu-devel] Question about total_sectors in block/vpc.c
Am 15.04.2011 22:40, schrieb Lyu Mitnick: > Hello Kevin, > > 2011/4/14 Kevin Wolf mailto:kw...@redhat.com>> > > Am 13.04.2011 22:59, schrieb Lyu Mitnick: > > Hello Stefan, > > > > I have a question about get_option_parameter(). I am wondering whether > > get_option_parameter is suitable to use instead of doing the > search by > > myself > > in the case like following: > > > > /* Read out options */ > > while (options && options->name) { > > if (!strcmp(options->name, BLOCK_OPT_SIZE)) { > > // do something > > } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) { > >// do something > > } > > options++; > > } > > Yes, I think it is, though you need to check whether the option has been > set in order to allow use default values. > > Kevin > > > I have no idea about the mean of "check whether the option has been set in > order to allow use default values" , would you mind to give me an > example about > it?? > > So as the example above. I am wondering whether the code should be > rewritten > as: > > /* Read out options */ > if(get_option_parameter(options, BLOCK_OPT_SIZE)) { > // do something > } > > if (get_option_parameter(options, BLOCK_OPT_CLUSTER_SIZE)) { > // do something > } get_option_parameter would never return NULL in your example. Kevin
Re: [Qemu-devel] [PATCH] atapi: Add 'medium ready' to 'medium not ready' transition on cd change
Am 18.04.2011 13:45, schrieb Amit Shah: > MMC-5 Table F.1 lists errors that can be thrown for the TEST_UNIT_READY > command. Going from medium not ready to medium ready states is > communicated by throwing an error. > > This adds the missing 'tray opened' event that we fail to report to > guests. After doing this, older Linux guests properly revalidate a disc > on the change command. HSM violation errors, which caused Linux guests > to do a soft-reset of the link, also go away: > > ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 > sr 1:0:0:0: CDB: Test Unit Ready: 00 00 00 00 00 00 > ata2.00: cmd a0/00:00:00:00:00/00:00:00:00:00/a0 tag 0 > res 01/60:00:00:00:00/00:00:00:00:00/a0 Emask 0x3 (HSM violation) > ata2.00: status: { ERR } > ata2: soft resetting link > ata2.00: configured for MWDMA2 > ata2: EH complete > > Signed-off-by: Amit Shah Thanks, applied to the block branch. Besides the tests that you did, Win 7 seems to work well with it, too, and I almost like the patch, so it's probably the best that we can get for now. Kevin
Re: [Qemu-devel] [PATCH 02/17] s390x: s390x-linux-user support
Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: > On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > > > The patch looks OK, but I'd like to have a try with some s390x static > > > binaries. Such binaries are also useful for me to test that new patches > > > for linxu-user don't break targets I don't usually use. > > > > Sure - what exactly would you like there? I can easily compile a few. Do > > you want to have them added to the tests/ directory? > > busybox has so far been most useful. > Good idea, what about adding a collection of static busybox for the different arches? Not everyone testing has the compiler around for $ARCH . Best, Jan-Simon
Re: [Qemu-devel] [PATCH] atapi: Add 'medium ready' to 'medium not ready' transition on cd change
Amit Shah writes: > MMC-5 Table F.1 lists errors that can be thrown for the TEST_UNIT_READY > command. Going from medium not ready to medium ready states is > communicated by throwing an error. > > This adds the missing 'tray opened' event that we fail to report to > guests. After doing this, older Linux guests properly revalidate a disc > on the change command. HSM violation errors, which caused Linux guests > to do a soft-reset of the link, also go away: > > ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 > sr 1:0:0:0: CDB: Test Unit Ready: 00 00 00 00 00 00 > ata2.00: cmd a0/00:00:00:00:00/00:00:00:00:00/a0 tag 0 > res 01/60:00:00:00:00/00:00:00:00:00/a0 Emask 0x3 (HSM violation) > ata2.00: status: { ERR } > ata2: soft resetting link > ata2.00: configured for MWDMA2 > ata2: EH complete > > Signed-off-by: Amit Shah Linux is happy with it in my tests. Tested-by: Markus Armbruster
Re: [Qemu-devel] [PATCH 02/17] s390x: s390x-linux-user support
On 18.04.2011, at 15:21, Jan-Simon Möller wrote: > Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: >> On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: The patch looks OK, but I'd like to have a try with some s390x static binaries. Such binaries are also useful for me to test that new patches for linxu-user don't break targets I don't usually use. >>> >>> Sure - what exactly would you like there? I can easily compile a few. Do >>> you want to have them added to the tests/ directory? >> >> busybox has so far been most useful. >> > > Good idea, what about adding a collection of static busybox for the different > arches? Not everyone testing has the compiler around for $ARCH . It'd probably make more sense to help the busybox guys to build an s390 version automatically. The others are already available: http://www.busybox.net/downloads/binaries/latest/ Alex
Re: [Qemu-devel] [PATCH 02/17] s390x: s390x-linux-user support
On Mon, Apr 18, 2011 at 03:21:54PM +0200, Jan-Simon Möller wrote: > Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: > > On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > > > > The patch looks OK, but I'd like to have a try with some s390x static > > > > binaries. Such binaries are also useful for me to test that new patches > > > > for linxu-user don't break targets I don't usually use. > > > > > > Sure - what exactly would you like there? I can easily compile a few. Do > > > you want to have them added to the tests/ directory? > > > > busybox has so far been most useful. > > > > Good idea, what about adding a collection of static busybox for the different > arches? Not everyone testing has the compiler around for $ARCH . > It's something that already exists [1]. It would actually make sense to add s390x binaries there. Also it might be a good idea to provide a minimal system image as on other architectures. [1] http://wiki.qemu.org/Download -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH 02/17] s390x: s390x-linux-user support
On 18.04.2011, at 15:36, Aurelien Jarno wrote: > On Mon, Apr 18, 2011 at 03:21:54PM +0200, Jan-Simon Möller wrote: >> Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: >>> On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > The patch looks OK, but I'd like to have a try with some s390x static > binaries. Such binaries are also useful for me to test that new patches > for linxu-user don't break targets I don't usually use. Sure - what exactly would you like there? I can easily compile a few. Do you want to have them added to the tests/ directory? >>> >>> busybox has so far been most useful. >>> >> >> Good idea, what about adding a collection of static busybox for the >> different >> arches? Not everyone testing has the compiler around for $ARCH . >> > > It's something that already exists [1]. It would actually make sense to > add s390x binaries there. Also it might be a good idea to provide a > minimal system image as on other architectures. > > [1] http://wiki.qemu.org/Download I find the minimal systems rather useless, but love your Debian images. So if you could create one of those for s390, that'd be awesome! :) Alex
Re: [Qemu-devel] [PATCH 24/26] acpi, acpi_piix: factor out GPE logic
On Mon, Apr 18, 2011 at 11:22:40AM +0300, Avi Kivity wrote: > Are you using qemu-kvm.git or qemu.git? I think there are indeed two > issues, your patch fixes the first and there is another that is specific > to qemu-kvm. I'm using qemu.git. I've start to have a look at qemu-kvm.git, -- yamahata
Re: [Qemu-devel] [PATCH 02/17] s390x: s390x-linux-user support
On Mon, Apr 18, 2011 at 03:42:25PM +0200, Alexander Graf wrote: > > On 18.04.2011, at 15:36, Aurelien Jarno wrote: > > > On Mon, Apr 18, 2011 at 03:21:54PM +0200, Jan-Simon Möller wrote: > >> Am Montag, 18. April 2011, 14:19:26 schrieb Riku Voipio: > >>> On Mon, Apr 18, 2011 at 02:06:02PM +0200, Alexander Graf wrote: > > The patch looks OK, but I'd like to have a try with some s390x static > > binaries. Such binaries are also useful for me to test that new patches > > for linxu-user don't break targets I don't usually use. > > Sure - what exactly would you like there? I can easily compile a few. Do > you want to have them added to the tests/ directory? > >>> > >>> busybox has so far been most useful. > >>> > >> > >> Good idea, what about adding a collection of static busybox for the > >> different > >> arches? Not everyone testing has the compiler around for $ARCH . > >> > > > > It's something that already exists [1]. It would actually make sense to > > add s390x binaries there. Also it might be a good idea to provide a > > minimal system image as on other architectures. > > > > [1] http://wiki.qemu.org/Download > > I find the minimal systems rather useless, but love your Debian images. So if > you could create one of those for s390, that'd be awesome! :) > Once I get qemu-system-s390x fully working, it looks my scripts to produce images should work with minor changes for s390. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
[Qemu-devel] [PATCH] acpi_piix4: fix save/load of PIIX4PMState
It's vmstate parameter was wrong. This patch fixes it. Reported-by: Avi Kivity Signed-off-by: Isaku Yamahata --- hw/acpi_piix4.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 96f5222..3a8fece 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -214,10 +214,9 @@ static int vmstate_acpi_post_load(void *opaque, int version_id) { \ .name = (stringify(_field)), \ .version_id = 0,\ - .num= GPE_LEN, \ .info = &vmstate_info_uint16, \ .size = sizeof(uint16_t), \ - .flags = VMS_ARRAY | VMS_POINTER, \ + .flags = VMS_SINGLE | VMS_POINTER, \ .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ } -- 1.7.1.1
Re: [Qemu-devel] [PATCH 1/3] slirp: Implement TFTP Blocksize option
On Mon, Apr 11, 2011 at 07:10:52PM +, Herve Poussineau wrote: > From: Herv? Poussineau > > This option is described in RFC 1783. As this is only an optional field, > we may ignore it in some situations and handle it in some others. > Here, if client requests a block size bigger than the block size we emit > (512 bytes), accept the option with a value of 512 > > Signed-off-by: Herv? Poussineau > --- > slirp/tftp.c | 40 > 1 files changed, 32 insertions(+), 8 deletions(-) The code looks fine except a small indentation issue below. However I don't really see the point of such a patch. This patch basically look for this option, but beside acking it, the behavior doesn't change. On the other hand servers are free to not support all the possible option, in which case they should simply ignore them (i.e. the current behavior). > diff --git a/slirp/tftp.c b/slirp/tftp.c > index 8055ccc..7ef44c9 100644 > --- a/slirp/tftp.c > +++ b/slirp/tftp.c > @@ -116,13 +116,13 @@ static int tftp_read_data(struct tftp_session *spt, > uint16_t block_nr, > } > > static int tftp_send_oack(struct tftp_session *spt, > - const char *key, uint32_t value, > + const char *key[], uint32_t value[], int nb, >struct tftp_t *recv_tp) > { > struct sockaddr_in saddr, daddr; > struct mbuf *m; > struct tftp_t *tp; > -int n = 0; > +int i, n = 0; > > m = m_get(spt->slirp); > > @@ -136,10 +136,12 @@ static int tftp_send_oack(struct tftp_session *spt, > m->m_data += sizeof(struct udpiphdr); > > tp->tp_op = htons(TFTP_OACK); > -n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s", > - key) + 1; > -n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u", > - value) + 1; > +for (i = 0; i < nb; i++) { > + n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s", > +key[i]) + 1; > + n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u", > +value[i]) + 1; > +} > > saddr.sin_addr = recv_tp->ip.ip_dst; > saddr.sin_port = recv_tp->udp.uh_dport; > @@ -260,6 +262,9 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t > *tp, int pktlen) >int s, k; >size_t prefix_len; >char *req_fname; > + const char *option_name[2]; > + uint32_t option_value[2]; > + int nb_options = 0; > >/* check if a session already exists and if so terminate it */ >s = tftp_session_find(slirp, tp); > @@ -364,9 +369,28 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t > *tp, int pktlen) > } > } > > - tftp_send_oack(spt, "tsize", tsize, tp); > - return; > + option_name[nb_options] = "tsize"; > + option_value[nb_options] = tsize; > + nb_options++; >} > +if (strcasecmp(key, "blksize") == 0) { > + int blksize = atoi(value); > + > + /* If blksize option is bigger than what we will > + * emit, accept the option with our packet size. > + * Otherwise, simply do as we didn't see the option. > + */ > + if (blksize >= 512) { > +option_name[nb_options] = "blksize"; > +option_value[nb_options] = 512; > +nb_options++; > + } > +} > + } > + I known slirp/tftp.c has weird indentation, but you should probably try to match the indentation from "tsize" for this black, that is 4 space like in QEMU, except for the initial indentation. > + if (nb_options > 0) { > +tftp_send_oack(spt, option_name, option_value, nb_options, tp); > +return; >} > >tftp_send_data(spt, 1, tp); > -- > 1.6.0.2.GIT > > > -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH 2/3] slirp: Handle more than 65535 blocks in TFTP transfers
On Mon, Apr 11, 2011 at 07:10:53PM +, Herve Poussineau wrote: > From: Herv? Poussineau > > RFC 1350 does not mention block count-roll over. However, a lot of TFTP > servers > implement it to be able to transmit big files, so do it also > > Signed-off-by: Herv? Poussineau > --- > slirp/tftp.c |9 + > slirp/tftp.h |1 + > 2 files changed, 6 insertions(+), 4 deletions(-) Reviewed-by: Aurelien Jarno > diff --git a/slirp/tftp.c b/slirp/tftp.c > index 7ef44c9..7e63269 100644 > --- a/slirp/tftp.c > +++ b/slirp/tftp.c > @@ -92,7 +92,7 @@ static int tftp_session_find(Slirp *slirp, struct tftp_t > *tp) >return -1; > } > > -static int tftp_read_data(struct tftp_session *spt, uint16_t block_nr, > +static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr, >uint8_t *buf, int len) > { >int fd; > @@ -196,7 +196,7 @@ out: > } > > static int tftp_send_data(struct tftp_session *spt, > - uint16_t block_nr, > + uint32_t block_nr, > struct tftp_t *recv_tp) > { >struct sockaddr_in saddr, daddr; > @@ -221,7 +221,7 @@ static int tftp_send_data(struct tftp_session *spt, >m->m_data += sizeof(struct udpiphdr); > >tp->tp_op = htons(TFTP_DATA); > - tp->x.tp_data.tp_block_nr = htons(block_nr); > + tp->x.tp_data.tp_block_nr = htons(block_nr & 0x); > >saddr.sin_addr = recv_tp->ip.ip_dst; >saddr.sin_port = recv_tp->udp.uh_dport; > @@ -253,6 +253,7 @@ static int tftp_send_data(struct tftp_session *spt, > tftp_session_terminate(spt); >} > > + spt->block_nr = block_nr; >return 0; > } > > @@ -407,7 +408,7 @@ static void tftp_handle_ack(Slirp *slirp, struct tftp_t > *tp, int pktlen) >} > >if (tftp_send_data(&slirp->tftp_sessions[s], > - ntohs(tp->x.tp_data.tp_block_nr) + 1, > + slirp->tftp_sessions[s].block_nr + 1, >tp) < 0) { > return; >} > diff --git a/slirp/tftp.h b/slirp/tftp.h > index 72e5e91..471f22e 100644 > --- a/slirp/tftp.h > +++ b/slirp/tftp.h > @@ -36,6 +36,7 @@ struct tftp_session { > > struct in_addr client_ip; > uint16_t client_port; > +uint32_t block_nr; > > int timestamp; > }; > -- > 1.6.0.2.GIT > > > -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH 3/3] slirp: improve TFTP performance
On Mon, Apr 11, 2011 at 07:10:54PM +, Herve Poussineau wrote: > From: Herv? Poussineau > > When transfering a file, keep it open during the whole transfer, > instead of opening/closing it for each block. > > Signed-off-by: Herv? Poussineau > --- > slirp/tftp.c | 20 > slirp/tftp.h |1 + > 2 files changed, 13 insertions(+), 8 deletions(-) > > diff --git a/slirp/tftp.c b/slirp/tftp.c > index 7e63269..48748f1 100644 > --- a/slirp/tftp.c > +++ b/slirp/tftp.c > @@ -37,6 +37,10 @@ static inline void tftp_session_update(struct tftp_session > *spt) > > static void tftp_session_terminate(struct tftp_session *spt) > { > +if (spt->fd >= 0) { > +close(spt->fd); > +spt->fd = -1; > +} > qemu_free(spt->filename); > spt->slirp = NULL; > } > @@ -54,7 +58,7 @@ static int tftp_session_allocate(Slirp *slirp, struct > tftp_t *tp) > > /* sessions time out after 5 inactive seconds */ > if ((int)(curtime - spt->timestamp) > 5000) { > -qemu_free(spt->filename); > +tftp_session_terminate(spt); > goto found; > } >} > @@ -64,6 +68,7 @@ static int tftp_session_allocate(Slirp *slirp, struct > tftp_t *tp) > found: >memset(spt, 0, sizeof(*spt)); >memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip)); > + spt->fd = -1; >spt->client_port = tp->udp.uh_sport; >spt->slirp = slirp; > > @@ -95,23 +100,22 @@ static int tftp_session_find(Slirp *slirp, struct tftp_t > *tp) > static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr, >uint8_t *buf, int len) > { > - int fd; >int bytes_read = 0; > > - fd = open(spt->filename, O_RDONLY | O_BINARY); > + if (spt->fd < 0) { > +spt->fd = open(spt->filename, O_RDONLY | O_BINARY); > + } > > - if (fd < 0) { > + if (spt->fd < 0) { > return -1; >} > >if (len) { > -lseek(fd, block_nr * 512, SEEK_SET); > +lseek(spt->fd, block_nr * 512, SEEK_SET); > > -bytes_read = read(fd, buf, len); > +bytes_read = read(spt->fd, buf, len); >} > > - close(fd); > - >return bytes_read; > } Given you are rewriting this most of this function, it's probably the good moment to also fix the indentation to 4 spaces. > diff --git a/slirp/tftp.h b/slirp/tftp.h > index 471f22e..51704e4 100644 > --- a/slirp/tftp.h > +++ b/slirp/tftp.h > @@ -33,6 +33,7 @@ struct tftp_t { > struct tftp_session { > Slirp *slirp; > char *filename; > +int fd; > > struct in_addr client_ip; > uint16_t client_port; > -- > 1.6.0.2.GIT > Except the minor nit above: Reviewed-by: Aurelien Jarno -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [RFC PATCH] implement vmware pvscsi device
On 04/15/2011 10:56 PM, Paolo Bonzini wrote: On 04/15/2011 05:04 PM, Stefan Hajnoczi wrote: The way I approached virtio-scsi was to look at the SCSI Architecture Model document and some of the Linux SCSI code. I'm not sure if letting virtio-blk SCSI pass-through or scsi-generic guide us is a good approach. How do your ioprio and barrier relate to SCSI? Both are part of the transport protocol, which can provide additional features with respect to SAM. For example SCSI doesn't provide the full details of hotplug/hotunplug, or doesn't have a way for the guest to trigger a drive unplug on the host, but these are all desirable features for virtio-scsi (and they are supported by vmw_pvscsi by the way). And this is something I really miss in the current proposals, namely a working transport layer. The SCSI spec (SPC etc) itself just handles command delivery between initiator and target. Anything else (like hotplug, error recovery, target addressing etc) is out of the scope of the spec and needs to be implemented on another layer (that's the ominous transport layer). Hence any protocol implemented to the above spec would be missing those parts, and they would need to be implemented additionally. Which also explains why these features are missing when just using SCSI CDBs as the main command container. My proposal would be to implement a full virtio-scsi _host_, and extend the proposal to be able to handle the transport layer too. At the lastest we would need to include a LUN address before the CDB, and define TMF command values for proper error recovery. That way we could handle hotplug / -unplug via a simple host rescan, and would even be able to pass-in NPIV hosts. There seem to be recent/exotic commands that can have both data-in and data-out buffers. These are bi-directional commands which are required for OSD. That can fit by adding more stuff at the end of the buffer. It can be in the first version, or it can be an extra feature for later. Since QEMU currently cannot handle it, probably it would need negotiation even if it were in the first version. The sense buffer length is also not necessarily 96 bytes max, I believe. I couldn't find that in either SPC or SAM indeed. It seems like a pretty widespread assumption though. Perhaps Nicholas or Hannes know where it comes from. 96 bytes is a carry-over from scsi parallel. We shouldn't rely on a fixed length here but rather use an additional pointer/iovec and length field. Check SG_IO header on how it's done. Cheers, Hannes -- Dr. Hannes Reinecke zSeries & Storage h...@suse.de +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Markus Rex, HRB 16746 (AG Nürnberg)
[Qemu-devel] [PATCH v2 1/1] Add QMP bits for blockdev-snapshot-sync.
From: Jes Sorensen This is quivalent to snapshot_blkdev in the human monitor, with _sync added to the command name to make it explicit that the command is synchronous and leave space for a future async version. Signed-off-by: Jes Sorensen --- qmp-commands.hx | 26 ++ 1 files changed, 26 insertions(+), 0 deletions(-) diff --git a/qmp-commands.hx b/qmp-commands.hx index fbd98ee..b8f537c 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -667,6 +667,32 @@ Example: EQMP { +.name = "blockdev-snapshot-sync", +.args_type = "device:B,snapshot_file:s?,format:s?", +.params = "device [new-image-file] [format]", +.user_print = monitor_user_noop, +.mhandler.cmd_new = do_snapshot_blkdev, +}, + +SQMP +Synchronous snapshot of block device, using snapshot file as target +if provided. + +If a new image file is specified, the new image file will become the +new root image. If format is specified, the snapshot file will be +created in that format. Otherwise the snapshot will be internal! +(currently unsupported). + +Errors: +If creating the new snapshot image fails, QEMU will continue running +on the original image. If switching to the newly created image fails, +it will be attempted to fall back to the original image and return +QERR_OPEN_FILE_FAILED with the snapshot filename. If re-opening +the original image fails, QERR_OPEN_FILE_FAILED will be returned with +the original image filename. +EQMP + +{ .name = "balloon", .args_type = "value:M", .params = "target", -- 1.7.4.4
[Qemu-devel] [PATCH v2 0/1] Add QMP bits for blockdev-snapshot-sync.
From: Jes Sorensen This is an old patch I am resurrecting, adding a QMP command for live snapshot support. I have tried to address the comments received in the previous emails around March 9th. Please let me know if you have further issues with this. Jes Sorensen (1): Add QMP bits for blockdev-snapshot-sync. qmp-commands.hx | 26 ++ 1 files changed, 26 insertions(+), 0 deletions(-) -- 1.7.4.4
[Qemu-devel] [RFC][PATCH v2 00/11] QEMU Guest Agent: QMP-based host/guest communication (virtagent)
These apply on top of Anthony's glib tree, commit 03d5927deb5e6baebaade1b4c8ff2428a85e125c currently, and can also be obtained from: git://repo.or.cz/qemu/mdroth.git qga_v2 Patches 1-8 are general json/QAPI-related fixes. Anthony, please consider pulling these into your glib tree. The json fix-ups may need further evaluation, but I'm confident they're at least an improvement. The QAPI ones are mostly trivial fix-ups. Changes since V1: - Added guest agent worker thread to execute RPCs in the guest. With this in place we have a reliable timeout mechanism for hung commands, currently set at 30 seconds. - Add framework for registering init/cleanup routines for stateful RPCs to clean up after themselves after a timeout. - Added the following RPCs: guest-file-{open,close,read,write,seek}, guest-shutdown, guest-info, and removed stubs for guest-view-file (now deprecated) - Added GUEST_AGENT_UP/GUEST_AGENT_DOWN QMP events - Switched to a TCP-style host-initiated 3-way handshake for channel negotiation, this simplifies client negotiation/interaction over the wire - Added configurable log level/log file/pid file options for guest agent - Various fixes for bugs/memory leaks and checkpatch.pl fixups ISSUES/TODOS: - Fix QMP proxy handling of error responses sent by guest agent, currently ignored - Add unit tests for guest agent wire protocol - Add unit tests for QMP interfaces - Add host-side timeout mechanism for async QMP commands - Return error for guest commands if guest up event has not yet been recieved - Make QMP param names more consistent between related commands - Clean up logging OVERVIEW For a better overview of what these patches are meant to accomplish, please reference the RFC for virtagent: http://comments.gmane.org/gmane.comp.emulators.qemu/96096 These patches integrate the previous virtagent guest agent work directly in QAPI/QMP to leverage it's auto-generated marshalling code. This has numerous benefits: - addresses previous concerns over relying on external libraries to handle data encapsulation - reduces the need for manual unmarshalling of requests/responses, which makes adding new RPCs much safer/less error-prone, as well as cutting down on redundant code - QAPI documentation aligns completely with guest-side RPC implementation - is Just Better (TM) BUILD/USAGE build: ./configure --target-list=x86_64-softmmu make make qemu-ga #should be built on|for target guest start guest: qemu \ -drive file=/home/mdroth/vm/rhel6_64_base.raw,snapshot=off,if=virtio \ -net nic,model=virtio,macaddr=52:54:00:12:34:00 \ -net tap,script=/etc/qemu-ifup \ -vnc :1 -m 1024 --enable-kvm \ -chardev socket,path=/tmp/mon-qmp.sock,server,nowait,id=mon-qmp \ -qmp mon-qmp \ -chardev qmp_proxy,id=qmp_proxy \ -device virtio-serial \ -device virtserialport,chardev=qmp_proxy,name=qcg" use guest agent: ./qemu-ga -h ./qemu-ga -c virtio-serial -p /dev/virtio-ports/qcg start/use qmp: mdroth@illuin:~$ sudo socat unix-connect:/tmp/mon-qmp.sock readline {"QMP": {"version": {"qemu": {"micro": 50, "minor": 13, "major": 0}, "package": ""}, "capabilities": []}} {"execute":"guest-info"} {"return": {}} {"execute": "guest-info"} {"return": {"version": "1.0", "timeout_ms": 3}} {"execute":"guest-file-open", "arguments":{"filename":"/tmp/testqga","mode":"w+"}} {"return": 0} {"execute":"guest-file-write", "arguments":{"filehandle":0,"data_b64":"aGVsbG8gd29ybGQhCg==","count":13}} // writes "hello world!\n" {"return": {"count": 13, "eof": false}} {"execute":"guest-file-open", "arguments":{"filename":"/tmp/testqga","mode":"r"}} {"return": 1} {"execute":"guest-file-read", "arguments":{"filehandle":1,"count":1024}} {"return": {"buf": "aGVsbG8gd29ybGQhCg==", "count": 13, "eof": true}} {"execute":"guest-file-close","arguments":{"filehandle":1}} {"return": {}} Makefile| 15 +- Makefile.objs |1 + configure |6 +- json-lexer.c| 33 ++- json-lexer.h|1 + json-parser.c |6 +- json-streamer.c | 35 ++- qapi-schema.json| 140 - qemu-char.c | 55 +++ qemu-ga.c | 711 +++ qemu-sockets.c |2 +- qga/guest-agent-command-state.c | 73 qga/guest-agent-commands.c | 284 qga/guest-agent-core.c | 139 qga/guest-agent-core.h | 40 +++ qga/guest-agent-worker.c| 173 ++ qmp-core.c | 13 +- qmp-core.h |7 +- qmp-gen.py | 15 +- qmp-proxy-core.h| 21 ++ qmp-proxy.c | 294 vl.c|1 + 22 files changed, 2023 insertions(+), 42 deletions(-)
[Qemu-devel] [RFC][PATCH v2 07/17] qapi: qmp-gen.py, use basename of path for guard/core prefix
To avoid errors when generating output to a seperate subdirectory, use only the filename, minus any leading directories, when passing it into functions to be used as a prefix for header guards, includes, etc. Also, trim file extensions based on "." seperator instead of assuming a single-char extension and trimming the last 2 chars Signed-off-by: Michael Roth --- qmp-gen.py |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qmp-gen.py b/qmp-gen.py index 3667ec5..eeef58c 100644 --- a/qmp-gen.py +++ b/qmp-gen.py @@ -2047,10 +2047,11 @@ def generate(kind, output): enum_types = [] event_types = {} indent_level = 0 +prefix = output.split("/")[-1].split(".")[0] -guard = '%s_H' % c_var(output[:-2]).upper() -core = '%s-core.h' % output[:-2] -header = '%s.h' % output[:-2] +guard = '%s_H' % c_var(prefix).upper() +core = '%s-core.h' % prefix +header = '%s.h' % prefix if kind.endswith('body') or kind.endswith('header'): ret = mcgen(''' @@ -2387,7 +2388,7 @@ void qcfg_options_init(void) return ret def main(args): -if len(args) != 2: +if len(args) < 2: return 1 if not args[0].startswith('--'): return 1 -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 09/17] qmp proxy: core code for proxying qmp requests to guest
This provides a QmpProxy class, 1 instance of which is shared by all QMP servers/sessions to send/receive QMP requests/responses between QEMU and the QEMU guest agent. A single qmp_proxy_send_request() is the only interface currently needed by a QMP session, QAPI/QMP's existing async support handles all the work of doing callbacks and routing responses to the proper session. Signed-off-by: Michael Roth --- qapi-schema.json |7 ++ qmp-core.c |8 ++ qmp-core.h |7 +- qmp-proxy-core.h | 21 qmp-proxy.c | 294 ++ vl.c |1 + 6 files changed, 332 insertions(+), 6 deletions(-) create mode 100644 qmp-proxy-core.h create mode 100644 qmp-proxy.c diff --git a/qapi-schema.json b/qapi-schema.json index de6c9a3..5292938 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1498,3 +1498,10 @@ # Since: 0.14.0 ## { 'option': 'vnc', 'data': 'VncConfig', 'implicit': 'address' } + +## 0.15.0 Events ## +{ 'event': 'GUEST_AGENT_UP' } +{ 'command': 'get-guest-agent-up-event', 'returns': 'GUEST_AGENT_UP' } + +{ 'event': 'GUEST_AGENT_RESET' } +{ 'command': 'get-guest-agent-reset-event', 'returns': 'GUEST_AGENT_RESET' } diff --git a/qmp-core.c b/qmp-core.c index 9f3d182..dab50a1 100644 --- a/qmp-core.c +++ b/qmp-core.c @@ -937,7 +937,15 @@ void qmp_async_complete_command(QmpCommandState *cmd, QObject *retval, Error *er qemu_free(cmd); } +extern QmpProxy *qmp_proxy_default; + void qmp_guest_dispatch(const char *name, const QDict *args, Error **errp, QmpGuestCompletionFunc *cb, void *opaque) { +if (!qmp_proxy_default) { +/* TODO: should set errp here */ +fprintf(stderr, "qmp proxy: no guest proxy found\n"); +return; +} +qmp_proxy_send_request(qmp_proxy_default, name, args, errp, cb, opaque); } diff --git a/qmp-core.h b/qmp-core.h index b676020..114d290 100644 --- a/qmp-core.h +++ b/qmp-core.h @@ -4,6 +4,7 @@ #include "monitor.h" #include "qmp-marshal-types.h" #include "error_int.h" +#include "qmp-proxy-core.h" struct QmpCommandState { @@ -85,11 +86,5 @@ int qmp_state_get_fd(QmpState *sess); }\ } while(0) -typedef void (QmpGuestCompletionFunc)(void *opaque, QObject *ret_data, Error *err); - -void qmp_guest_dispatch(const char *name, const QDict *args, Error **errp, -QmpGuestCompletionFunc *cb, void *opaque); - - #endif diff --git a/qmp-proxy-core.h b/qmp-proxy-core.h new file mode 100644 index 000..6afdc23 --- /dev/null +++ b/qmp-proxy-core.h @@ -0,0 +1,21 @@ +#ifndef QMP_PROXY_CORE_H +#define QMP_PROXY_CORE_H + +#define QMP_PROXY_PATH_DEFAULT "/tmp/qmp-proxy.sock" + +typedef void (QmpGuestCompletionFunc)(void *opaque, QObject *ret_data, + Error *err); + +void qmp_guest_dispatch(const char *name, const QDict *args, Error **errp, +QmpGuestCompletionFunc *cb, void *opaque); + +typedef struct QmpProxy QmpProxy; + +void qmp_proxy_send_request(QmpProxy *p, const char *name, +const QDict *args, Error **errp, +QmpGuestCompletionFunc *cb, void *opaque); +QmpProxy *qmp_proxy_new(CharDriverState *chr); +void qmp_proxy_close(QmpProxy *p); +int qmp_proxy_read(QmpProxy *p, const uint8_t *buf, int len); + +#endif diff --git a/qmp-proxy.c b/qmp-proxy.c new file mode 100644 index 000..a4c7eea --- /dev/null +++ b/qmp-proxy.c @@ -0,0 +1,294 @@ +/* + * QMP definitions for communicating with guest agent + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include +#include "qmp.h" +#include "qmp-core.h" +#include "qemu-queue.h" +#include "json-parser.h" +#include "json-streamer.h" +#include "qemu_socket.h" + +#define QMP_SENTINEL 0xFF + +typedef struct QmpProxyRequest { +const char *name; +const QDict *args; +QmpGuestCompletionFunc *cb; +void *opaque; +QString *json; +QTAILQ_ENTRY(QmpProxyRequest) entry; +} QmpProxyRequest; + +struct QmpProxy { +int session_id; +JSONMessageParser parser; +GString *tx; +QEMUTimer *tx_timer; +int tx_timer_interval; +QTAILQ_HEAD(, QmpProxyRequest) requests; +CharDriverState *chr; +}; + +static GuestAgentUpEvent guest_agent_up_event; +static GuestAgentResetEvent guest_agent_reset_event; +static void qmp_proxy_write(QmpProxy *p); + +GuestAgentUpEvent *qmp_get_guest_agent_up_event(Error **errp) +{ +return &guest_agent_up_event; +} + +GuestAgentResetEvent *qmp_get_guest_agent_reset_event(Error **errp) +{ +return &guest_agent_reset_event; +} + +static int qmp_proxy_cancel_request(QmpProxy *p, QmpProxyRequest *r) +{ +if (r && r->cb) { +r->cb(r->opaque, NULL, NULL); +} + +return
[Qemu-devel] [RFC][PATCH v2 08/17] qapi: fix Error usage in qemu-sockets.c
Fix spurious errors due to not initializing Error pointer to NULL before checking for errors. Signed-off-by: Michael Roth --- qemu-sockets.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qemu-sockets.c b/qemu-sockets.c index dc8beeb..e709e5f 100644 --- a/qemu-sockets.c +++ b/qemu-sockets.c @@ -630,7 +630,7 @@ int unix_connect(const char *path) { QemuOpts *opts; int sock; -Error *err; +Error *err = NULL; opts = qemu_opts_create(&dummy_opts, NULL, 0, &err); if (err) { -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 04/17] qapi: fix function name typo in qmp-gen.py
Signed-off-by: Michael Roth --- qmp-gen.py |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qmp-gen.py b/qmp-gen.py index 90069ca..4164692 100644 --- a/qmp-gen.py +++ b/qmp-gen.py @@ -2328,7 +2328,7 @@ void qga_init_marshal(void) if not s.has_key('command'): continue name = s['command'] -if qmp_is_proxy_command(name): +if qmp_is_proxy_cmd(name): ret += mcgen(''' qga_register_command("%(name)s", &qmp_marshal_%(c_name)s); ''', -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 06/17] qapi: fix memory leak for async marshalling code
When generating the callback function for an async command, if we expect a QString we copy it into a native char* type, then call the completion function. We should free it after calling the completion function, since the completion function will later copy it into a new QString before adding it to the response object and then passing it on to the wire. Signed-off-by: Michael Roth --- qmp-gen.py |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/qmp-gen.py b/qmp-gen.py index 4164692..3667ec5 100644 --- a/qmp-gen.py +++ b/qmp-gen.py @@ -349,6 +349,10 @@ static void qmp_%(c_name)s_cb(void *qmp__opaque, QObject *qmp__retval, Error *qm ret += cgen('qmp__cb->cb(qmp__cb->opaque, qmp__err);') else: ret += cgen('qmp__cb->cb(qmp__cb->opaque, qmp__native_retval, qmp__err);') +if retval != 'none' and qmp_type_should_free(retval): +ret += cgen('%(free)s(qmp__native_retval);', +free=qapi_free_func(retval)) + ret += cgen('}') return ret -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 16/17] guest agent: add guest agent RPCs/commands
This adds the initial set of QMP/QAPI commands provided by the guest agent: guest-ping guest-file-open guest-file-read guest-file-write guest-file-seek guest-file-close The input/output specification for these commands are documented in the schema. Signed-off-by: Michael Roth --- qapi-schema.json | 133 - qga/guest-agent-commands.c | 284 2 files changed, 415 insertions(+), 2 deletions(-) create mode 100644 qga/guest-agent-commands.c diff --git a/qapi-schema.json b/qapi-schema.json index 5292938..e2f209d 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1387,10 +1387,139 @@ { 'enum': 'VirtioNetTxStrategy', 'data': ['bh', 'timer'] } { 'type': 'GuestInfo', 'data': {'*name': 'str', '*pid': 'int'} } +## +# @guest-ping: +# +# Ping the guest agent, a non-error return implies success +# +# Since: 0.15.0 +## { 'command': 'guest-ping' } -{ 'command': 'guest-view-file', 'data': { 'filename': 'str' }, - 'returns': 'str' } +## +# @guest-info: +# +# Get some information about the guest agent. +# +# Since: 0.15.0 +## +{ 'type': 'GuestAgentInfo', 'data': {'version': 'str', 'timeout_ms': 'int'} } +{ 'command': 'guest-info', + 'returns': 'GuestAgentInfo' } + +## +# @guest-shutdown: +# +# Initiate guest-activated shutdown +# +# @shutdown_mode: "halt", "powerdown", or "reboot" +# +# Returns: Nothing on success +# +# Since: 0.15.0 +## +{ 'command': 'guest-shutdown', 'data': { 'shutdown_mode': 'str' } } + +## +# @guest-file-open: +# +# Open a file in the guest and retrieve a file handle for it +# +# @filename: Full path to the file in the guest to open. +# +# @mode: #optional open mode, as per fopen(), "r" is the default. +# +# Returns: Guest file handle on success. +# If @filename cannot be opened, OpenFileFailed +# +# Since: 0.15.0 +## +{ 'command': 'guest-file-open', + 'data':{ 'filename': 'str', 'mode': 'str' }, + 'returns': 'int' } + +## +# @guest-file-read: +# +# Read from an open file in the guest +# +# @filehandle: filehandle returned by guest-file-open +# +# @count: maximum number of bytes to read +# +# Returns: GuestFileRead on success. +# If @filehandle cannot be found, OpenFileFailed +# +# Since: 0.15.0 +## +{ 'type': 'GuestFileRead', + 'data': { 'count': 'int', 'buf': 'str', 'eof': 'bool' } } + +{ 'command': 'guest-file-read', + 'data':{ 'filehandle': 'int', 'count': 'int' }, + 'returns': 'GuestFileRead' } + +## +# @guest-file-write: +# +# Write to an open file in the guest +# +# @filehandle: filehandle returned by guest-file-open +# +# @data_b64: base64-encoded string representing data to be written +# +# @count: bytes to write (actual bytes, after b64-decode) +# +# Returns: GuestFileWrite on success. +# If @filehandle cannot be found, OpenFileFailed +# +# Since: 0.15.0 +## +{ 'type': 'GuestFileWrite', + 'data': { 'count': 'int', 'eof': 'bool' } } +{ 'command': 'guest-file-write', + 'data':{ 'filehandle': 'int', 'data_b64': 'str', 'count': 'int' }, + 'returns': 'GuestFileWrite' } + +## +# @guest-file-seek: +# +# Seek to a position in the file, as with fseek(), and return the +# current file position afterward. Also encapsulates ftell()'s +# functionality, just Set offset=0, whence=SEEK_CUR. +# +# @filehandle: filehandle returned by guest-file-open +# +# @offset: bytes to skip over in the file stream +# +# @whence: SEEK_SET, SEEK_CUR, or SEEK_END, as with fseek() +# +# Returns: GuestFileSeek on success. +# If @filename cannot be opened, OpenFileFailed +# +# Since: 0.15.0 +## +{ 'type': 'GuestFileSeek', + 'data': { 'position': 'int', 'eof': 'bool' } } + +{ 'command': 'guest-file-seek', + 'data':{ 'filehandle': 'int', 'offset': 'int', 'whence': 'int' }, + 'returns': 'GuestFileSeek' } + +## +# @guest-file-close: +# +# Close an open file in the guest +# +# @filehandle: filehandle returned by guest-file-open +# +# Returns: Nothing on success. +# If @filename cannot be opened, OpenFileFailed +# +# Since: 0.15.0 +## +{ 'command': 'guest-file-close', + 'data': { 'filehandle': 'int' } } { 'type': 'ProbeProtocol', 'data': { 'unsafe': 'bool', 'filename': 'str' } } diff --git a/qga/guest-agent-commands.c b/qga/guest-agent-commands.c new file mode 100644 index 000..843ef36 --- /dev/null +++ b/qga/guest-agent-commands.c @@ -0,0 +1,284 @@ +/* + * QEMU Guest Agent commands + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include +#include "guest-agent.h" + +static bool enable_syslog = true; +static GAState *ga_state; + +#define SLOG(msg, ...) do { \ +if (enable_syslog) { \ +g_log("syslog", G_LOG_LEVEL_INFO, msg, ## __VA_ARGS__); \ +} \ +} while(0) + +void qga_guest_ping(Error **err) +{ +SLOG("guest-ping called"); +} + +struct GuestAgentInfo *qga_guest_info(Error **
[Qemu-devel] [RFC][PATCH v2 12/17] guest agent: worker thread class
Signed-off-by: Michael Roth --- qga/guest-agent-worker.c | 173 ++ 1 files changed, 173 insertions(+), 0 deletions(-) create mode 100644 qga/guest-agent-worker.c diff --git a/qga/guest-agent-worker.c b/qga/guest-agent-worker.c new file mode 100644 index 000..e3295da --- /dev/null +++ b/qga/guest-agent-worker.c @@ -0,0 +1,173 @@ +/* + * QEMU Guest Agent worker thread interfaces + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include +#include +#include +#include +#include +#include +#include +#include "guest-agent.h" +#include "../error.h" + +struct GAWorker { +pthread_t thread; +ga_worker_func execute; +pthread_mutex_t input_mutex; +pthread_cond_t input_avail_cond; +void *input; +bool input_avail; +pthread_mutex_t output_mutex; +pthread_cond_t output_avail_cond; +void *output; +Error *output_error; +bool output_avail; +}; + +static void *worker_run(void *worker_p) +{ +GAWorker *worker = worker_p; +Error *err; +void *input, *output; + +while (1) { +/* wait for input */ +pthread_mutex_lock(&worker->input_mutex); +while (!worker->input_avail) { +pthread_cond_wait(&worker->input_avail_cond, &worker->input_mutex); +} +input = worker->input; +worker->input_avail = false; +pthread_mutex_unlock(&worker->input_mutex); + +/* process input. input points to shared data, so if we ever add + * asynchronous dispatch, we'll need to copy the input instead + */ +worker->execute(input, &output, &err); + +/* signal waiters */ +pthread_mutex_lock(&worker->output_mutex); +worker->output = output; +worker->output_error = err; +worker->output_avail = true; +pthread_cond_signal(&worker->output_avail_cond); +pthread_mutex_unlock(&worker->output_mutex); +} + +return NULL; +} + +static void ga_worker_set_input(GAWorker *worker, void *input) +{ +pthread_mutex_lock(&worker->input_mutex); + +/* provide input for thread, and signal it */ +worker->input = input; +worker->input_avail = true; +pthread_cond_signal(&worker->input_avail_cond); + +pthread_mutex_unlock(&worker->input_mutex); +} + +static bool ga_worker_get_output(GAWorker *worker, void **output, int timeout) +{ +struct timespec ts; +GTimeVal tv; +bool timed_out = false; +int ret; + +pthread_mutex_lock(&worker->output_mutex); + +while (!worker->output_avail) { +if (timeout > 0) { +g_get_current_time(&tv); +g_time_val_add(&tv, timeout * 1000); +ts.tv_sec = tv.tv_sec; +ts.tv_nsec = tv.tv_usec * 1000; +ret = pthread_cond_timedwait(&worker->output_avail_cond, + &worker->output_mutex, &ts); +if (ret == ETIMEDOUT) { +timed_out = true; +goto out; +} +} else { +ret = pthread_cond_wait(&worker->output_avail_cond, +&worker->output_mutex); +} +} + +/* handle output from thread */ +worker->output_avail = false; +*output = worker->output; + +out: +pthread_mutex_unlock(&worker->output_mutex); +return timed_out; +} + +bool ga_worker_dispatch(GAWorker *worker, void *input, void *output, +int timeout, Error **errp) +{ +ga_worker_set_input(worker, input); +return ga_worker_get_output(worker, output, timeout); +} + +static void ga_worker_start(GAWorker *worker) +{ +int ret; + +pthread_cond_init(&worker->input_avail_cond, NULL); +pthread_cond_init(&worker->output_avail_cond, NULL); +pthread_mutex_init(&worker->input_mutex, NULL); +pthread_mutex_init(&worker->output_mutex, NULL); +worker->output_avail = false; +worker->input_avail = false; + +ret = pthread_create(&worker->thread, NULL, worker_run, worker); +if (ret == -1) { +g_error("error: %s", strerror(errno)); +} +} + +static void ga_worker_stop(GAWorker *worker) +{ +int ret; +void *status; + +ret = pthread_cancel(worker->thread); +if (ret == -1) { +g_error("pthread_cancel() failed: %s", strerror(errno)); +} + +ret = pthread_join(worker->thread, &status); +if (ret == -1) { +g_error("pthread_join() failed: %s", strerror(errno)); +} +/* TODO: should *_destroy pthread data structures here */ +} + +GAWorker *ga_worker_new(ga_worker_func func) +{ +GAWorker *worker = g_malloc0(sizeof(GAWorker)); + +g_assert(func); +worker->execute = func; +ga_worker_start(worker); + +return worker; +} + +void ga_worker_cleanup(GAWorker *worker) +{ +ga_worker_stop(worker); +
[Qemu-devel] [RFC][PATCH v2 10/17] qmp proxy: add qmp_proxy chardev
This allows qemu to be started with guest agent support via: qemu -chardev qmp_proxy,id=qmp_proxy -device ...,chardev=qmp_proxy Writes to the guest agent are buffered, with deferred work handled by a timer. Writes from the guest agent to host/proxy are passed directly into a JSON streamer object/buffer. The chardev is intended for use with virtio-serial or isa-serial channels. Other uses may be possible with appropriate changes to guest agent. Signed-off-by: Michael Roth --- qemu-char.c | 55 +++ 1 files changed, 55 insertions(+), 0 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index d301925..27b1252 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2276,6 +2276,60 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) } /***/ +/* QMP host->guest proxy chardev */ +#include "qmp-proxy-core.h" +#include "json-streamer.h" + +extern QmpProxy *qmp_proxy_default; + +static int qmp_proxy_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ +QmpProxy *p = chr->opaque; + +qmp_proxy_read(p, buf, len); + +return len; +} + +static void qmp_proxy_chr_close(CharDriverState *chr) +{ +QmpProxy *p = chr->opaque; + +qmp_proxy_default = NULL; +qmp_proxy_close(p); +qemu_chr_event(chr, CHR_EVENT_CLOSED); +} + +static CharDriverState *qemu_chr_open_qmp_proxy(QemuOpts *opts) +{ +CharDriverState *chr = qemu_mallocz(sizeof(CharDriverState)); +QmpProxy *p; + +/* initialize the qmp guest proxy */ +if (qmp_proxy_default) { +fprintf(stderr, "error, multiple qmp guest proxies are not allowed\n"); +goto err; +} +p = qmp_proxy_default = qmp_proxy_new(chr); +if (p == NULL) { +fprintf(stderr, "error initializing qmp guest proxy\n"); +goto err; +} + +chr->opaque = p; +chr->chr_write = qmp_proxy_chr_write; +chr->chr_close = qmp_proxy_chr_close; +qemu_chr_generic_open(chr); + +return chr; +err: +if (chr) { +qemu_free(chr); +} +return NULL; +} + +/***/ /* Memory chardev */ typedef struct { size_t outbuf_size; @@ -2495,6 +2549,7 @@ static const struct { || defined(__FreeBSD_kernel__) { .name = "parport", .open = qemu_chr_open_pp }, #endif +{ .name = "qmp_proxy", .open = qemu_chr_open_qmp_proxy }, }; CharDriverState *qemu_chr_open_opts(QemuOpts *opts, -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 02/17] json-streamer: add handling for JSON_ERROR token/state
This allows a JSON_ERROR state to be passed to the streamer to force a flush of the current tokens and pass a NULL token list to the parser rather that have it churn on bad data. (Alternatively we could just not pass it to the parser at all, but it may be useful to push there errors up the stack. NULL token lists are not currently handled by the parser, the next patch will address that) Signed-off-by: Michael Roth --- json-streamer.c | 35 +++ 1 files changed, 23 insertions(+), 12 deletions(-) diff --git a/json-streamer.c b/json-streamer.c index a6cb28f..c255c78 100644 --- a/json-streamer.c +++ b/json-streamer.c @@ -56,29 +56,40 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok qlist_append(parser->tokens, dict); -if (parser->brace_count < 0 || +if (type == JSON_ERROR) { +goto out_emit_bad; +} else if (parser->brace_count < 0 || parser->bracket_count < 0 || (parser->brace_count == 0 && parser->bracket_count == 0)) { -parser->brace_count = 0; -parser->bracket_count = 0; -parser->emit(parser, parser->tokens); -QDECREF(parser->tokens); -parser->tokens = qlist_new(); -parser->token_size = 0; +goto out_emit; } else if (parser->token_size > MAX_TOKEN_SIZE || parser->bracket_count > MAX_NESTING || parser->brace_count > MAX_NESTING) { /* Security consideration, we limit total memory allocated per object * and the maximum recursion depth that a message can force. */ -parser->brace_count = 0; -parser->bracket_count = 0; -parser->emit(parser, parser->tokens); +goto out_emit; +} + +return; + +out_emit_bad: +/* clear out token list and tell the parser to emit and error + * indication by passing it a NULL list + */ +QDECREF(parser->tokens); +parser->tokens = NULL; +out_emit: +/* send current list of tokens to parser and reset tokenizer */ +parser->brace_count = 0; +parser->bracket_count = 0; +parser->emit(parser, parser->tokens); +if (parser->tokens) { QDECREF(parser->tokens); -parser->tokens = qlist_new(); -parser->token_size = 0; } +parser->tokens = qlist_new(); +parser->token_size = 0; } void json_message_parser_init(JSONMessageParser *parser, -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 13/17] guest agent: command state class
Signed-off-by: Michael Roth --- qga/guest-agent-command-state.c | 73 +++ 1 files changed, 73 insertions(+), 0 deletions(-) create mode 100644 qga/guest-agent-command-state.c diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c new file mode 100644 index 000..997355e --- /dev/null +++ b/qga/guest-agent-command-state.c @@ -0,0 +1,73 @@ +/* + * QEMU Guest Agent command state interfaces + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include +#include "guest-agent.h" + +struct GACommandState { +GSList *groups; +}; + +typedef struct GACommandGroup { +void (*init)(void); +void (*cleanup)(void); +} GACommandGroup; + +/* handle init/cleanup for stateful guest commands */ + +void ga_command_state_add(GACommandState *cs, + void (*init)(void), + void (*cleanup)(void)) +{ +GACommandGroup *cg = g_malloc0(sizeof(GACommandGroup)); +cg->init = init; +cg->cleanup = cleanup; +cs->groups = g_slist_append(cs->groups, cg); +} + +static void ga_command_group_init(gpointer opaque, gpointer unused) +{ +GACommandGroup *cg = opaque; + +g_assert(cg); +if (cg->init) { +cg->init(); +} +} + +void ga_command_state_init_all(GACommandState *cs) +{ +g_assert(cs); +g_slist_foreach(cs->groups, ga_command_group_init, NULL); +} + +static void ga_command_group_cleanup(gpointer opaque, gpointer unused) +{ +GACommandGroup *cg = opaque; + +g_assert(cg); +if (cg->cleanup) { +cg->cleanup(); +} +} + +void ga_command_state_cleanup_all(GACommandState *cs) +{ +g_assert(cs); +g_slist_foreach(cs->groups, ga_command_group_cleanup, NULL); +} + +GACommandState *ga_command_state_new(void) +{ +GACommandState *cs = g_malloc0(sizeof(GACommandState)); +cs->groups = NULL; +return cs; +} -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 01/17] json-lexer: make lexer error-recovery more deterministic
Currently when we reach an error state we effectively flush everything fed to the lexer, which can put us in a state where we keep feeding tokens into the parser at arbitrary offsets in the stream. This makes it difficult for the lexer/tokenizer/parser to get back in sync when bad input is made by the client. With these changes we emit an error state/token up to the tokenizer as soon as we reach an error state, and continue processing any data passed in rather than bailing out. The reset token will be used to reset the tokenizer and parser, such that they'll recover state as soon as the lexer begins generating valid token sequences again. We also map chr(192,193,245-255) to an error state here, since they are invalid UTF-8 characters. QMP guest proxy/agent will use chr(255) to force a flush/reset of previous input for reliable delivery of certain events, so also we document that thoroughly here. Signed-off-by: Michael Roth --- json-lexer.c | 33 - json-lexer.h |1 + 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/json-lexer.c b/json-lexer.c index 3462c89..bede557 100644 --- a/json-lexer.c +++ b/json-lexer.c @@ -105,7 +105,8 @@ static const uint8_t json_lexer[][256] = { ['u'] = IN_DQ_UCODE0, }, [IN_DQ_STRING] = { -[1 ... 0xFF] = IN_DQ_STRING, +[1 ... 0xBF] = IN_DQ_STRING, +[0xC2 ... 0xF4] = IN_DQ_STRING, ['\\'] = IN_DQ_STRING_ESCAPE, ['"'] = JSON_STRING, }, @@ -144,7 +145,8 @@ static const uint8_t json_lexer[][256] = { ['u'] = IN_SQ_UCODE0, }, [IN_SQ_STRING] = { -[1 ... 0xFF] = IN_SQ_STRING, +[1 ... 0xBF] = IN_SQ_STRING, +[0xC2 ... 0xF4] = IN_SQ_STRING, ['\\'] = IN_SQ_STRING_ESCAPE, ['\''] = JSON_STRING, }, @@ -305,10 +307,25 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch) new_state = IN_START; break; case ERROR: +/* XXX: To avoid having previous bad input leaving the parser in an + * unresponsive state where we consume unpredictable amounts of + * subsequent "good" input, percolate this error state up to the + * tokenizer/parser by forcing a NULL object to be emitted, then + * reset state. + * + * Also note that this handling is required for reliable channel + * negotiation between QMP and the guest agent, since chr(0xFF) + * is placed at the beginning of certain events to ensure proper + * delivery when the channel is in an unknown state. chr(0xFF) is + * never a valid ASCII/UTF-8 sequence, so this should reliably + * induce an error/flush state. + */ +lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y); QDECREF(lexer->token); lexer->token = qstring_new(); new_state = IN_START; -return -EINVAL; +lexer->state = new_state; +return 0; default: break; } @@ -334,7 +351,6 @@ int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size) for (i = 0; i < size; i++) { int err; - err = json_lexer_feed_char(lexer, buffer[i]); if (err < 0) { return err; @@ -346,7 +362,14 @@ int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size) int json_lexer_flush(JSONLexer *lexer) { -return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0); +if (lexer->state != IN_START) { +lexer->state = IN_START; +QDECREF(lexer->token); +lexer->token = qstring_new(); +return -EINVAL; +} + +return 0; } void json_lexer_destroy(JSONLexer *lexer) diff --git a/json-lexer.h b/json-lexer.h index 3b50c46..10bc0a7 100644 --- a/json-lexer.h +++ b/json-lexer.h @@ -25,6 +25,7 @@ typedef enum json_token_type { JSON_STRING, JSON_ESCAPE, JSON_SKIP, +JSON_ERROR, } JSONTokenType; typedef struct JSONLexer JSONLexer; -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 05/17] qapi: fix handling for null-return async callbacks
Async commands like 'guest-ping' have NULL retvals. Handle these by inserting an empty dictionary in the response's "return" field. Signed-off-by: Michael Roth --- qmp-core.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/qmp-core.c b/qmp-core.c index e33f7a4..9f3d182 100644 --- a/qmp-core.c +++ b/qmp-core.c @@ -922,9 +922,12 @@ void qmp_async_complete_command(QmpCommandState *cmd, QObject *retval, Error *er rsp = qdict_new(); if (err) { qdict_put_obj(rsp, "error", error_get_qobject(err)); -} else { +} else if (retval) { qobject_incref(retval); qdict_put_obj(rsp, "return", retval); +} else { +/* add empty "return" dict, this is the standard for NULL returns */ +qdict_put_obj(rsp, "return", QOBJECT(qdict_new())); } if (cmd->tag) { qdict_put_obj(rsp, "tag", cmd->tag); -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 03/17] json-parser: add handling for NULL token list
Currently a NULL token list will crash the parser, instead we have it pass back a NULL QObject. Signed-off-by: Michael Roth --- json-parser.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/json-parser.c b/json-parser.c index 58e973b..849e215 100644 --- a/json-parser.c +++ b/json-parser.c @@ -633,9 +633,13 @@ QObject *json_parser_parse(QList *tokens, va_list *ap) QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp) { JSONParserContext ctxt = {}; -QList *working = qlist_copy(tokens); +QList *working; QObject *result; +if (!tokens) { +return NULL; +} +working = qlist_copy(tokens); result = parse_value(&ctxt, &working, ap); QDECREF(working); -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 15/17] guest agent: qemu-ga daemon
This is the actual guest daemon, it listens for requests over a virtio-serial/isa-serial/unix socket channel and routes them through to dispatch routines, and writes the results back to the channel in a manner similar to QMP. A shorthand invocation: qemu-ga -d Is equivalent to: qemu-ga -c virtio-serial -p /dev/virtio-ports/org.qemu.guest_agent \ -p /var/run/qemu-guest-agent.pid -d Signed-off-by: Michael Roth --- qemu-ga.c | 711 + 1 files changed, 711 insertions(+), 0 deletions(-) create mode 100644 qemu-ga.c diff --git a/qemu-ga.c b/qemu-ga.c new file mode 100644 index 000..800d16b --- /dev/null +++ b/qemu-ga.c @@ -0,0 +1,711 @@ +/* + * QEMU Guest Agent + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Adam Litke + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "qemu_socket.h" +#include "json-streamer.h" +#include "json-parser.h" +#include "qga/guest-agent.h" + +#define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent" +#define QGA_PIDFILE_DEFAULT "/var/run/qemu-va.pid" +#define QGA_BAUDRATE_DEFAULT B38400 /* for isa-serial channels */ +#define QGA_TIMEOUT_DEFAULT 30*1000 /* ms */ + +struct GAState { +bool active; +int session_id; +const char *proxy_path; +JSONMessageParser parser; +GMainLoop *main_loop; +guint conn_id; +GSocket *conn_sock; +GIOChannel *conn_channel; +guint listen_id; +GSocket *listen_sock; +GIOChannel *listen_channel; +const char *path; +const char *method; +bool virtio; /* fastpath to check for virtio to deal with poll() quirks */ +GACommandState *command_state; +GAWorker *worker; +int timeout_ms; +GLogLevelFlags log_level; +FILE *log_file; +}; + +static void usage(const char *cmd) +{ +printf( +"Usage: %s -c \n" +"QEMU Guest Agent %s\n" +"\n" +" -c, --channel channel method: one of unix-connect, virtio-serial, or\n" +"isa-serial (virtio-serial is the default)\n" +" -p, --pathchannel path (%s is the default for virtio-serial)\n" +" -l, --logfile set logfile path, logs to stderr by default\n" +" -f, --pidfile specify pidfile (default is %s)\n" +" -v, --verbose log extra debugging information\n" +" -V, --version print version information and exit\n" +" -d, --daemonize become a daemon\n" +" -h, --helpdisplay this help and exit\n" +"\n" +"Report bugs to \n" +, cmd, QGA_VERSION, QGA_VIRTIO_PATH_DEFAULT, QGA_PIDFILE_DEFAULT); +} + +static void conn_channel_close(GAState *s); + +static const char *ga_log_level_str(GLogLevelFlags level) +{ +switch (level & G_LOG_LEVEL_MASK) { +case G_LOG_LEVEL_ERROR: return "error"; +case G_LOG_LEVEL_CRITICAL: return "critical"; +case G_LOG_LEVEL_WARNING: return "warning"; +case G_LOG_LEVEL_MESSAGE: return "message"; +case G_LOG_LEVEL_INFO: return "info"; +case G_LOG_LEVEL_DEBUG: return "debug"; +default:return "user"; +} +} + +static void ga_log(const gchar *domain, GLogLevelFlags level, + const gchar *msg, gpointer opaque) +{ +GAState *s = opaque; +GTimeVal time; +const char *level_str = ga_log_level_str(level); + +level &= G_LOG_LEVEL_MASK; +if (g_strcmp0(domain, "syslog") == 0) { +syslog(LOG_INFO, "%s: %s", level_str, msg); +} else if (level & s->log_level) { +g_get_current_time(&time); +fprintf(s->log_file, +"%lu.%lu: %s: %s\n", time.tv_sec, time.tv_usec, level_str, msg); +fflush(s->log_file); +} +} + +int ga_get_timeout(GAState *s) +{ +return s->timeout_ms; +} + +static void become_daemon(const char *pidfile) +{ +pid_t pid, sid; +int pidfd; +char *pidstr = NULL; + +pid = fork(); +if (pid < 0) { +exit(EXIT_FAILURE); +} +if (pid > 0) { +exit(EXIT_SUCCESS); +} + +pidfd = open(pidfile, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); +if (!pidfd || lockf(pidfd, F_TLOCK, 0)) { +g_error("Cannot lock pid file"); +} + +if (ftruncate(pidfd, 0) || lseek(pidfd, 0, SEEK_SET)) { +g_critical("Cannot truncate pid file"); +goto fail; +} +if (asprintf(&pidstr, "%d", getpid()) == -1) { +g_critical("Cannot allocate memory"); +goto fail; +} +if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) { +g_critical("Failed to write pid file"); +goto fail; +} + +umask(0); +sid = setsid(); +if (sid < 0) { +goto fail; +} +if ((chdir("/")) < 0) { +goto fail; +} + +close(STDIN_FILENO); +close(STDOUT_FILENO); +close(STDERR_FILENO); +retur
[Qemu-devel] [RFC][PATCH v2 14/17] guest agent: core marshal/dispatch interfaces
These are basically a stripped-down, guest-side analogue to what's in qmp_core.c: definitions used by qmp-gen.py-generated marshalling code to handle dispatch and a registration of command->function mappings (minus all the bits related to Qmp sessions/server/events). As a result of that, there is a little bit of code duplication here. It wouldn't be difficult to make the common bits shareable, but there isn't much. The guest agent will use these interfaces to handle dispatch/execution of requests it gets from the proxy. Signed-off-by: Michael Roth --- qga/guest-agent-core.c | 139 qga/guest-agent-core.h | 40 ++ 2 files changed, 179 insertions(+), 0 deletions(-) create mode 100644 qga/guest-agent-core.c create mode 100644 qga/guest-agent-core.h diff --git a/qga/guest-agent-core.c b/qga/guest-agent-core.c new file mode 100644 index 000..55498b1 --- /dev/null +++ b/qga/guest-agent-core.c @@ -0,0 +1,139 @@ +/* + * QEMU Guest Agent core functions + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Adam Litke + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include "guest-agent-core.h" + +typedef enum QmpCommandType { +QCT_NORMAL, +QCT_ASYNC, +} QmpCommandType; + +typedef struct QmpCommand { +const char *name; +QmpCommandType type; +QmpCommandFunc *fn; +QmpAsyncCommandFunc *afn; +QTAILQ_ENTRY(QmpCommand) node; +} QmpCommand; + +static QTAILQ_HEAD(, QmpCommand) qmp_commands = +QTAILQ_HEAD_INITIALIZER(qmp_commands); + +QmpMarshalState *qmp_state_get_mstate(QmpState *sess) +{ +return NULL; +} + +void qga_register_command(const char *name, QmpCommandFunc *fn) +{ +QmpCommand *cmd = qemu_mallocz(sizeof(*cmd)); + +cmd->name = name; +cmd->type = QCT_NORMAL; +cmd->fn = fn; +QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node); +} + +static QmpCommand *qmp_find_command(const char *name) +{ +QmpCommand *i; + +QTAILQ_FOREACH(i, &qmp_commands, node) { +if (strcmp(i->name, name) == 0) { +return i; +} +} +return NULL; +} + +static QObject *qga_dispatch_err(QObject *request, Error **errp) +{ +const char *command; +QDict *args, *dict; +QmpCommand *cmd; +QObject *ret = NULL; + +if (qobject_type(request) != QTYPE_QDICT) { +error_set(errp, QERR_JSON_PARSE_ERROR, "request is not a dictionary"); +goto out; +} + +dict = qobject_to_qdict(request); +if (!qdict_haskey(dict, "execute")) { +error_set(errp, QERR_JSON_PARSE_ERROR, "no execute key"); +goto out; +} + +command = qdict_get_str(dict, "execute"); +cmd = qmp_find_command(command); +if (cmd == NULL) { +error_set(errp, QERR_COMMAND_NOT_FOUND, command); +goto out; +} + +if (!qdict_haskey(dict, "arguments")) { +args = qdict_new(); +} else { +args = qdict_get_qdict(dict, "arguments"); +QINCREF(args); +} + +switch (cmd->type) { +case QCT_NORMAL: +cmd->fn(NULL, args, &ret, errp); +if (ret == NULL) { +ret = QOBJECT(qdict_new()); +} +break; +case QCT_ASYNC: { +QmpCommandState *s = qemu_mallocz(sizeof(*s)); +/* FIXME save async commands and do something + * smart if disconnect occurs before completion + */ +s->tag = NULL; +if (qdict_haskey(dict, "tag")) { +s->tag = qdict_get(dict, "tag"); +qobject_incref(s->tag); +} +cmd->afn(args, errp, s); +ret = NULL; +} +break; +} + +QDECREF(args); + +out: +return ret; +} + +QObject *qga_dispatch(QObject *request, Error **errp) +{ +Error *err = NULL; +QObject *ret; +QDict *rsp; + +ret = qga_dispatch_err(request, &err); + +rsp = qdict_new(); +if (err) { +qdict_put_obj(rsp, "error", error_get_qobject(err)); +error_free(err); +} else if (ret) { +qdict_put_obj(rsp, "return", ret); +} else { +QDECREF(rsp); +return NULL; +} + +return QOBJECT(rsp); +} diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h new file mode 100644 index 000..51ae798 --- /dev/null +++ b/qga/guest-agent-core.h @@ -0,0 +1,40 @@ +/* + * QEMU Guest Agent core declarations + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Adam Litke + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include "qmp-core.h" +#include "qapi-types-core.h" +#include "qmp-marshal-types-core.h" +#include "qemu-common.h" +#include "qdict.h" + +#define QGA_VERSION "1.0" + +typedef struct GAState GAState; +typedef struct GACommandState GACommandState; +typedef struct GAWorker GAWorker; +typedef void (*ga_w
[Qemu-devel] [RFC][PATCH v2 17/17] guest agent: build qemu-ga, add QEMU-wide gio dep
This allows us to build qemu-ga with "make qemu-ga". It pulls in the qemu-tools deps, but does not currently build by default. This may change to avoid bitrot and help with host-side-only unit tests. This also pulls in gio dependences for all of qemu, currently we only pull in gthread. In general this brings in gio, gmodule, and gobject. Can limit this to only the guest agent, but it's expected that all of these will be needed as we start relying more on glib throughout qemu, so leaving for now. Signed-off-by: Michael Roth --- Makefile | 15 +-- configure |6 +++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index d510779..a7c1503 100644 --- a/Makefile +++ b/Makefile @@ -173,10 +173,10 @@ libqmp.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py libqmp.c: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py $(call quiet-command,python $(SRC_PATH)/qmp-gen.py --lib-body $@ < $<, " GEN $@") -guest-agent.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py +qga/guest-agent.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py $(call quiet-command,python $(SRC_PATH)/qmp-gen.py --guest-header $@ < $<, " GEN $@") -guest-agent.c: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py +qga/guest-agent.c: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py $(call quiet-command,python $(SRC_PATH)/qmp-gen.py --guest-body $@ < $<, " GEN $@") qdev-marshal.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qmp-gen.py @@ -206,6 +206,7 @@ libqmp.o: libqmp.c libqmp.h qapi-types.h qdev-marshal.o: qdev-marshal.c qdev-marshal.h qapi-types.h qcfg-marshal.o: qcfg-marshal.c qcfg-marshal.h qapi-types.h qcfg-opts.o: qcfg-opts.c qcfg-opts.h qcfg-marshal.h qapi-types.h +qemu-ga.o: qga/guest-agent.c qga/guest-agent.h qmp-marshal-types.c qmp-marshal-types.h version.o: $(SRC_PATH)/version.rc config-host.mak $(call quiet-command,$(WINDRES) -I. -o $@ $<," RC$(TARGET_DIR)$@") @@ -214,7 +215,9 @@ version-obj-$(CONFIG_WIN32) += version.o ## qemu-img.o: qemu-img-cmds.h -qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS) +qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o: $(GENERATED_HEADERS) + +qemu-ga$(EXESUF): qemu-ga.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o qemu-sockets.o qmp-marshal-types-core.o qmp-marshal-types.o qga/guest-agent.o qga/guest-agent-core.o qga/guest-agent-commands.o qga/guest-agent-command-state.o qga/guest-agent-worker.o qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o @@ -276,8 +279,8 @@ clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f qemu-options.def - rm -f *.o *.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~ - rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d + rm -f *.o *.d *.a $(TOOLS) qemu-ga TAGS cscope.* *.pod *~ */*~ + rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qga/*.o qga/*.d rm -f qemu-img-cmds.h rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp @@ -463,4 +466,4 @@ tarbin: $(mandir)/man8/qemu-nbd.8 # Include automatically generated dependency files --include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d) +-include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d qga/*.d) diff --git a/configure b/configure index d99deb2..bfea356 100755 --- a/configure +++ b/configure @@ -1659,9 +1659,9 @@ fi ## # glib support probe -if $pkg_config --modversion gthread-2.0 > /dev/null 2>&1 ; then -glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null` -glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null` +if $pkg_config --modversion gthread-2.0 gio-2.0 > /dev/null 2>&1 ; then +glib_cflags=`$pkg_config --cflags gthread-2.0 gio-2.0 2>/dev/null` +glib_libs=`$pkg_config --libs gthread-2.0 gio-2.0 2>/dev/null` libs_softmmu="$glib_libs $libs_softmmu" libs_tools="$glib_libs $libs_tools" else -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v2 11/17] qmp proxy: build QEMU with qmp proxy
Signed-off-by: Michael Roth --- Makefile.objs |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Makefile.objs b/Makefile.objs index df7e670..f143bd8 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -103,6 +103,7 @@ common-obj-y += block-migration.o common-obj-y += pflib.o common-obj-y += qmp-marshal.o qmp-marshal-types.o common-obj-y += qmp-marshal-types-core.o qmp-core.o +common-obj-y += qmp-proxy.o common-obj-y += hmp.o common-obj-$(CONFIG_BRLAPI) += baum.o -- 1.7.0.4
Re: [Qemu-devel] [PULL] Migration of misc devices
On 04/17/2011 03:08 PM, Juan Quintela wrote: > > > The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885: > > usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100) > > are available in the git repository at: > git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2 Migration appears to be broken for me. It's not caused by this series but I'm surprised you didn't encounter it. Maybe it's my kernel version? My suspicion is that the cause of this is: commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0 Author: Jan Kiszka Date: Mon Feb 7 12:19:26 2011 +0100 kvm: x86: Introduce kvmclock device to save/restore its state Regards, Anthony Liguori > Juan Quintela (45): > vmstate: port adb_kbd > vmstate: port adb_mouse > vmstate: port ads7846 > vmstate: port m48t59 > vmstate: port mipsnet > vmstate: port arm sp804 > vmstate: port arm_timer > vmstate: port sysborg_timer > vmstate: port pmtimer > vmstate: port syborg_rtc > vmstate: port pxa2xx_keypad > vmstate: port pl011 > vmstate: port armv7m nvic > vmstate: port stellaris i2c > vmstate: port stellaris ssi bus > vmstate: port stellaris sys > vmstate: port pl022 ssp > vmstate: port heathrow_pic > vmstate: port cuda > vmstate: port stellaris gptm > vmstate: port pxa2xx_i2s > vmstate: port pxa2xx_cm > vmstate: port pxa2xx_mm > vmstate: port pxa2xx_pm > vmstate: port ppce500_pci > vmstate: port ppc4xx_pci > vmstate: port syborg_pointer > vmstate: port stellaris_adc > vmstate: port syborg_serial > vmstate: port syborg_keyboard > vmstate: port stellaris gamepad > vmstate: stellaris use unused for placeholder entries > pxa2xx_lcd: name anonymous struct > pxa2xx_lcd: up field is used as a bool and migrated as an uint8_t > vmstate: port pxa2xx_lcd > max111x: input field is only used as uint8_t > vmstate: port max111x > nand: pin values are uint8_t > vmstate: port nand > mac_nvram: size is a size, no need to be a target dependent type > vmstate: port mac_nvram > piix4: create PIIX4State > vmstate: port piix4 > mac_dbdma: create DBDMAState instead of passing one array around > vmstate: port mac_dbdma > > hw/adb.c | 83 +- > hw/ads7846.c | 41 +++ > hw/arm_timer.c | 66 --- > hw/armv7m_nvic.c | 39 ++ > hw/cuda.c| 116 +++--- > hw/flash.h |4 +- > hw/heathrow_pic.c| 62 -- > hw/hw.h | 17 ++- > hw/m48t59.c | 36 ++ > hw/mac_dbdma.c | 83 +++-- > hw/mac_nvram.c | 32 ++--- > hw/max111x.c | 51 +++- > hw/mipsnet.c | 53 +++-- > hw/nand.c| 79 +++-- > hw/piix4.c | 44 > hw/pl011.c | 76 > hw/pl022.c | 84 ++ > hw/ppc4xx_pci.c | 80 ++--- > hw/ppce500_pci.c | 87 ++ > hw/ptimer.c | 59 +++--- > hw/pxa2xx.c | 158 + > hw/pxa2xx_keypad.c | 53 +++-- > hw/pxa2xx_lcd.c | 138 +- > hw/stellaris.c | 323 > +- > hw/stellaris_input.c | 50 > hw/syborg_keyboard.c | 57 +++-- > hw/syborg_pointer.c | 73 +--- > hw/syborg_rtc.c | 34 ++ > hw/syborg_serial.c | 60 +++--- > hw/syborg_timer.c| 46 +++- > qemu-timer.h |2 - > 31 files changed, 854 insertions(+), 1332 deletions(-) > >
Re: [Qemu-devel] [RFC PATCH] implement vmware pvscsi device
On Mon, Apr 18, 2011 at 3:05 PM, Hannes Reinecke wrote: > On 04/15/2011 10:56 PM, Paolo Bonzini wrote: >> >> On 04/15/2011 05:04 PM, Stefan Hajnoczi wrote: >>> >>> The way I approached virtio-scsi was to look at the SCSI Architecture >>> Model document and some of the Linux SCSI code. I'm not sure if >>> letting virtio-blk SCSI pass-through or scsi-generic guide us is a >>> good approach. >>> >>> How do your ioprio and barrier relate to SCSI? >> >> Both are part of the transport protocol, which can provide >> additional features with respect to SAM. For example SCSI doesn't >> provide the full details of hotplug/hotunplug, or doesn't have a way >> for the guest to trigger a drive unplug on the host, but these are >> all desirable features for virtio-scsi (and they are supported by >> vmw_pvscsi by the way). >> > And this is something I really miss in the current proposals, namely > a working transport layer. > > The SCSI spec (SPC etc) itself just handles command delivery between > initiator and target. Anything else (like hotplug, error recovery, target > addressing etc) is out of the scope of the spec and needs to be implemented > on another layer (that's the ominous > transport layer). > > Hence any protocol implemented to the above spec would be missing those > parts, and they would need to be implemented additionally. > Which also explains why these features are missing when just using SCSI CDBs > as the main command container. > > My proposal would be to implement a full virtio-scsi _host_, and extend the > proposal to be able to handle the transport layer too. > At the lastest we would need to include a LUN address before the CDB, and > define TMF command values for proper error recovery. > > That way we could handle hotplug / -unplug via a simple host rescan, and > would even be able to pass-in NPIV hosts. In my prototype there is a header and a footer for the request and response, respectively: http://git.kernel.org/?p=linux/kernel/git/nab/lio-core-2.6.git;a=blob;f=include/linux/virtio_scsi.h;hb=refs/heads/tcm_vhost We definitely need more than plain CDB pass-through. Stefan
[Qemu-devel] [PATCH 1/3] linux-user: Don't use MAP_FIXED in do_brk()
Since mmap() with MAP_FIXED will map over the top of existing mappings, it's a bad idea to use it to implement brk(), because brk() with a large size is likely to overwrite important things like qemu itself or the host libc. So we drop MAP_FIXED and handle "mapped but at different address" as an error case instead. Signed-off-by: Peter Maydell --- linux-user/syscall.c | 29 - 1 files changed, 20 insertions(+), 9 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index bb0999d..e68c5e0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -733,23 +733,34 @@ abi_long do_brk(abi_ulong new_brk) return target_brk; } -/* We need to allocate more memory after the brk... */ +/* We need to allocate more memory after the brk... Note that + * we don't use MAP_FIXED because that will map over the top of + * any existing mapping (like the one with the host libc or qemu + * itself); instead we treat "mapped but at wrong address" as + * a failure and unmap again. + */ new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, PROT_READ|PROT_WRITE, -MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); +MAP_ANON|MAP_PRIVATE, 0, 0)); + +if (mapped_addr == brk_page) { +target_brk = new_brk; +return target_brk; +} else if (mapped_addr != -1) { +/* Mapped but at wrong address, meaning there wasn't actually + * enough space for this brk. + */ +target_munmap(mapped_addr, new_alloc_size); +mapped_addr = -1; +} #if defined(TARGET_ALPHA) /* We (partially) emulate OSF/1 on Alpha, which requires we return a proper errno, not an unchanged brk value. */ -if (is_error(mapped_addr)) { -return -TARGET_ENOMEM; -} +return -TARGET_ENOMEM; #endif - -if (!is_error(mapped_addr)) { - target_brk = new_brk; -} +/* For everything else, return the previous break. */ return target_brk; } -- 1.7.1
[Qemu-devel] [PATCH 2/3] arm-semi.c: Use correct check for failure of do_brk()
In the ARM semihosting implementation of SYS_HEAPINFO, use the correct check for whether do_brk() has failed -- it does not return -1 but the previous value of the break limit. Signed-off-by: Peter Maydell --- arm-semi.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arm-semi.c b/arm-semi.c index e9e6f89..5a62d03 100644 --- a/arm-semi.c +++ b/arm-semi.c @@ -440,15 +440,16 @@ uint32_t do_arm_semihosting(CPUState *env) /* Some C libraries assume the heap immediately follows .bss, so allocate it using sbrk. */ if (!ts->heap_limit) { -long ret; +abi_ulong ret; ts->heap_base = do_brk(0); limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; /* Try a big heap, and reduce the size if that fails. */ for (;;) { ret = do_brk(limit); -if (ret != -1) +if (ret >= limit) { break; +} limit = (ts->heap_base >> 1) + (limit >> 1); } ts->heap_limit = limit; -- 1.7.1
[Qemu-devel] [PATCH 0/3] Fix ARM semihosting SYS_HEAPINFO issues
This patchset is intended to fix some problems with the ARM semihosting SYS_HEAPINFO call. Patch 1 fixes a bug in do_brk() which meant that using SYS_HEAPINFO tended to result in our accidentally unmapping the host libc. Patch 2 fixes the bug https://bugs.launchpad.net/qemu/+bug/656285 by correcting the check for failure of do_brk(). Patch 3 does the same for the equivalent code in m68k-semi.c, but note that I have only tested that it compiles. (linux-user/m68k-sim.c also has a suspicious error check on do_brk(), but since I don't have any specs of what the simcalls there are supposed to do on error I haven't attempted to fix this one.) Peter Maydell (3): linux-user: Don't use MAP_FIXED in do_brk() arm-semi.c: Use correct check for failure of do_brk() m68k-semi.c: Use correct check for failure of do_brk() arm-semi.c |5 +++-- linux-user/syscall.c | 29 - m68k-semi.c |5 +++-- 3 files changed, 26 insertions(+), 13 deletions(-)
Re: [Qemu-devel] KVM call agenda for April 19th
Tools for resource accounting the virtual machines. Fingerprint 35C0 49D6 E879 1F30 2FC3 0313 58C0 8857 4681 A236 Luis Antonio Galindo Castro (FunkyM0nk3y) On Mon, Apr 18, 2011 at 04:46, Juan Quintela wrote: > > Please, send in any agenda items you are interested in covering. > > Later, Juan. > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html >
Re: [Qemu-devel] [PULL] Migration of misc devices
On 2011-04-18 17:12, Anthony Liguori wrote: > On 04/17/2011 03:08 PM, Juan Quintela wrote: >> >> >> The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885: >> >> usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100) >> >> are available in the git repository at: >> git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2 > > Migration appears to be broken for me. It's not caused by this series > but I'm surprised you didn't encounter it. Maybe it's my kernel version? > > My suspicion is that the cause of this is: > > commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0 > Author: Jan Kiszka > Date: Mon Feb 7 12:19:26 2011 +0100 > > kvm: x86: Introduce kvmclock device to save/restore its state Can you prove your suspicion a bit by retrying with -cpu ...,-kvmclock? Is your guest using kvmclock? Are you migrating from old to new or between new versions? Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH] set VIRTIO_BALLOON_F_MUST_TELL_HOST unconditionally
On Fri, 2011-04-15 at 14:20 -0500, Anthony Liguori wrote: > On 04/15/2011 02:15 PM, Dave Hansen wrote: > > On Fri, 2011-04-15 at 12:17 -0500, Anthony Liguori wrote: > >> If you're in OOM and you need memory, you can't ask the host for more > >> and wait for a response. You have to reclaim it immediately. > > Why not? The call in to the notifier chain the s390 case is > > synchronous. The OOM only affects one task at a time and won't proceed > > elsewhere while this is going on. > > Because if we tell the host, we have to wait for the host to ack which > means we'd sleep waiting for an interrupt. Can you do this in the OOM path? Sure. One of the s390 handlers sleeps today. > > Why do we even _tell_ qemu, though? The MADV_WILLNEED is nice, but far > > from being necessary. We could just skip the entire notification in OOM > > situations. > > There's really no particular reason to other than symmetry. When we get there, it sounds like we can simply _skip_ the notification in the qemu case. -- Dave
Re: [Qemu-devel] [PULL] Migration of misc devices
On 04/18/2011 10:36 AM, Jan Kiszka wrote: > On 2011-04-18 17:12, Anthony Liguori wrote: >> On 04/17/2011 03:08 PM, Juan Quintela wrote: >>> >>> >>> The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885: >>> >>> usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100) >>> >>> are available in the git repository at: >>> git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2 >> >> Migration appears to be broken for me. It's not caused by this series >> but I'm surprised you didn't encounter it. Maybe it's my kernel version? >> >> My suspicion is that the cause of this is: >> >> commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0 >> Author: Jan Kiszka >> Date: Mon Feb 7 12:19:26 2011 +0100 >> >> kvm: x86: Introduce kvmclock device to save/restore its state > > Can you prove your suspicion a bit by retrying with -cpu ...,-kvmclock? > Is your guest using kvmclock? Are you migrating from old to new or > between new versions? Heh, it turns out I was migrating from KVM to TCG :-) This changeset "breaks" that but I don't think I'd count this as a supported use-case so I don't count it as a regression. So ignore the noise here. Regards, Anthony Liguori > Jan >
[Qemu-devel] [PATCH 3/3] m68k-semi.c: Use correct check for failure of do_brk()
In the m68k semihosting implementation of HOSTED_INIT_SIM, use the correct check for whether do_brk() has failed -- it does not return -1 but the previous value of the break limit. Signed-off-by: Peter Maydell --- m68k-semi.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/m68k-semi.c b/m68k-semi.c index 0371089..7fde10e 100644 --- a/m68k-semi.c +++ b/m68k-semi.c @@ -370,7 +370,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) TaskState *ts = env->opaque; /* Allocate the heap using sbrk. */ if (!ts->heap_limit) { -long ret; +abi_ulong ret; uint32_t size; uint32_t base; @@ -379,8 +379,9 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) /* Try a big heap, and reduce the size if that fails. */ for (;;) { ret = do_brk(base + size); -if (ret != -1) +if (ret >= (base + size)) { break; +} size >>= 1; } ts->heap_limit = base + size; -- 1.7.1
Re: [Qemu-devel] [PULL] Migration of misc devices
On 2011-04-18 17:44, Anthony Liguori wrote: > On 04/18/2011 10:36 AM, Jan Kiszka wrote: >> On 2011-04-18 17:12, Anthony Liguori wrote: >>> On 04/17/2011 03:08 PM, Juan Quintela wrote: The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885: usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100) are available in the git repository at: git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2 >>> >>> Migration appears to be broken for me. It's not caused by this series >>> but I'm surprised you didn't encounter it. Maybe it's my kernel version? >>> >>> My suspicion is that the cause of this is: >>> >>> commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0 >>> Author: Jan Kiszka >>> Date: Mon Feb 7 12:19:26 2011 +0100 >>> >>> kvm: x86: Introduce kvmclock device to save/restore its state >> >> Can you prove your suspicion a bit by retrying with -cpu ...,-kvmclock? >> Is your guest using kvmclock? Are you migrating from old to new or >> between new versions? > > Heh, it turns out I was migrating from KVM to TCG :-) > > This changeset "breaks" that but I don't think I'd count this as a > supported use-case so I don't count it as a regression. I would say it now breaks earlier and less subtly. :) Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [Bug 656285] Re: arm-semi mishandling SYS_HEAPINFO
I've just submitted a patchset which I think fixes this bug (among others): http://patchwork.ozlabs.org/patch/91789/ [1/3] linux-user: Don't use MAP_FIXED in do_brk() http://patchwork.ozlabs.org/patch/91790/ [2/3] arm-semi.c: Use correct check for failure of do_brk() http://patchwork.ozlabs.org/patch/91793/ [3/3] m68k-semi.c: Use correct check for failure of do_brk() -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/656285 Title: arm-semi mishandling SYS_HEAPINFO Status in QEMU: New Bug description: I am running qemu-arm on a 32-bit fedora-7 i386 machine: $ /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm --version qemu-arm version 0.12.3, Copyright (c) 2003-2008 Fabrice Bellard When I try to run an arm semi-hosted executable, I sometimes get unexpected segv and sometimes not, depending on the executable. The symptom is: $ /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm -cpu cortex-a9 -- a.out qemu: uncaught target signal 11 (Segmentation fault) - core dumped Segmentation fault It appear to be because of the handling of the SYS_HEAPINFO syscall in arm-semi.c. There it tries to allocate 128M for the heap by calling do_brk() which calls target_mmap(). This is the DEBUG_MMAP diagnostic: mmap: start=0x9000 len=0x08001000 prot=rw- flags=MAP_FIXED MAP_ANON MAP_PRIVATE fd=0 offset= but this mmap is failing because there are shared libraries (and the gate page) mapped there: $ ldd /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm linux-gate.so.1 => (0x0088) librt.so.1 => /lib/librt.so.1 (0x03409000) libpthread.so.0 => /lib/libpthread.so.0 (0x00d7d000) libm.so.6 => /lib/libm.so.6 (0x00d4b000) libc.so.6 => /lib/libc.so.6 (0x00bf5000) /lib/ld-linux.so.2 (0x00bd6000) However, it seems that the code in arm-semi.c does not interpret the result of do_brk() correctly, and thinks that the mapping succeeded. The following patch appears to fix the problem: $ diff -u arm-semi.c.orig arm-semi.c --- arm-semi.c.orig 2010-09-21 13:19:15.0 +0100 +++ arm-semi.c 2010-10-07 13:23:13.0 +0100 @@ -475,7 +475,7 @@ /* Try a big heap, and reduce the size if that fails. */ for (;;) { ret = do_brk(limit); -if (ret != -1) +if (ret == limit) break; limit = (ts->heap_base >> 1) + (limit >> 1); } Do you think this is a genuine bug? Steve.
Re: [Qemu-devel] [RFC PATCH] implement vmware pvscsi device
On 04/18/2011 04:05 PM, Hannes Reinecke wrote: My proposal would be to implement a full virtio-scsi _host_, and extend the proposal to be able to handle the transport layer too. Yes, I have added this independently from Friday to today, and it is why I haven't sent the proposal yet. At the lastest we would need to include a LUN address before the CDB, and define TMF command values for proper error recovery. I haven't yet worked out TMF, but I did add a LUN. That way we could handle hotplug / -unplug via a simple host rescan It's a bit more complicated because you also want guest-initiated unplug, and SAM transport reset events include more than hotplug/unplug. I couldn't find that in either SPC or SAM indeed. It seems like a pretty widespread assumption though. Perhaps Nicholas or Hannes know where it comes from. 96 bytes is a carry-over from scsi parallel. We shouldn't rely on a fixed length here but rather use an additional pointer/iovec and length field. Check SG_IO header on how it's done. Will do. Paolo
Re: [Qemu-devel] iPXE/Etherboot prompts twice for booting?
On Mon, 2011-04-18 at 10:45 +0100, Stefan Hajnoczi wrote: > On Sat, Apr 16, 2011 at 8:41 PM, Michael Tokarev wrote: > > I'm playing with iPXE ROM images again, and see > > iPXE prompts two times during bootup. Once like > > this: "Press Ctrl-B to configure", at early stage, > > even if -boot n is not selected. And second time > > when it actually tries to boot, like "Press Ctrl-B > > for the command line". > > > > The same behavor happens with old Etherboot, with > > the exception that during init stage it tries to > > boot too but fails. > > > > Any idea how to get rid of that? > > IIRC you need to #define BANNER_TIMEOUT 0 in src/config/general.h. I think src/local/config/general.h is the preferred location, which is what the script in my tree does and includes pre-built ipxe images: https://github.com/awilliam/qemu/tree/ipxe Alex
Re: [Qemu-devel] [PATCH] acpi_piix4: fix save/load of PIIX4PMState
Isaku Yamahata wrote: > It's vmstate parameter was wrong. This patch fixes it. > > Reported-by: Avi Kivity > Signed-off-by: Isaku Yamahata > --- > hw/acpi_piix4.c |3 +-- > 1 files changed, 1 insertions(+), 2 deletions(-) > > diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c > index 96f5222..3a8fece 100644 > --- a/hw/acpi_piix4.c > +++ b/hw/acpi_piix4.c > @@ -214,10 +214,9 @@ static int vmstate_acpi_post_load(void *opaque, int > version_id) > { \ > .name = (stringify(_field)), \ > .version_id = 0,\ > - .num= GPE_LEN, \ > .info = &vmstate_info_uint16, \ > .size = sizeof(uint16_t), \ > - .flags = VMS_ARRAY | VMS_POINTER, \ > + .flags = VMS_SINGLE | VMS_POINTER, \ > .offset = vmstate_offset_pointer(_state, _field, uint8_t), > \ shouldn't last one still be uint16_t? I guess that on ich9, GPE becomes one array, do you have that code handy somewhere, just to see what you want to do? I think that best thing to do at this point is just to revert this whole patch. We are creating a new type for uint8_t, that becomes a pointer. We are not sending the length of that array, so we need to add a new version/subsection when we add ICH9 anyways. Seeing what you want to do would help me trying to figure out the best vmstate aproach. Thanks, Juan.
Re: [Qemu-devel] [PATCH 03/17] linux-user: define a couple of syscalls for non-uid16 targets
On Fri, Apr 15, 2011 at 05:32:44PM +0200, Alexander Graf wrote: > From: Ulrich Hecht > > Quite a number of syscalls are only defined on systems with USE_UID16 > defined; this patch defines them on other systems as well. > > Fixes a large number of uid/gid-related testcases on the s390x target > (and most likely on other targets as well) I'll provide cleaner patch for the same effect. This one makes the code more ifdeffed and harder to follow. > Signed-off-by: Ulrich Hecht > > --- > > v3 -> v4: > > - remove linux-user host bits > --- > linux-user/syscall.c | 125 > ++ > 1 files changed, 105 insertions(+), 20 deletions(-) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 504b26c..99f5935 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -326,7 +326,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, > mode_t mode) >return (fchmodat(dirfd, pathname, mode, 0)); > } > #endif > -#if defined(TARGET_NR_fchownat) && defined(USE_UID16) > +#if defined(TARGET_NR_fchownat) > static int sys_fchownat(int dirfd, const char *pathname, uid_t owner, > gid_t group, int flags) > { > @@ -435,7 +435,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char > *,pathname,int,mode) > #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) > _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode) > #endif > -#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && > defined(USE_UID16) > +#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) > _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname, >uid_t,owner,gid_t,group,int,flags) > #endif > @@ -6817,18 +6817,35 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > case TARGET_NR_setfsgid: > ret = get_errno(setfsgid(arg1)); > break; > +#else /* USE_UID16 */ > +#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) > +case TARGET_NR_fchownat: > +if (!(p = lock_user_string(arg2))) > +goto efault; > +ret = get_errno(sys_fchownat(arg1, p, arg3, arg4, arg5)); > +unlock_user(p, arg2, 0); > +break; > +#endif > #endif /* USE_UID16 */ > > -#ifdef TARGET_NR_lchown32 > +#if defined(TARGET_NR_lchown32) || !defined(USE_UID16) > +#if defined(TARGET_NR_lchown32) > case TARGET_NR_lchown32: > +#else > +case TARGET_NR_lchown: > +#endif > if (!(p = lock_user_string(arg1))) > goto efault; > ret = get_errno(lchown(p, arg2, arg3)); > unlock_user(p, arg1, 0); > break; > #endif > -#ifdef TARGET_NR_getuid32 > +#if defined(TARGET_NR_getuid32) || (defined(TARGET_NR_getuid) && > !defined(USE_UID16)) > +#if defined(TARGET_NR_getuid32) > case TARGET_NR_getuid32: > +#else > +case TARGET_NR_getuid: > +#endif > ret = get_errno(getuid()); > break; > #endif > @@ -6973,33 +6990,57 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > break; > #endif > > -#ifdef TARGET_NR_getgid32 > +#if defined(TARGET_NR_getgid32) || (defined(TARGET_NR_getgid) && > !defined(USE_UID16)) > +#if defined(TARGET_NR_getgid32) > case TARGET_NR_getgid32: > +#else > +case TARGET_NR_getgid: > +#endif > ret = get_errno(getgid()); > break; > #endif > -#ifdef TARGET_NR_geteuid32 > +#if defined(TARGET_NR_geteuid32) || (defined(TARGET_NR_geteuid) && > !defined(USE_UID16)) > +#if defined(TARGET_NR_geteuid32) > case TARGET_NR_geteuid32: > +#else > +case TARGET_NR_geteuid: > +#endif > ret = get_errno(geteuid()); > break; > #endif > -#ifdef TARGET_NR_getegid32 > +#if defined(TARGET_NR_getegid32) || (defined(TARGET_NR_getegid) && > !defined(USE_UID16)) > +#if defined(TARGET_NR_getegid32) > case TARGET_NR_getegid32: > +#else > +case TARGET_NR_getegid: > +#endif > ret = get_errno(getegid()); > break; > #endif > -#ifdef TARGET_NR_setreuid32 > +#if defined(TARGET_NR_setreuid32) || !defined(USE_UID16) > +#if defined(TARGET_NR_setreuid32) > case TARGET_NR_setreuid32: > +#else > +case TARGET_NR_setreuid: > +#endif > ret = get_errno(setreuid(arg1, arg2)); > break; > #endif > -#ifdef TARGET_NR_setregid32 > +#if defined(TARGET_NR_setregid32) || !defined(USE_UID16) > +#if defined(TARGET_NR_setregid32) > case TARGET_NR_setregid32: > +#else > +case TARGET_NR_setregid: > +#endif > ret = get_errno(setregid(arg1, arg2)); > break; > #endif > -#ifdef TARGET_NR_getgroups32 > +#if defined(TARGET_NR_getgroups32) || !defined(USE_UID16) > +#if defined(TARGET_NR_getgroups32) > case TARGET_NR_getgroups32: > +#else > +case TARGET_NR_getgroups: > +#endif > { > int gidsetsize = arg1; > uint32_t *target_grouplist; > @@ -7023,8 +7064,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long > arg1, > } > break
Re: [Qemu-devel] [PATCH] Remove unneeded function parameter from gen_pc_load
Am 17.04.2011 23:43, schrieb Aurelien Jarno: On Sun, Apr 17, 2011 at 10:34:47PM +0100, Peter Maydell wrote: On 17 April 2011 22:07, Stefan Weil wrote: Am 17.04.2011 20:27, schrieb Aurelien Jarno: On Thu, Apr 14, 2011 at 08:50:00PM +0200, Stefan Weil wrote: Am 13.04.2011 23:05, schrieb Peter Maydell: On 13 April 2011 21:38, Stefan Weil wrote: gen_pc_load was introduced in commit d2856f1ad4c259e5766847c49acbb4e390731bd4. The only reason for parameter searched_pc was a debug statement in target-i386/translate.c. Remove searched_pc from the debug statement and from the parameter list of gen_pc_load. No issues with the meat of the patch, but if we're going to change all the callers and implementations of this anyway, is there any appetite for giving it a more appropriate name? It doesn't generate any code, it affects more than just the pc, and it doesn't do a load... restore_state_to_opc() ? set_env_for_opc() ? -- PMM What about cpu_restore_pc()? That's not always the whole truth, but it's always the main action done in function n.n. which currently is called gen_pc_load. Or cpu_restore_helper()? Helper is very generic - it always fits. Aurelien, please feel free to choose a name which suits bests. I don't mind if you simply patch my patch, create a new one or tell me which name should go into a new version of the patch so I can send it. As Peter said, the function is doing more than simply restoring the pc. I am fine with the name he proposed, I think restore_state_to_opc() is a bit better. Ok, so I'll send a new patch which also replaces gen_pc_load by restore_state_to_op. That's _to_opc, not _to_op : I was trying to be consistent with the naming of the gen_opc_* arrays. Oops, sorry, just a cut & paste mistake. I agree, but it was my mistake. The first of the following patches is an improved version of my previous patch. It uses the correct name restore_state_to_opc and also removes a second parameter. The second patch is based on the first and removes a parameter from another function. [PATCH 1/2] Remove unused function parameters from gen_pc_load and rename the function [PATCH 2/2] Remove unused function parameter from cpu_restore_state Cheers, Stefan W.
[Qemu-devel] [PATCH 1/2] Remove unused function parameters from gen_pc_load and rename the function
Function gen_pc_load was introduced in commit d2856f1ad4c259e5766847c49acbb4e390731bd4. The only reason for parameter searched_pc was a debug statement in target-i386/translate.c. Parameter puc was needed by target-sparc until commit d2856f1ad4c259e5766847c49acbb4e390731bd4. Remove searched_pc from the debug statement and remove both parameters from the parameter list of gen_pc_load. As the function name gen_pc_load was also misleading, it is now called restore_state_to_opc. This new name was suggested by Peter Maydell, thanks. v2: Remove last parameter, too, and rename the function. Signed-off-by: Stefan Weil --- exec-all.h|4 ++-- target-alpha/translate.c |3 +-- target-arm/translate.c|7 +++ target-cris/translate.c |3 +-- target-i386/translate.c |7 +++ target-lm32/translate.c |3 +-- target-m68k/translate.c |3 +-- target-microblaze/translate.c |3 +-- target-mips/translate.c |3 +-- target-ppc/translate.c|3 +-- target-s390x/translate.c |3 +-- target-sh4/translate.c|3 +-- target-sparc/translate.c |3 +-- target-unicore32/translate.c |3 +-- translate-all.c |2 +- 15 files changed, 20 insertions(+), 33 deletions(-) diff --git a/exec-all.h b/exec-all.h index 496c001..29fd322 100644 --- a/exec-all.h +++ b/exec-all.h @@ -77,8 +77,8 @@ extern uint16_t gen_opc_icount[OPC_BUF_SIZE]; void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); -void gen_pc_load(CPUState *env, struct TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc); +void restore_state_to_opc(CPUState *env, struct TranslationBlock *tb, + int pc_pos); void cpu_gen_init(void); int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 96e922b..456ba51 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -3367,8 +3367,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) return env; } -void gen_pc_load(CPUState *env, TranslationBlock *tb, -unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->pc = gen_opc_pc[pc_pos]; } diff --git a/target-arm/translate.c b/target-arm/translate.c index 6190028..7e7652e 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -9551,8 +9551,8 @@ static inline void gen_intermediate_code_internal(CPUState *env, * This is handled in the same way as restoration of the * PC in these situations: we will be called again with search_pc=1 * and generate a mapping of the condexec bits for each PC in - * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore - * the condexec bits. + * gen_opc_condexec_bits[]. restore_state_to_opc[] then uses + * this to restore the condexec bits. * * Note that there are no instructions which can read the condexec * bits, and none which can write non-static values to them, so @@ -9817,8 +9817,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, #endif } -void gen_pc_load(CPUState *env, TranslationBlock *tb, -unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->regs[15] = gen_opc_pc[pc_pos]; env->condexec_bits = gen_opc_condexec_bits[pc_pos]; diff --git a/target-cris/translate.c b/target-cris/translate.c index 1c03fa5..e2607d6 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3604,8 +3604,7 @@ void cpu_reset (CPUCRISState *env) #endif } -void gen_pc_load(CPUState *env, struct TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->pc = gen_opc_pc[pc_pos]; } diff --git a/target-i386/translate.c b/target-i386/translate.c index 7d1340e..199302e 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7890,8 +7890,7 @@ void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb) gen_intermediate_code_internal(env, tb, 1); } -void gen_pc_load(CPUState *env, TranslationBlock *tb, -unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { int cc_op; #ifdef DEBUG_DISAS @@ -7903,8 +7902,8 @@ void gen_pc_load(CPUState *env, TranslationBlock *tb, qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]); } } -qemu_log("spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n", -searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs
[Qemu-devel] [PATCH 2/2] Remove unused function parameter from cpu_restore_state
The previous patch removed the need for parameter puc. Is is now unused, so remove it. Cc: Aurelien Jarno Signed-off-by: Stefan Weil --- cpu-exec.c|2 +- exec-all.h|3 +-- exec.c|9 - target-alpha/op_helper.c |2 +- target-arm/op_helper.c|2 +- target-cris/op_helper.c |2 +- target-i386/op_helper.c |2 +- target-lm32/op_helper.c |2 +- target-m68k/op_helper.c |2 +- target-microblaze/op_helper.c |2 +- target-mips/op_helper.c |4 ++-- target-ppc/op_helper.c|2 +- target-s390x/op_helper.c |2 +- target-sh4/op_helper.c|2 +- target-sparc/op_helper.c |2 +- translate-all.c |3 +-- 16 files changed, 20 insertions(+), 23 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 5d6c9a8..293ae10 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -800,7 +800,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ -cpu_restore_state(tb, env, pc, puc); +cpu_restore_state(tb, env, pc); } /* we restore the process signal mask as the sigreturn should diff --git a/exec-all.h b/exec-all.h index 29fd322..7c2d29f 100644 --- a/exec-all.h +++ b/exec-all.h @@ -84,8 +84,7 @@ void cpu_gen_init(void); int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, int *gen_code_size_ptr); int cpu_restore_state(struct TranslationBlock *tb, - CPUState *env, unsigned long searched_pc, - void *puc); + CPUState *env, unsigned long searched_pc); void cpu_resume_from_signal(CPUState *env1, void *puc); void cpu_io_recompile(CPUState *env, void *retaddr); TranslationBlock *tb_gen_code(CPUState *env, diff --git a/exec.c b/exec.c index b1ee52a..c3dc68a 100644 --- a/exec.c +++ b/exec.c @@ -1070,8 +1070,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, restore the CPU state */ current_tb_modified = 1; -cpu_restore_state(current_tb, env, - env->mem_io_pc, NULL); +cpu_restore_state(current_tb, env, env->mem_io_pc); cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, ¤t_flags); } @@ -1179,7 +1178,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr, restore the CPU state */ current_tb_modified = 1; -cpu_restore_state(current_tb, env, pc, puc); +cpu_restore_state(current_tb, env, pc); cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, ¤t_flags); } @@ -3266,7 +3265,7 @@ static void check_watchpoint(int offset, int len_mask, int flags) cpu_abort(env, "check_watchpoint: could not find TB for " "pc=%p", (void *)env->mem_io_pc); } -cpu_restore_state(tb, env, env->mem_io_pc, NULL); +cpu_restore_state(tb, env, env->mem_io_pc); tb_phys_invalidate(tb, -1); if (wp->flags & BP_STOP_BEFORE_ACCESS) { env->exception_index = EXCP_DEBUG; @@ -4301,7 +4300,7 @@ void cpu_io_recompile(CPUState *env, void *retaddr) retaddr); } n = env->icount_decr.u16.low + tb->icount; -cpu_restore_state(tb, env, (unsigned long)retaddr, NULL); +cpu_restore_state(tb, env, (unsigned long)retaddr); /* Calculate how many instructions had been executed before the fault occurred. */ n = n - env->icount_decr.u16.low; diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index 6c2ae20..afa3afb 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -1373,7 +1373,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (likely(tb)) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ -cpu_restore_state(tb, env, pc, NULL); +cpu_restore_state(tb, env, pc); } } /* Exception index and error code are already set */ diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 3de2610..ee7997b 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -90,7 +90,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ -cpu_restore_state(tb, env, pc, NULL); +cpu_restore_state(tb, env, pc); }
Re: [Qemu-devel] [PULL] Migration of misc devices
Anthony Liguori wrote: > On 04/17/2011 03:08 PM, Juan Quintela wrote: >> >> >> The following changes since commit a0102082de4026833afbd2525e8a6320d1f92885: >> >> usb: fix spelling errors in usb-linux.c (2011-04-16 12:24:28 +0100) >> >> are available in the git repository at: >> git://repo.or.cz/qemu/quintela.git vmstate-misc-devices-v2 > > Migration appears to be broken for me. It's not caused by this series > but I'm surprised you didn't encounter it. Maybe it's my kernel version? > > My suspicion is that the cause of this is: > > commit 0ec329dab938e2d97d12a91f8ed15fec27b325e0 > Author: Jan Kiszka > Date: Mon Feb 7 12:19:26 2011 +0100 > > kvm: x86: Introduce kvmclock device to save/restore its state GPE is broken. see Isazu & Avi comments. It worked for me with Sunday tree, will retry now. Later, Juan.
Re: [Qemu-devel] [PATCH 1/2] Remove unused function parameters from gen_pc_load and rename the function
On 18 April 2011 17:39, Stefan Weil wrote: > Function gen_pc_load was introduced in commit > d2856f1ad4c259e5766847c49acbb4e390731bd4. > The only reason for parameter searched_pc was > a debug statement in target-i386/translate.c. > > Parameter puc was needed by target-sparc until > commit d2856f1ad4c259e5766847c49acbb4e390731bd4. Don't you mean d7da2a10402f1644128b66414ca8f86bdea9ae7c ? > diff --git a/target-arm/translate.c b/target-arm/translate.c > index 6190028..7e7652e 100644 > --- a/target-arm/translate.c > +++ b/target-arm/translate.c > @@ -9551,8 +9551,8 @@ static inline void > gen_intermediate_code_internal(CPUState *env, > * This is handled in the same way as restoration of the > * PC in these situations: we will be called again with search_pc=1 > * and generate a mapping of the condexec bits for each PC in > - * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore > - * the condexec bits. > + * gen_opc_condexec_bits[]. restore_state_to_opc[] then uses > + * this to restore the condexec bits. If you have to do another round of this patch then you could make that say "restore_state_to_opc()" (round brackets rather than square), but it's not worth doing a fresh round just to fix an existing typo. Reviewed-by: Peter Maydell -- PMM
Re: [Qemu-devel] [PATCH v2 0/3] pc-bios: Use iPXE ROMs
On Mon, 2011-04-11 at 13:57 -0600, Alex Williamson wrote: > On Mon, 2011-04-11 at 14:48 -0500, Anthony Liguori wrote: > > On 04/11/2011 02:35 PM, Alex Williamson wrote: > > > This series replaces our current gPXE based PXE ROMs with iPXE > > > versions from the iPXE project (http://ipxe.org). This version > > > adds ipxe to our submodules so it can be easily included in > > > releases. I'm still including a script for updating these, > > > perhaps someone better with Makefiles can eventually adopt this > > > to a build target. > > > > > > This email series is mainly for reference, there's too much > > > renaming and replacing binary files to send out to the mailing > > > list. I'll strip out the binaries here so the rest can be > > > reviewed. For the real code, please pull: > > > > > > git://github.com/awilliam/qemu.git (ipxe branch) > > > > > > Thanks to Anthony for already setting up an ipxe mirror. > > > Thanks, > > > > Looks good to me. How different is this from what we've been shipping? > > Have you tested PXE boot from the builtin TFTP server and from an > > external one (like dnsmasq)? > > We were shipping v0.9.9, which was tagged 10/2009. There's been a gpxe > v1.0.0 release since then, plus the split between ipxe and gpxe. I > think Michael is hoping to have a release soon, but the code feels > pretty stable to me as is. > > I've tested external booting from dhcp/tftp server for all the NICs. > I'll make a pass through testing with the builtin server and report > back. Thanks, Ping, any reason this isn't going in? Testing passed, I updated the script to use bash and alphabetized the Makefile per Stefan Weil's suggestions. These are updated in the above github tree. Let me know. Thanks, Alex
Re: [Qemu-devel] [PATCH 2/2] Remove unused function parameter from cpu_restore_state
On 18 April 2011 17:39, Stefan Weil wrote: > The previous patch removed the need for parameter puc. > Is is now unused, so remove it. Reviewed-by: Peter Maydell -- PMM
[Qemu-devel] [PATCH 0/6] linux-user: pending patches
Apart from the last patch, all patches have been seen on the list. If no problems are found in reviews, I'll send these as the next pull request. Changes can also be pulled by git from: git://gitorious.org/qemu-maemo/qemu.git linux-user-for-upstream notice that linux-user git will move soon to some other location. Alexander Graf (1): linux-user: add s390x to llseek list Laurent Vivier (3): linux-user: improve traces linux-user: convert ioctl(SIOCGIFCONF, ...) result. linux-user: add ioctl(SIOCGIWNAME, ...) support. Riku Voipio (2): [v2] linux-user: bigger default stack linux-user: untie syscalls from UID16 linux-user/alpha/syscall_nr.h |7 -- linux-user/ioctls.h |4 +- linux-user/strace.c | 161 + linux-user/strace.list| 12 ++-- linux-user/syscall.c | 154 +++ linux-user/syscall_defs.h |8 ++- 6 files changed, 315 insertions(+), 31 deletions(-)
[Qemu-devel] [PATCH 2/6] linux-user: improve traces
From: Laurent Vivier Add trace details for getpid(), kill(), _llseek(), rt_sigaction(), rt_sigprocmask(), clone(). Signed-off-by: Laurent Vivier Signed-off-by: Riku Voipio --- linux-user/strace.c| 161 linux-user/strace.list | 12 ++-- 2 files changed, 167 insertions(+), 6 deletions(-) diff --git a/linux-user/strace.c b/linux-user/strace.c index 8dd398b..5d9bb08 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "qemu.h" int do_strace=0; @@ -63,6 +64,7 @@ UNUSED static void print_string(abi_long, int); UNUSED static void print_raw_param(const char *, abi_long, int); UNUSED static void print_timeval(abi_ulong, int); UNUSED static void print_number(abi_long, int); +UNUSED static void print_signal(abi_ulong, int); /* * Utility functions @@ -117,6 +119,37 @@ if( cmd == val ) { \ gemu_log("%d",cmd); } +static void +print_signal(abi_ulong arg, int last) +{ +const char *signal_name = NULL; +switch(arg) { +case TARGET_SIGHUP: signal_name = "SIGHUP"; break; +case TARGET_SIGINT: signal_name = "SIGINT"; break; +case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break; +case TARGET_SIGILL: signal_name = "SIGILL"; break; +case TARGET_SIGABRT: signal_name = "SIGABRT"; break; +case TARGET_SIGFPE: signal_name = "SIGFPE"; break; +case TARGET_SIGKILL: signal_name = "SIGKILL"; break; +case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break; +case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break; +case TARGET_SIGALRM: signal_name = "SIGALRM"; break; +case TARGET_SIGTERM: signal_name = "SIGTERM"; break; +case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break; +case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break; +case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break; +case TARGET_SIGCONT: signal_name = "SIGCONT"; break; +case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break; +case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break; +case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break; +} +if (signal_name == NULL) { +print_raw_param("%ld", arg, 1); +return; +} +gemu_log("%s%s", signal_name, get_comma(last)); +} + #ifdef TARGET_NR__newselect static void print_fdset(int n, abi_ulong target_fds_addr) @@ -427,6 +460,32 @@ UNUSED static struct flags fcntl_flags[] = { FLAG_END, }; +UNUSED static struct flags clone_flags[] = { +FLAG_GENERIC(CLONE_VM), +FLAG_GENERIC(CLONE_FS), +FLAG_GENERIC(CLONE_FILES), +FLAG_GENERIC(CLONE_SIGHAND), +FLAG_GENERIC(CLONE_PTRACE), +FLAG_GENERIC(CLONE_VFORK), +FLAG_GENERIC(CLONE_PARENT), +FLAG_GENERIC(CLONE_THREAD), +FLAG_GENERIC(CLONE_NEWNS), +FLAG_GENERIC(CLONE_SYSVSEM), +FLAG_GENERIC(CLONE_SETTLS), +FLAG_GENERIC(CLONE_PARENT_SETTID), +FLAG_GENERIC(CLONE_CHILD_CLEARTID), +FLAG_GENERIC(CLONE_DETACHED), +FLAG_GENERIC(CLONE_UNTRACED), +FLAG_GENERIC(CLONE_CHILD_SETTID), +FLAG_GENERIC(CLONE_NEWUTS), +FLAG_GENERIC(CLONE_NEWIPC), +FLAG_GENERIC(CLONE_NEWUSER), +FLAG_GENERIC(CLONE_NEWPID), +FLAG_GENERIC(CLONE_NEWNET), +FLAG_GENERIC(CLONE_IO), +FLAG_END, +}; + /* * print_xxx utility functions. These are used to print syscall * parameters in certain format. All of these have parameter @@ -669,6 +728,39 @@ print_chmod(const struct syscallname *name, } #endif +#ifdef TARGET_NR_clone +static void +print_clone(const struct syscallname *name, +abi_long arg0, abi_long arg1, abi_long arg2, +abi_long arg3, abi_long arg4, abi_long arg5) +{ +print_syscall_prologue(name); +#if defined(TARGET_M68K) +print_flags(clone_flags, arg0, 0); +print_raw_param("newsp=0x" TARGET_ABI_FMT_lx, arg1, 1); +#elif defined(TARGET_SH4) || defined(TARGET_ALPHA) +print_flags(clone_flags, arg0, 0); +print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0); +print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0); +print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg3, 0); +print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg4, 1); +#elif defined(TARGET_CRIS) +print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg0, 0); +print_flags(clone_flags, arg1, 0); +print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0); +print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0); +print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1); +#else +print_flags(clone_flags, arg0, 0); +print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0); +print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0); +print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0); +print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1); +#endif +print_syscall_epilogue(name); +} +#endif + #ifdef TARGET_NR_creat static void print_creat(const struct syscallname *name, @@ -805,6 +897,28 @@ print_linkat(const struct s
[Qemu-devel] [PATCH 1/6] [v2] linux-user: bigger default stack
From: Riku Voipio PTHREAD_STACK_MIN (16KB) is somewhat inadequate for a new stack for new QEMU threads. Set new limit to 256K which should be enough, yet doesn't increase memory pressure significantly. Signed-off-by: Riku Voipio Reviewed-by: Nathan Froyd --- linux-user/syscall.c |7 ++- 1 files changed, 2 insertions(+), 5 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index bb0999d..732f71a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3690,9 +3690,9 @@ static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr) #endif /* defined(TARGET_I386) */ -#if defined(CONFIG_USE_NPTL) +#define NEW_STACK_SIZE 0x4 -#define NEW_STACK_SIZE PTHREAD_STACK_MIN +#if defined(CONFIG_USE_NPTL) static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER; typedef struct { @@ -3736,9 +3736,6 @@ static void *clone_func(void *arg) return NULL; } #else -/* this stack is the equivalent of the kernel stack associated with a - thread/process */ -#define NEW_STACK_SIZE 8192 static int clone_func(void *arg) { -- 1.7.1
[Qemu-devel] [PATCH 4/6] linux-user: add ioctl(SIOCGIWNAME, ...) support.
From: Laurent Vivier Allow to run properly following program from linux-user: /* cc -o wifi wifi.c */ #include #include #include #include #include #include #include #include int main(int argc, char **argv) { int ret; struct ifreq req; struct sockaddr_in *addr; int s; if (argc != 2) { fprintf(stderr, "Need an interface name (like wlan0)\n"); return 1; } s = socket( AF_INET, SOCK_DGRAM, 0 ); if (s < 0) { perror("Cannot open socket"); return 1; } strncpy(req.ifr_name, argv[1], sizeof(req.ifr_name)); ret = ioctl( s, SIOCGIWNAME, &req ); if (ret < 0) { fprintf(stderr, "No wireless extension\n"); return 1; } printf("%s\n", req.ifr_name); printf("%s\n", req.ifr_newname); return 0; } $ ./wifi eth0 No wireless extension $ ./wifi wlan0 wlan0 IEEE 802.11bg Signed-off-by: Laurent Vivier Signed-off-by: Riku Voipio --- linux-user/ioctls.h |1 + linux-user/syscall.c |2 +- linux-user/syscall_defs.h |3 +++ 3 files changed, 5 insertions(+), 1 deletions(-) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index ab15b86..42b3ae3 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -122,6 +122,7 @@ IOCTL(SIOCDRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq))) + IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq))) IOCTL(CDROMPAUSE, 0, TYPE_NULL) IOCTL(CDROMSTART, 0, TYPE_NULL) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 123909f..5f9061d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -59,7 +59,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, //#include #include #include -#include +#include #include #ifdef TARGET_GPROF #include diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index bde8921..527f31d 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -765,6 +765,9 @@ struct target_pollfd { #define TARGET_SIOCADDDLCI 0x8980 /* Create new DLCI device */ #define TARGET_SIOCDELDLCI 0x8981 /* Delete DLCI device */ +/* From */ + +#define TARGET_SIOCGIWNAME 0x8B01 /* get name == wireless protocol */ /* From */ -- 1.7.1
[Qemu-devel] [PATCH 5/6] linux-user: add s390x to llseek list
From: Alexander Graf We keep a list of host architectures that do llseek with the same syscall as lseek. S390x is one of them, so let's add it to the list. Original-patch-by: Ulrich Hecht Signed-off-by: Alexander Graf Signed-off-by: Riku Voipio --- linux-user/syscall.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5f9061d..e7af2ea 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -197,7 +197,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ #define __NR_sys_inotify_add_watch __NR_inotify_add_watch #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch -#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) +#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \ +defined(__s390x__) #define __NR__llseek __NR_lseek #endif -- 1.7.1
[Qemu-devel] [PATCH 3/6] linux-user: convert ioctl(SIOCGIFCONF, ...) result.
From: Laurent Vivier The result needs to be converted as it is stored in an array of struct ifreq and sizeof(struct ifreq) differs according to target and host alignment rules. This patch allows to execute correctly the following program on arm and m68k: #include #include #include #include #include #include #include #include int main(void) { int s, ret; struct ifconf ifc; int i; memset( &ifc, 0, sizeof( struct ifconf ) ); ifc.ifc_len = 8 * sizeof(struct ifreq); ifc.ifc_buf = alloca(ifc.ifc_len); s = socket( AF_INET, SOCK_DGRAM, 0 ); if (s < 0) { perror("Cannot open socket"); return 1; } ret = ioctl( s, SIOCGIFCONF, &ifc ); if (s < 0) { perror("ioctl() failed"); return 1; } for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq) ; i ++) { struct sockaddr_in *s; s = (struct sockaddr_in*)&ifc.ifc_req[i].ifr_addr; printf("%s\n", ifc.ifc_req[i].ifr_name); printf("%s\n", inet_ntoa(s->sin_addr)); } } Signed-off-by: Laurent Vivier Signed-off-by: Riku Voipio --- linux-user/ioctls.h |3 +- linux-user/syscall.c | 96 +- 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 526aaa2..ab15b86 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -112,7 +112,8 @@ IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) IOCTL(SIOCSIFLINK, 0, TYPE_NULL) - IOCTL(SIOCGIFCONF, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifconf))) + IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf, +MK_PTR(MK_STRUCT(STRUCT_ifconf))) IOCTL(SIOCGIFENCAP, IOC_RW, MK_PTR(TYPE_INT)) IOCTL(SIOCSIFENCAP, IOC_W, MK_PTR(TYPE_INT)) IOCTL(SIOCDARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 732f71a..123909f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -59,6 +59,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, //#include #include #include +#include #include #ifdef TARGET_GPROF #include @@ -2970,7 +2971,6 @@ static abi_long do_ipc(unsigned int call, int first, #endif /* kernel structure types definitions */ -#define IFNAMSIZ16 #define STRUCT(name, ...) STRUCT_ ## name, #define STRUCT_SPECIAL(name) STRUCT_ ## name, @@ -3095,6 +3095,100 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp, } #endif +static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, +int fd, abi_long cmd, abi_long arg) +{ +const argtype *arg_type = ie->arg_type; +int target_size; +void *argptr; +int ret; +struct ifconf *host_ifconf; +uint32_t outbufsz; +const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) }; +int target_ifreq_size; +int nb_ifreq; +int free_buf = 0; +int i; +int target_ifc_len; +abi_long target_ifc_buf; +int host_ifc_len; +char *host_ifc_buf; + +assert(arg_type[0] == TYPE_PTR); +assert(ie->access == IOC_RW); + +arg_type++; +target_size = thunk_type_size(arg_type, 0); + +argptr = lock_user(VERIFY_READ, arg, target_size, 1); +if (!argptr) +return -TARGET_EFAULT; +thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); +unlock_user(argptr, arg, 0); + +host_ifconf = (struct ifconf *)(unsigned long)buf_temp; +target_ifc_len = host_ifconf->ifc_len; +target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf; + +target_ifreq_size = thunk_type_size(ifreq_arg_type, 0); +nb_ifreq = target_ifc_len / target_ifreq_size; +host_ifc_len = nb_ifreq * sizeof(struct ifreq); + +outbufsz = sizeof(*host_ifconf) + host_ifc_len; +if (outbufsz > MAX_STRUCT_SIZE) { +/* We can't fit all the extents into the fixed size buffer. + * Allocate one that is large enough and use it instead. + */ +host_ifconf = malloc(outbufsz); +if (!host_ifconf) { +return -TARGET_ENOMEM; +} +memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf)); +free_buf = 1; +} +host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf); + +host_ifconf->ifc_len = host_ifc_len; +host_ifconf->ifc_buf = host_ifc_buf; + +ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf)); +if (!is_error(ret)) { + /* convert host ifc_len to target ifc_len */ + +nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq); +target_ifc_len = nb_ifreq * target_ifreq_size; +host_ifconf->ifc_len = target_ifc_len; + + /* restore target ifc_buf */ + +host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf; + + /* copy struct ifconf to target user */ + +argptr = lock_user(VERIFY_WRITE, ar
[Qemu-devel] [PATCH 6/6] linux-user: untie syscalls from UID16
Quite a number of uid/gid related syscalls are only defined on systems with USE_UID16 defined. This is apperently based on the idea that these system calls would never be called on non-UID16 systems. Make these syscalls available for all architectures that define them. drop alpha hack to support selected UID16 syscalls. MIPS and PowerPC were also defined as UID16, to get uid/gid syscalls available, drop this error as well. Change QEMU to reflect this. Cc: Ulrich Hecht Cc: Richard Henderson Cc: Alexander Graf Signed-off-by: Riku Voipio --- linux-user/alpha/syscall_nr.h |7 -- linux-user/syscall.c | 48 +--- linux-user/syscall_defs.h |5 +++- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h index 7182223..e3127df 100644 --- a/linux-user/alpha/syscall_nr.h +++ b/linux-user/alpha/syscall_nr.h @@ -412,10 +412,3 @@ #define TARGET_NR_timerfd 477 #define TARGET_NR_eventfd 478 -/* The following aliases are defined in order to match up with the - standard i386 syscalls implemented in syscalls.c. */ -#define TARGET_NR_chown32 TARGET_NR_chown -#define TARGET_NR_setuid32 TARGET_NR_setuid -#define TARGET_NR_setgid32 TARGET_NR_setgid -#define TARGET_NR_setfsuid32 TARGET_NR_setfsuid -#define TARGET_NR_setfsgid32 TARGET_NR_setfsgid diff --git a/linux-user/syscall.c b/linux-user/syscall.c index e7af2ea..e969d1b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -328,7 +328,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode) return (fchmodat(dirfd, pathname, mode, 0)); } #endif -#if defined(TARGET_NR_fchownat) && defined(USE_UID16) +#if defined(TARGET_NR_fchownat) static int sys_fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags) { @@ -437,7 +437,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode) #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode) #endif -#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16) +#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname, uid_t,owner,gid_t,group,int,flags) #endif @@ -4164,7 +4164,31 @@ static inline int low2highgid(int gid) else return gid; } - +static inline int tswapid(int id) +{ +return tswap16(id); +} +#else /* !USE_UID16 */ +static inline int high2lowuid(int uid) +{ +return uid; +} +static inline int high2lowgid(int gid) +{ +return gid; +} +static inline int low2highuid(int uid) +{ +return uid; +} +static inline int low2highgid(int gid) +{ +return gid; +} +static inline int tswapid(int id) +{ +return tswap32(id); +} #endif /* USE_UID16 */ void syscall_init(void) @@ -6765,25 +6789,32 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = host_to_target_stat64(cpu_env, arg3, &st); break; #endif -#ifdef USE_UID16 case TARGET_NR_lchown: if (!(p = lock_user_string(arg1))) goto efault; ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3))); unlock_user(p, arg1, 0); break; +#ifdef TARGET_NR_getuid case TARGET_NR_getuid: ret = get_errno(high2lowuid(getuid())); break; +#endif +#ifdef TARGET_NR_getgid case TARGET_NR_getgid: ret = get_errno(high2lowgid(getgid())); break; +#endif +#ifdef TARGET_NR_geteuid case TARGET_NR_geteuid: ret = get_errno(high2lowuid(geteuid())); break; +#endif +#ifdef TARGET_NR_getegid case TARGET_NR_getegid: ret = get_errno(high2lowgid(getegid())); break; +#endif case TARGET_NR_setreuid: ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2))); break; @@ -6793,7 +6824,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_getgroups: { int gidsetsize = arg1; -uint16_t *target_grouplist; +target_id *target_grouplist; gid_t *grouplist; int i; @@ -6806,7 +6837,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (!target_grouplist) goto efault; for(i = 0;i < ret; i++) -target_grouplist[i] = tswap16(grouplist[i]); +target_grouplist[i] = tswapid(high2lowgid(grouplist[i])); unlock_user(target_grouplist, arg2, gidsetsize * 2); } } @@ -6814,7 +6845,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_setgroups: { int gidsetsize = arg1; -uint16_t *target_grouplist; +target_id *target_grouplist;
Re: [Qemu-devel] [PATCH v2 0/3] pc-bios: Use iPXE ROMs
On 04/18/2011 12:25 PM, Alex Williamson wrote: > On Mon, 2011-04-11 at 13:57 -0600, Alex Williamson wrote: >> On Mon, 2011-04-11 at 14:48 -0500, Anthony Liguori wrote: >>> On 04/11/2011 02:35 PM, Alex Williamson wrote: This series replaces our current gPXE based PXE ROMs with iPXE versions from the iPXE project (http://ipxe.org). This version adds ipxe to our submodules so it can be easily included in releases. I'm still including a script for updating these, perhaps someone better with Makefiles can eventually adopt this to a build target. This email series is mainly for reference, there's too much renaming and replacing binary files to send out to the mailing list. I'll strip out the binaries here so the rest can be reviewed. For the real code, please pull: git://github.com/awilliam/qemu.git (ipxe branch) Thanks to Anthony for already setting up an ipxe mirror. Thanks, >>> >>> Looks good to me. How different is this from what we've been shipping? >>> Have you tested PXE boot from the builtin TFTP server and from an >>> external one (like dnsmasq)? >> >> We were shipping v0.9.9, which was tagged 10/2009. There's been a gpxe >> v1.0.0 release since then, plus the split between ipxe and gpxe. I >> think Michael is hoping to have a release soon, but the code feels >> pretty stable to me as is. >> >> I've tested external booting from dhcp/tftp server for all the NICs. >> I'll make a pass through testing with the builtin server and report >> back. Thanks, > > Ping, any reason this isn't going in? Testing passed, I updated the > script to use bash and alphabetized the Makefile per Stefan Weil's > suggestions. These are updated in the above github tree. Let me know. > Thanks, I actually was just testing the github tree. Unfortunately, it looks like there's something broken. You renamed all of the pxe roms to end with .bin but Makefile still refers to everything as .rom. This makes make install break along with building from a separate build directory. Regards, Anthony Liguori > > Alex >