[Qemu-devel] [PATCH v2 1/6] fix some debug printf format strings
These are normally ifdefed out and don't matter. But if you enable them, they ought to be correct. Signed-off-by: Matthew Ogilvie mmogilvi_q...@miniinfo.net --- This version of the patch adds i8259.c. An alternative approach might be to eliminate these printf's, and/or replace them with trace*() calls, but until someone gets around to doing so... hw/cirrus_vga.c | 4 ++-- hw/i8259.c | 3 ++- hw/ide/cmd646.c | 5 +++-- hw/ide/via.c| 5 +++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index e8dcc6b..909899d 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2055,8 +2055,8 @@ static void cirrus_vga_mem_write(void *opaque, } } else { #ifdef DEBUG_CIRRUS -printf(cirrus: mem_writeb TARGET_FMT_plx value %02x\n, addr, - mem_value); +printf(cirrus: mem_writeb TARGET_FMT_plx value % PRIx64 \n, + addr, mem_value); #endif } } diff --git a/hw/i8259.c b/hw/i8259.c index 53daf78..6587666 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -355,7 +355,8 @@ static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr, ret = s-imr; } } -DPRINTF(read: addr=0x%02x val=0x%02x\n, addr, ret); +DPRINTF(read: addr=0x%02 TARGET_PRIxPHYS val=0x%02x\n, +addr, ret); return ret; } diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index e0b9443..dd2855e 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -154,7 +154,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, break; } #ifdef DEBUG_IDE -printf(bmdma: readb 0x%02x : 0x%02x\n, addr, val); +printf(bmdma: readb 0x%02 TARGET_PRIxPHYS : 0x%02x\n, addr, val); #endif return val; } @@ -170,7 +170,8 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE -printf(bmdma: writeb 0x%02x : 0x%02x\n, addr, val); +printf(bmdma: writeb 0x%02 TARGET_PRIxPHYS : 0x%02 PRIx64 \n, + addr, val); #endif switch(addr 3) { case 0: diff --git a/hw/ide/via.c b/hw/ide/via.c index b20e4f0..948a469 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -55,7 +55,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, break; } #ifdef DEBUG_IDE -printf(bmdma: readb 0x%02x : 0x%02x\n, addr, val); +printf(bmdma: readb 0x%02 TARGET_PRIxPHYS : 0x%02x\n, addr, val); #endif return val; } @@ -70,7 +70,8 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE -printf(bmdma: writeb 0x%02x : 0x%02x\n, addr, val); +printf(bmdma: writeb 0x%02 TARGET_PRIxPHYS : 0x%02 PRIx64 \n, + addr, val); #endif switch (addr 3) { case 0: -- 1.7.10.2.484.gcd07cc5
[Qemu-devel] [PATCH v2 0/6] Running Microport UNIX (ca 1987)
After applying this version 2 of this patch series, I can successfully run Micoport UNIX System V/386, v 2.1 (ca 1987) under qemu. (although not if I try to enable KVM) Version 1 of this series was posted about 4 weeks ago. See http://patchwork.ozlabs.org/project/qemu-devel/list/?submitter=15654 The patches are all independent, except that the documentation part of patch 5 (vga) adds onto patch 4 (retrace=) changes. Patches 2 (mov crN), 5 (vga/cga), and 6 (spurious interrupts) are required to run this UNIX. The other three patches are trivial improvements I noticed while tracking down the main issues. The first four patches are probably trivially obvious. The last two patches might be a little controversial, since they add hacks to work around what could be argued are operating system bugs. But I've tried to make them minimal impact (leave them disabled by default, isolate relevant code in minimal number of places, etc), and tried to implement and describe them so that they might be useful for other old OS's and programs besides my old version of UNIX. == Just for reference, in case someone else wants to debug similar issues with other operating systems, here are some notes about running and debugging this UNIX system under qemu: - This version of UNIX seems to hard code the number of tracks per cylinder for the hard drive to 17. So build your drive image with that in mind, and tell qemu to use 17 tracks per cylinder. - This version of UNIX seems to think it doesn't have any RAM unless I configure the virtual machine with 17MB or less RAM. I've mostly been reducing that to 15 while debugging other issues, just to eliminate any possible problems at 16. Someday I'll try 17 again. - I use a command line similar to the following (from a shell script): qemu-system-i386 -monitor stdio -m 15 -hdachs 977,5,17 -hda $diskC \ -drive file=$installDisk,if=floppy,snapshot=on -no-fd-bootchk \ -vga std,cga_hacks=palette_blanking+font_height \ -no-spurious-interrupt-hack - -no-shutdown and -no-reboot were also handy for tracking some of the early bootup issues (mov crN patch). - Without my cga hacks patch, you can get a snapshot of the screen by running pmemsave 0xb8000 0x8000 screenDump.out in the monitor, and then examining every other byte of screenDump.out externally. - Other tools: - I can mount the first install floppy in Linux if I skip the first track: mount -t sysv -r -o loop,offset=15K $installDisk /mnt/misc - I can also mount the UNIX hard drive in Linux, but I don't know a good way to find the correct offset. UNIX seems to use it's own partition scheme within a DOS-style partition, so it doesn't work to just use the offset of the (DOS) partition. kpartx and pvscan sounded promising, but only seem to find DOS partitions. Perhaps reboot with the max_part option on a kernel configured with the correct partitioning scheme enabled? I found the offset by brute force trying every sector on the the above hard disk. The actual number likely depends on a lot of things. mount -t sysv -r -o loop,offset=5178880 $diskC /mnt/misc - GNU objdump can dissassemble the kernel with something like objdump -s -d $MOUNTPOINT/unix from Linux, including function names but not much else. But objdump needs to be configured with something like: ./configure -enable-target=i386-foobar-coff - gdb can recognize function names from UNIX kernel if configured with something like ./configure -target=i386-foobar-coff. Use qemu's -s option, run gdb $MOUNTPOINT/unix, and issue the gdb command target remote:1234. After the floppy boots (kernel loaded in RAM), but before it accesses the hard disk, I could set breakpoints early in panic like break splintpanic2. I could examine registers (info registers or info all-registers) and memory, but the call stack tended to be truncated early. == Matthew Ogilvie (6): fix some debug printf format strings target-i386/translate.c: mov to/from crN/drN: ignore mod bits vl: fix -hdachs/-hda argument order parsing issues qemu-options.hx: mention retrace= VGA option vga: add some optional CGA compatibility hacks i8259: add -no-spurious-interrupt-hack option cpu-exec.c | 12 + hw/cirrus_vga.c | 4 +-- hw/i8259.c | 21 +++- hw/ide/cmd646.c | 5 ++-- hw/ide/via.c| 5 ++-- hw/pc.h | 4 +++ hw/vga.c| 39 +++-- qemu-options.hx | 38 +++- sysemu.h| 1 + target-i386/translate.c | 14 --- vl.c| 66 + 11 files changed, 163 insertions(+), 46 deletions(-) -- 1.7.10.2.484.gcd07cc5
[Qemu-devel] [PATCH v2 6/6] i8259: add -no-spurious-interrupt-hack option
This patch provides a way to optionally suppress spurious interrupts, as a workaround for systems described below: Some old operating systems do not handle spurious interrupts well, and qemu tends to generate them significantly more often than real hardware. Examples: - Microport UNIX System V/386 v 2.1 (ca 1987) (The main problem I'm fixing: Without this patch, it panics sporadically when accessing the hard disk.) - ATT UNIX System V/386 Release 4.0 Version 2.1a (ca 1991) See screenshot in QEMU Official OS Support List: http://www.claunia.com/qemu/objectManager.php?sClass=applicationiId=9 (I don't have this system to test.) - A report about OS/2 boot lockup from 2004 by Hampa Hug: http://lists.nongnu.org/archive/html/qemu-devel/2004-09/msg00367.html (My patch was partially inspired by his.) Also: http://lists.nongnu.org/archive/html/qemu-devel/2005-06/msg00243.html (I don't have this system to test.) Signed-off-by: Matthew Ogilvie mmogilvi_q...@miniinfo.net --- Note: checkpatches.pl gives an error about initializing the global int no_spurious_interrupt_hack = 0;, even though existing lines near it are doing the same thing. Should I give precedence to checkpatches.pl, or nearby code? There was no version 1 of this patch; this was the last thing I had to work around to get UNIX running. High level symptoms: 1. Despite using this UNIX system for nearly 10 years (ca 1987-1996) on an early 80386, I don't remember ever seeing any crash like this. I vaguely remember I may have had one or two crashes for which I don't have other explanations that perhaps could have been this, but I don't remember the error messages to confirm it. 2. It is somewhat random when UNIX crashes when running in qemu. - Sometimes it crashes the first time the floppy-based installer tries to access the hard disk (partition table?). - Other times (though fairly rarely), it actually finishes formatting and copying the first disk's files to the hard disk without crashing. - On the other hand, I've never seen it successfully boot from the hard disk without this patch. An attempt to boot from the hard drive always panics quite early. 3. I tried -win2k-hack instead, thinking maybe the hard disk is just responding faster than UNIX expected. But it doesn't seem to have any effect. UNIX still panics sporadically the same way. - TANGENT: I was going to see if my patch provides an alternative fix for installing Windows 2000, but I was unable to reproduce the original -win2k-hack problem at all (with neither -win2k-hack NOR this patch). Maybe some other change has fixed it some other way? Or maybe it is only an issue in configurations I didn't test? (KVM instead of TCG? Less RAM? Something else?) It might be worth doing a little more investigation, and eliminating the -win2k-hack option if appropriate. 4. If I enable KVM, I get a different error very early in bootup (in splx function instead of splint), and this patch doesn't help. My low level analysis of what is going on: It is hard to track down all the details, but based on logging a lot of qemu IRQ stuff, and setting a breakpoint in the earliest panic-related UNIX function using gdb, it looks like: 1. It is near the end of servicing a previous IRQ14 from the hard disk. 2. The processor has interrupts disabled (I think), while UNIX clears the slave 8259's IMR (mask) register (sets it to 0), allowing all interrupts to be passed on to the master. 3. While in that state, IRQ14 is raised (on the slave), which gets propagated to the master (IRQ2), but the CPU is not interrupted yet. 4. UNIX then masks the slave 8259's IMR register completely (sets to 0xff). 5. Because the master elcr register is set (by BIOS; UNIX never touches it) to edge trigger for IRQ2, the master latched on to IRQ2 earlier, and continues to assert the processors INT line (the env-interrupt_requestCPU_INTERRUPT_HARD bit) even after all slave IRQs have been masked off (clearing the input IRQ2). 6. Finally, UNIX enables CPU interrupts and the interrupt is delivered to the CPU, which ends up as a spurious IRQ15 due to the slave's imr register. UNIX doesn't know what to do with that, and panics/halts. I'm not sure why it only sporadically hits this sequence of events. There doesn't seem to be other IRQs asserted or serviced anywhere in the near past; the last several were all IRQ14's. But I can't help feeling I'm not reading the log output correctly or something, because that doesn't make sense. Maybe there is there some kind of a-few-instructions delay before a CPU interrupt is actually deliviered after interrupts are enabled, or some delay in raising
[Qemu-devel] [PATCH v2 3/6] vl: fix -hdachs/-hda argument order parsing issues
Without this patch, the -hdachs argument had to occur either BEFORE the corresponding -hda option, or AFTER the plain disk image name (if neither -hda nor -drive is used). Otherwise it would effectively be ignored. Option -hdachs still has no effect on -drive, but that seems best. Signed-off-by: Matthew Ogilvie mmogilvi_q...@miniinfo.net --- Version 1 of this patch had the confusing subject Re: [Qemu-devel] [PATCH 0/3] Attempting to run Microport UNIX (ca 1987). This version reworks things a little to avoid duplicated code between the -hda and just a file cases, based on Markus Armbruster's comments. An alternative approach would be to just get rid of the -hdachs option, and require the use of -drive for anything that -hda can't handle by itself. vl.c | 39 ++- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/vl.c b/vl.c index 7c577fa..febfd62 100644 --- a/vl.c +++ b/vl.c @@ -2352,8 +2352,9 @@ int main(int argc, char **argv, char **envp) char boot_devices[33] = cad; /* default to HD-floppy-CD-ROM */ DisplayState *ds; DisplayChangeListener *dcl; -int cyls, heads, secs, translation; -QemuOpts *hda_opts = NULL, *opts, *machine_opts; +char hdachs_params[512]; /* save -hdachs to apply to later -hda */ +QemuOpts *hda_opts = NULL; /* save -hda to be modified by later -hdachs */ +QemuOpts *opts, *machine_opts; QemuOptsList *olist; int optind; const char *optarg; @@ -2408,8 +2409,7 @@ int main(int argc, char **argv, char **envp) cpu_model = NULL; ram_size = 0; snapshot = 0; -cyls = heads = secs = 0; -translation = BIOS_ATA_TRANSLATION_AUTO; +snprintf(hdachs_params, sizeof(hdachs_params), %s, HD_OPTS); for (i = 0; i MAX_NODES; i++) { node_mem[i] = 0; @@ -2457,7 +2457,7 @@ int main(int argc, char **argv, char **envp) if (optind = argc) break; if (argv[optind][0] != '-') { - hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS); +hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], hdachs_params); } else { const QEMUOption *popt; @@ -2475,21 +2475,8 @@ int main(int argc, char **argv, char **envp) cpu_model = optarg; break; case QEMU_OPTION_hda: -{ -char buf[256]; -if (cyls == 0) -snprintf(buf, sizeof(buf), %s, HD_OPTS); -else -snprintf(buf, sizeof(buf), - %s,cyls=%d,heads=%d,secs=%d%s, - HD_OPTS , cyls, heads, secs, - translation == BIOS_ATA_TRANSLATION_LBA ? - ,trans=lba : - translation == BIOS_ATA_TRANSLATION_NONE ? - ,trans=none : ); -drive_add(IF_DEFAULT, 0, optarg, buf); -break; -} +hda_opts = drive_add(IF_DEFAULT, 0, optarg, hdachs_params); +break; case QEMU_OPTION_hdb: case QEMU_OPTION_hdc: case QEMU_OPTION_hdd: @@ -2523,7 +2510,10 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_hdachs: { +int cyls, heads, secs, translation; const char *p; +cyls = heads = secs = 0; +translation = BIOS_ATA_TRANSLATION_AUTO; p = optarg; cyls = strtol(p, (char **)p, 0); if (cyls 1 || cyls 16383) @@ -2555,7 +2545,14 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, qemu: invalid physical CHS format\n); exit(1); } - if (hda_opts != NULL) { +snprintf(hdachs_params, sizeof(hdachs_params), + %s,cyls=%d,heads=%d,secs=%d%s, + HD_OPTS , cyls, heads, secs, + translation == BIOS_ATA_TRANSLATION_LBA ? + ,trans=lba : + translation == BIOS_ATA_TRANSLATION_NONE ? + ,trans=none : ); +if (hda_opts != NULL) { char num[16]; snprintf(num, sizeof(num), %d, cyls); qemu_opt_set(hda_opts, cyls, num); -- 1.7.10.2.484.gcd07cc5
[Qemu-devel] unicore32 fails assertion without -kernel (was: How to reliably start a bare QEMU target to query capabilities via QMP)
Daniel P. Berrange berra...@redhat.com writes: I've been adapting libvirt to use to the various new QMP commands to query QEMU's capabilities, instead of the hated -help parsing. Obviously the critical part of this is being able to reliably start a bare QEMU process with no actual guest OS configured (no disks, no kernel, etc) and talk to its monitor. I hadn't anticipated problems since I only tested with x86_64 / i386 most of the time, which work well in this respect. Currently I am doing # $QEMU_BINARY -S \ -no-user-config \ -nodefconfig \ -nodefaults \ -nographic \ -qmp stdio This works for about 50% of the QEMU targets: [...] but fails for the other 50% of targets: [...] With the failing targets i see the following kinds of errors: $ qemu-system-arm -S -nodefconfig -nodefaults -nographic -qmp unix:/tmp/foo,server,nowait Kernel image must be specified [...] $ qemu-system-unicore32 -S -nodefconfig -nodefaults -nographic -qmp unix:/tmp/foo,server,nowait qemu-system-unicore32: /home/berrange/src/virt/qemu/hw/unicore32/../puv3.c:81: puv3_load_kernel: Assertion `kernel_filename != ((void *)0)' failed. Aborted Bug, cc'ing maintainer. It should fail cleanly, like the test case above. A similar bug was recently fixed for armv7m (commit 01fd41ab). [...]
Re: [Qemu-devel] [PATCH 3/6] QAPI: Introduce memchar_write QMP command
On 08/23/2012 01:42 PM, Eric Blake wrote: On 08/22/2012 11:14 PM, Lei Li wrote: Signed-off-by: Lei Li li...@linux.vnet.ibm.com Subject line uses '_', but the QMP command uses '-' [1] --- hmp-commands.hx | 16 hmp.c| 15 +++ hmp.h|1 + qapi-schema.json | 28 qemu-char.c | 36 qmp-commands.hx | 33 + 6 files changed, 129 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index f6104b0..829aea1 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -797,6 +797,22 @@ Inject an NMI on the given CPU (x86 only). ETEXI { +.name = memchar-write, HMP commands should use '_', not '-'. +++ b/qapi-schema.json @@ -235,6 +235,34 @@ ## { 'command': 'query-chardev', 'returns': ['ChardevInfo'] } +{ 'enum': 'DataFormat' + 'data': [ 'utf8', 'base64' ] } Missing documentation for DataFormat (see for example how @ErrorClass is documented). Sure, I will look into it and add documentation in v3, thanks! -- Lei
[Qemu-devel] [PATCH v2 2/6] target-i386/translate.c: mov to/from crN/drN: ignore mod bits
From AMD's documentation (multiple versions of 24594.pdf): This instruction is always treated as a register-to-register (MOD = 11) instruction, regardless of the encoding of the MOD field in the MODR/M byte. Also, Microport UNIX System V/386 v 2.1 (ca 1987) runs fine on real Intel 386 and 486 CPU's (at least), but does not run in qemu without this patch. Signed-off-by: Matthew Ogilvie mmogilvi_q...@miniinfo.net --- This version of the patch tweaks some of the comments to refer to AMD's documentation, based on malc av1...@comtv.ru's response to version 1. It is functionally identical. target-i386/translate.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 7ab2ccb..eb0cabc 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7551,8 +7551,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s-cs_base); } else { modrm = cpu_ldub_code(cpu_single_env, s-pc++); -if ((modrm 0xc0) != 0xc0) -goto illegal_op; +/* Ignore the mod bits (assume (modrm0xc0)==0xc0). + * AMD documentation (24594.pdf) and testing of + * intel 386 and 486 processors all show that the mod bits + * are assumed to be 1's, regardless of actual values. + */ rm = (modrm 7) | REX_B(s); reg = ((modrm 3) 7) | rex_r; if (CODE64(s)) @@ -7594,8 +7597,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s-cs_base); } else { modrm = cpu_ldub_code(cpu_single_env, s-pc++); -if ((modrm 0xc0) != 0xc0) -goto illegal_op; +/* Ignore the mod bits (assume (modrm0xc0)==0xc0). + * AMD documentation (24594.pdf) and testing of + * intel 386 and 486 processors all show that the mod bits + * are assumed to be 1's, regardless of actual values. + */ rm = (modrm 7) | REX_B(s); reg = ((modrm 3) 7) | rex_r; if (CODE64(s)) -- 1.7.10.2.484.gcd07cc5
[Qemu-devel] [PATCH v2 5/6] vga: add some optional CGA compatibility hacks
This patch adds some optional compatibility hacks (default disabled) to allow Microport UNIX to function under qemu. I've tried to structure it to be easy to add more hacks for other old CGA programs, if anyone ever needs them. Microport UNIX System V/386 v 2.1 (ca 1987) tries to program the CGA registers directly with neither the assistance of BIOS, nor with proper handling of EGA/VGA-only registers. Note that it didn't work on real VGA hardware, either (although in that case, the most obvious problems seemed to be out-of-range hsync and/or vsync signalling, rather than the issues in this patch). Eventually real MDA and/or CGA support might provide an alternative to this patch, although a hybrid approach like this patch might still be useful in marginal cases. Signed-off-by: Matthew Ogilvie mmogilvi_q...@miniinfo.net --- Note: checkpatches.pl gives an error about initializing the global int vga_cga_hacks = 0;, even though existing lines near it are doing the same thing. Should I give precedence to checkpatches.pl, or nearby code? Another approach would be to add real MDA and/or CGA support. Perhaps -vga mda and/or -vga cga command line options, and then make a split off hw/mda.c that is much simplified compared to vga.c. Note that even if qemu had a real -vga cga option, something like this patch might still be useful to allow running both old/fragile CGA programs and newer VGA programs in a single virtual machine. One downside of real CGA is the relatively ugly low-res font CGA uses (I think) for text mode, not just graphics mode. Although irrelevant to UNIX, this idea of implementing old graphics cards could be further extended: - -vga hgc (Hercules) support would probably be easy to add to MDA, after MDA was cleanly separated out. - -vga hgc+cga, (or perhaps -vga hgc,secondary=cga, or something else), to support a dual graphics card configurations. I believe the real hardware supported various combinations: (hgc|mda)\+(cga|std|...), (cga|std|...)\+(hgc|mda), cga\+(std|...), and (std|...)\+cga. Also, with a PCI bus, two of the same kind of card may be supported in some cases. In such a configuration, I would expect each graphics card would have it's own display window in the host OS. - Also, in my research about CGA stuff, I noticed that there were a few other old rare cards that appear to be minor variations of CGA and/or MDA (a combination CGA/HGC, a color HGC, a higher-resolution CGA, etc). Once you had a clean plain-CGA implementation, many of these could probably be implemented as optional enable flags fairly easily. Does anyone have any thoughts about the best way of adding MDA, HGC, CGA, or similar old video cards to qemu? hw/pc.h | 4 hw/vga.c| 39 +++ qemu-options.hx | 19 +++ vl.c| 23 +++ 4 files changed, 77 insertions(+), 8 deletions(-) diff --git a/hw/pc.h b/hw/pc.h index e4db071..37e2f87 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -176,6 +176,10 @@ enum vga_retrace_method { extern enum vga_retrace_method vga_retrace_method; +#define VGA_CGA_HACK_PALETTE_BLANKING (10) +#define VGA_CGA_HACK_FONT_HEIGHT (11) +extern int vga_cga_hacks; + static inline DeviceState *isa_vga_init(ISABus *bus) { ISADevice *dev; diff --git a/hw/vga.c b/hw/vga.c index f82ced8..08ec4bd 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -547,14 +547,31 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) printf(vga: write CR%x = 0x%02x\n, s-cr_index, val); #endif /* handle CR0-7 protection */ -if ((s-cr[VGA_CRTC_V_SYNC_END] VGA_CR11_LOCK_CR0_CR7) -s-cr_index = VGA_CRTC_OVERFLOW) { -/* can always write bit 4 of CR7 */ -if (s-cr_index == VGA_CRTC_OVERFLOW) { -s-cr[VGA_CRTC_OVERFLOW] = (s-cr[VGA_CRTC_OVERFLOW] ~0x10) | -(val 0x10); +if (s-cr[VGA_CRTC_V_SYNC_END] VGA_CR11_LOCK_CR0_CR7) { +if (s-cr_index = VGA_CRTC_OVERFLOW) { +/* can always write bit 4 of CR7 */ +if (s-cr_index == VGA_CRTC_OVERFLOW) { +s-cr[VGA_CRTC_OVERFLOW] = +(s-cr[VGA_CRTC_OVERFLOW] ~0x10) | (val 0x10); +} +return; +} else if ((vga_cga_hacks VGA_CGA_HACK_FONT_HEIGHT) + !(s-sr[VGA_SEQ_CLOCK_MODE] VGA_SR01_CHAR_CLK_8DOTS)) { +/* extra CGA compatibility hacks (not in standard VGA) */ +if (s-cr_index == VGA_CRTC_MAX_SCAN +val == 7 +(s-cr[VGA_CRTC_MAX_SCAN] 0xf) == 0xf) { +return; +} else if (s-cr_index == VGA_CRTC_CURSOR_START + val == 6 + (s-cr[VGA_CRTC_MAX_SCAN] 0xf) == 0xf) { +val
[Qemu-devel] [PATCH v2 4/6] qemu-options.hx: mention retrace= VGA option
The feature was added in commit cb5a7aa8c32141bb Sep 2008. My description is based on Better VGA retrace emulation (needed for some DOS games/demos) from http://www.boblycat.org/~malc/code/patches/qemu/index.html Signed-off-by: Matthew Ogilvie mmogilvi_q...@miniinfo.net --- This is the first version of this patch. I noticed this was missing when I wanted to add documentation for my own VGA option in the next patch... === qemu-options.hx | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qemu-options.hx b/qemu-options.hx index 3c411c4..104d228 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -944,7 +944,7 @@ DEF(vga, HAS_ARG, QEMU_OPTION_vga, -vga [std|cirrus|vmware|qxl|xenfb|none]\n select video card type\n, QEMU_ARCH_ALL) STEXI -@item -vga @var{type} +@item -vga @var{type}[,@var{prop}=@var{value}[,...]] @findex -vga Select type of VGA card to emulate. Valid values for @var{type} are @table @option @@ -971,6 +971,12 @@ Recommended choice when using the spice protocol. @item none Disable VGA card. @end table +Valid optional properties are +@table @option +@item retrace=dumb|precise +Select dumb (default) or precise VGA retrace logic, useful for some +DOS games/demos. +@end table ETEXI DEF(full-screen, 0, QEMU_OPTION_full_screen, -- 1.7.10.2.484.gcd07cc5
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH V2 03/17] hvm-pci: Handle PCI config space in Xen
Julien Grall julien.gr...@citrix.com 08/22/12 8:56 PM +int hvm_register_pcidev(domid_t domid, ioservid_t id, +uint8_t domain, uint8_t bus, +uint8_t device, uint8_t function) +{ domain needs to be uint16_t. Also, just to double check: we don't currently expose the option of MMCONFIG to the guest (as otherwise the change would be incomplete)? Jan
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH V2 05/17] hvm: Modify hvm_op
Julien Grall julien.gr...@citrix.com 08/22/12 8:56 PM @@ -4069,20 +4053,12 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg) switch ( a.index ) { -case HVM_PARAM_IOREQ_PFN: Removing sub-ops which a domain can issue for itself (which for this and another one below appears to be the case) is not allowed. +case HVM_PARAM_IO_PFN_FIRST: I don't see where in this patch this and the other new sub-op constants get defined. Jan
Re: [Qemu-devel] [PATCH 4/6] QAPI: Introduce memchar_read QMP command
On 08/23/2012 01:46 PM, Eric Blake wrote: On 08/22/2012 11:14 PM, Lei Li wrote: Signed-off-by: Lei Li li...@linux.vnet.ibm.com Again, subject line should use '-' not '_' for QMP. --- hmp-commands.hx | 16 hmp.c| 15 +++ hmp.h|1 + qapi-schema.json | 23 +++ qemu-char.c | 32 qmp-commands.hx | 31 +++ 6 files changed, 118 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 829aea1..9f61633 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -813,6 +813,22 @@ to memchr char device with size @var{size}. ETEXI { +.name = memchar-read, while the HMP command should use '_' not '-'. +++ b/qapi-schema.json @@ -264,6 +264,29 @@ '*format': 'DataFormat'} } ## +# @memchar-read: +# +# Provide read interface for memchardev. Read from memchar +# char device and return the data. +# +# @chardev: the name of the memchar char device. Why two spaces? +# +# @size: the size to write in bytes. s/write/read/ +# +# @format: #optional the format of the data want to read from +# memchardev, by default is 'utf8'. +# +# Returns: The data read from memchar as string. +# If @chardev is not a valid memchr device, DeviceNotFound +# If an I/O error occurs while reading, IOError +# +# Since: 1.2 1.3 +## +{ 'command': 'memchar-read', + 'data': {'chardev': 'str', 'size': 'int', '*format': 'DataFormat'}, + 'returns': 'str' } While writing can default to UTF-8, I'm worried about reading - does encoding in UTF-8 allow transmission of NUL bytes through JSON, or do you have to use base64 to allow full binary data through? What happens if the data read includes a NUL byte that can't be encoded back into the requested DataFormat? Yes, you are right. g_base64_encode did not support NULL bytes encoding, so encoding in UTF-8 should not allow transmission of NULL bytes through JSON. Thanks for pointing this out! -- Lei
Re: [Qemu-devel] [PATCH V4 1/2] qapi: Add SnapshotInfo and ImageInfo.
That seems backwards - with a raw file, don't you know the actual size, but have no idea what it can further grow to? In raw it commes from fstat() with the field st.st_blocks. from man: blkcnt_t st_blocks; /* number of 512B blocks allocated */ Benoît
Re: [Qemu-devel] [PATCH V4 1/2] qapi: Add SnapshotInfo and ImageInfo.
+## +# @ImageInfo: +# +# Information about a QEMU image file +# +# @filename: name of the image file +# +# @format: format of the image file +# +# @virtual-size: maximum capacity in bytes of the image +# +# @actual-size: #optional actual size on disk in bytes of the image That seems backwards - with a raw file, don't you know the actual size, but have no idea what it can further grow to? Try the current qemy-img info on a raw file you will be surprised of the results. This field also can have an unavailable value. example result with unpatched qemu-img: benoit@Laure:~/qemu$ qemu-img info truc1.raw image: truc1.raw file format: raw virtual size: 1.0G (1073741824 bytes) disk size: 776M disk size is actual-size. Benoît
Re: [Qemu-devel] QEMU version for ARM7 adaptation
On 23 August 2012 04:03, Vinicius Sanches viniciusrsanc...@gmail.com wrote: What is the best QEMU version available to enable ARM7 core? If you want to add a new feature to QEMU you should always work on git master; we don't accept patches against anything else. -- PMM
Re: [Qemu-devel] [PATCH] qom: removal of link property need to release its target
On Thu, Aug 23, 2012 at 12:36 AM, Anthony Liguori anth...@codemonkey.ws wrote: Paolo Bonzini pbonz...@redhat.com writes: Il 22/08/2012 05:02, Liu Ping Fan ha scritto: From: Liu Ping Fan pingf...@linux.vnet.ibm.com Currently, link property's target is only managed by object_set_link_property(). This will raise such issue that when the property is finalized, its target has no opportunity to release. Fix this issue by introduce object_finalize_link_property() Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com Acked-by: Paolo Bonzini pbonz...@redhat.com This patch is correct but it uncovers a bigger problem. Short of reworking most of the hotplug code, I can't find an easy fix. The first problem is that with this patch, all links are unreferenced at property removal. Right now, bus children are added as links but when they are added, the link is already set (there is no explicit set). This means that those links never get the extra reference. We can fix this by adding an extra reference in add_link but this Yeah, I was wondering about why it does not like this creates yet another problem with hotplug. Specificially, qdev_free() asserts that ref 0 because there is now a reference being held by the bus. This is the same problem we have with object_unparent. The key problem here is how unplug is implemented. Unplug wants to be both synchronous and asynchronous. I think we need to do the following: 1) Move object_unparent to qdev_device_del (the parent is added by qdev_device_add so this is quite logical). 2) Make DeviceState::unplug *never* call qdev_free(). 3) Add an unplugged NotifierList to DeviceState. 4) Change the various hotplug consumers to call qdev_set_parent_bus() to NULL to unplug the device from the bus. Change qdev_set_parent_bus() to allow this and remove the bus link and invoke the unplugged notifier. 5) Change qdev_device_del() to add a notifier to the object that calls object_unparent() and object_unref. 6) Rename DeviceState::unplug to DeviceState::request_unplug I like this good name! 7) Take Ping Fan's patch + another patch to add a reference count in object_property_add_link In these days, I had thought about the way to do the hot unplug like the following: Suppose we start from devA qdev_tree_delete(devA) { qdev_walk_children(devA, qdev_device_del, qdev_bus_del, NULL) qdev_device_del(devA) } For qdev_device_del() do the following things: --. delete link from parent bus --. detached from parent bus-children --. dev-parent_bus = NULL --. object_unref(dev); For qdev_bus_del(), -- delete child property of parent -- detach from parent-child_bus -- bus-parent = NULL -- object_unref(bus) So leave anything handled by object_unref(), no call to qdev_free and so on Thanks and regards, pingfan Regards, Anthony Liguori Paolo --- qom/object.c | 12 +++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/qom/object.c b/qom/object.c index a552be2..76b3d34 100644 --- a/qom/object.c +++ b/qom/object.c @@ -957,6 +957,16 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque, } } +static void object_finalize_link_property(Object *obj, const char *name, + void *opaque) +{ +Object **child = opaque; + +if (*child != NULL) { +object_unref(*child); +} +} + void object_property_add_link(Object *obj, const char *name, const char *type, Object **child, Error **errp) @@ -968,7 +978,7 @@ void object_property_add_link(Object *obj, const char *name, object_property_add(obj, name, full_type, object_get_link_property, object_set_link_property, -NULL, child, errp); +object_finalize_link_property, child, errp); g_free(full_type); }
Re: [Qemu-devel] [PATCH] qom: removal of link property need to release its target
Il 23/08/2012 00:40, Anthony Liguori ha scritto: I don't really like the notion of a forced eject where we delete a device when the guest is using it and not cooperative. I don't see the benefit at all. Forcing detachment of a BlockDriverState from a device followed by EIO being reported to the guest for all I/O ops makes sense to me. But not forced removal of virtio-blk-pci. PCI express even has support for detecting surprise removal early (with card presence detection pins, that break contact before others) and remove power before damaging the hardware. It's very much a real thing. You could surprise-remove an assigned card from under the feet of a non-cooperating guest, for example. Paolo
Re: [Qemu-devel] How to reliably start a bare QEMU target to query capabilities via QMP
On Wed, Aug 22, 2012 at 03:25:38PM -0500, Anthony Liguori wrote: Daniel P. Berrange berra...@redhat.com writes: I've been adapting libvirt to use to the various new QMP commands to query QEMU's capabilities, instead of the hated -help parsing. Obviously the critical part of this is being able to reliably start a bare QEMU process with no actual guest OS configured (no disks, no kernel, etc) and talk to its monitor. I hadn't anticipated problems since I only tested with x86_64 / i386 most of the time, which work well in this respect. Currently I am doing # $QEMU_BINARY -S \ -no-user-config \ -nodefconfig \ -nodefaults \ -nographic \ -qmp stdio This works for about 50% of the QEMU targets: Do we have to go down the route of adding some sort of -no-vm flag to explicitly say we don't care about any of the VM setup parts ? This would be more like what my old patches did which mapped monitors commands onto '-query-X' command line args, bypassing VM setup, but still using normal QMP monitor interaction. Any other suggestions on how to reliably get a QMP monitor to a target, without any VM config. ? -M none. See the patch I just sent out. I think we can include this in 1.2 as it poses no real risk. Great, that's an nice elegant solution to the problem :-) Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
Re: [Qemu-devel] [PATCH v12 1/2] qxl: add QXL_IO_MONITORS_CONFIG_ASYNC
On 08/22/12 10:16, Alon Levy wrote: v11-v12: fix build with older spice server (Gerd). Replaced patches in the spice queue. thanks, Gerd
Re: [Qemu-devel] [PATCH 2/5] trace-cmd: Use tracing directory to count CPUs
On Thu, 2012-08-23 at 12:00 +0900, Masami Hiramatsu wrote: (2012/08/23 11:01), Masami Hiramatsu wrote: (2012/08/22 22:41), Steven Rostedt wrote: On Wed, 2012-08-22 at 17:43 +0900, Yoshihiro YUNOMAE wrote: From: Masami Hiramatsu masami.hiramatsu...@hitachi.com Count debugfs/tracing/per_cpu/cpu* to determine the number of CPUs. I'm curious, do you find that sysconf doesn't return the # of CPUs the system has? No, sysconf returns the number of hosts CPUs, not guests. I've had boxes where the per_cpu/cpu* had more cpus than the box actually holds. But this was a bug in the kernel, not the tool. This change log needs to have rational instead of just explaining what the patch does. Ah, I see. Hmm, then this should be enabled by a command line option or an environment variable. Oops, I misunderstood. I'll add more comment for why this should be tried instead of sysconf. And now that I understand why you are doing this, why not only do this if the TRACE_AGENT or DEBUG_TRACING_DIR is defined. That is, if we are doing it against a bare metal system, then sysconf should suffice, but if we are tracing against a guest, then it should use the tracing directory to determine the buffers. We could add options to override this, but I would think the default should just Do The Right Thing(tm). -- Steve
Re: [Qemu-devel] [PATCH 1/2 v1] blkdrv: Add queue limits parameters for sg block drive
On Wed 22 Aug 2012 10:13:44 PM CST, Paolo Bonzini wrote: Il 22/08/2012 15:13, Stefan Hajnoczi ha scritto: http://lists.gnu.org/archive/html/qemu-devel/2010-12/msg01741.html This is a real problem in practice. IE. the USB CD-ROM on this POWER7 blade limits transfers to 0x1e000 bytes for example and the Linux sr driver on the guest is going to try to give me bigger requests than that if I don't start limiting them, which will cause all sort of errors. It cannot be fixed for emulated SCSI HBAs in general but it can for virtio-scsi. For disks, this should be fixed simply by using scsi-block instead of scsi-generic. CD-ROMs are indeed more complicated because burning CDs cannot be done with syscalls. :/ So, as the problem exist to CD-ROM, I will continue to get these patches move on. As Paolo pointed out, the only limit is max_sectors (the total size of a scatter-list), I will drop the other 2 parameters. Paolo, what's your opinion? Cong Paolo
Re: [Qemu-devel] [PATCH v2] register reset handler to write image into memory
Dear All, I can't find MAINTAINER of hw/loader.c. Who can help review and apply this patch? Best Regards, Olivia Yin -Original Message- From: Yin Olivia-R63875 Sent: Friday, August 17, 2012 5:08 PM To: qemu-...@nongnu.org; qemu-devel@nongnu.org Cc: Yin Olivia-R63875 Subject: [PATCH v2] register reset handler to write image into memory Instead of add rom blobs, this patch just write them directly to memory. This patch registers reset handler uimage_reset() and image_file_reset() which load images into RAM during initial bootup and VM reset. v2: use g_file_get_content() to load load image file. Signed-off-by: Olivia Yin hong-hua@freescale.com --- This patch is based on branch 'ppc-next' of Alex's upstream QEMU repo: http://repo.or.cz/r/qemu/agraf.git hw/loader.c | 88 - -- 1 files changed, 66 insertions(+), 22 deletions(-) diff --git a/hw/loader.c b/hw/loader.c index 33acc2f..0be8bf7 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -56,6 +56,12 @@ static int roms_loaded; +typedef struct ImageFile ImageFile; +struct ImageFile { +char *name; +target_phys_addr_t addr; +}; + /* return the size or -1 if error */ int get_image_size(const char *filename) { @@ -86,6 +92,24 @@ int load_image(const char *filename, uint8_t *addr) return size; } +static void image_file_reset(void *opaque) { +ImageFile *image = opaque; +GError *err = NULL; +gboolean res; +gchar *content; +gsize size; + +res = g_file_get_contents(image-name, content, size, err); +if (res == FALSE) { + error_report(failed to read image file: %s\n, image-name); + g_error_free(err); +} else { + cpu_physical_memory_rw(image-addr, (uint8_t *)content, size, 1); + g_free(content); +} +} + /* read()-like version */ ssize_t read_targphys(const char *name, int fd, target_phys_addr_t dst_addr, size_t nbytes) @@ -112,7 +136,12 @@ int load_image_targphys(const char *filename, return -1; } if (size 0) { -rom_add_file_fixed(filename, addr, -1); +ImageFile *image; +image = g_malloc0(sizeof(*image)); +image-name = g_strdup(filename); +image-addr = addr; + +qemu_register_reset(image_file_reset, image); } return size; } @@ -433,15 +462,14 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, return dstbytes; } -/* Load a U-Boot image. */ -int load_uimage(const char *filename, target_phys_addr_t *ep, -target_phys_addr_t *loadaddr, int *is_linux) +/* write uimage into memory */ +static int uimage_physical_loader(const char *filename, uint8_t **data, + target_phys_addr_t *loadaddr) { int fd; int size; uboot_image_header_t h; uboot_image_header_t *hdr = h; -uint8_t *data = NULL; int ret = -1; fd = open(filename, O_RDONLY | O_BINARY); @@ -474,18 +502,9 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, goto out; } -/* TODO: Check CPU type. */ -if (is_linux) { -if (hdr-ih_os == IH_OS_LINUX) -*is_linux = 1; -else -*is_linux = 0; -} - -*ep = hdr-ih_ep; -data = g_malloc(hdr-ih_size); +*data = g_malloc(hdr-ih_size); -if (read(fd, data, hdr-ih_size) != hdr-ih_size) { +if (read(fd, *data, hdr-ih_size) != hdr-ih_size) { fprintf(stderr, Error reading file\n); goto out; } @@ -495,11 +514,11 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, size_t max_bytes; ssize_t bytes; -compressed_data = data; +compressed_data = *data; max_bytes = UBOOT_MAX_GUNZIP_BYTES; -data = g_malloc(max_bytes); +*data = g_malloc(max_bytes); -bytes = gunzip(data, max_bytes, compressed_data, hdr-ih_size); +bytes = gunzip(*data, max_bytes, compressed_data, + hdr-ih_size); g_free(compressed_data); if (bytes 0) { fprintf(stderr, Unable to decompress gzipped image!\n); @@ -508,7 +527,6 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, hdr-ih_size = bytes; } -rom_add_blob_fixed(filename, data, hdr-ih_size, hdr-ih_load); if (loadaddr) *loadaddr = hdr-ih_load; @@ -516,12 +534,38 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, ret = hdr-ih_size; out: -if (data) -g_free(data); close(fd); return ret; } +static void uimage_reset(void *opaque) +{ +ImageFile *image = opaque; +uint8_t *data = NULL; +int size; + +size = uimage_physical_loader(image-name, data, image-addr); +cpu_physical_memory_rw(image-addr, data, size, 1); +g_free(data); +} +
Re: [Qemu-devel] [PATCH 1/2 v1] blkdrv: Add queue limits parameters for sg block drive
Il 23/08/2012 11:31, Cong Meng ha scritto: For disks, this should be fixed simply by using scsi-block instead of scsi-generic. CD-ROMs are indeed more complicated because burning CDs cannot be done with syscalls. :/ So, as the problem exist to CD-ROM, I will continue to get these patches move on. I'm still trying to understand the extent of the problem. The problem occurs for _USB_ CD-ROMs according to Ben. Passthrough of USB storage devices should be done via USB passthrough, not virtio-scsi. If we do USB passthrough via the SCSI layer we miss on all the quirks that the OS may do based on the USB product/vendor pairs. There's no end to these, and some of the quirks may cause the device to lock up or corruption. I'd rather see a reproducer using SAS/ATA/ATAPI disks before punting. Paolo
Re: [Qemu-devel] passing translated address out in QEMU
On Wed, Aug 22, 2012 at 09:38:17PM -0700, Xin Tong wrote: On Wed, Aug 22, 2012 at 8:14 PM, 陳韋任 (Wei-Ren Chen) che...@iis.sinica.edu.tw wrote: In tcg_gen_qemu_ld8s(tmp, addr, index); a TCGv addr is passed to the INDEX_op_qemu_ld8s as param and the loaded value is passed back in tmp. i want to get the translated value as well. how can i do that ? IIUC, qemu_ld takes addr as guest virtual address, then loads the value in that address into tmp. So, what translated value you mean here? The guest physical address, host virtual address, or the value of the guest virtual address? either the guest physical or the host virtual is fine with me. but better to be guest physical. i think guest physical can be obtained by subtracting host virtual with a fixed offset for ram. but the thing i do not know how to do is how to pass the guest physical back, can i store the guest physical in the TCGv from the guest virtual. qemu_ld will go through software tlb first, you will get host virtual address there. It will go ld{b,w,l,q}_mmu if software tlb miss, call tlb_fill - cpu_x86_handle_mmu_fault, you can get guest physical address there (target_phys_addr_t paddr). If you want to get guest physical address for each guest memory access, I guess you need to disable software tlb lookup, you can refer to Max's patch [1]. Or as you said, maybe you can get guest physical addr from host virtual addr. You can refer to cpu_physical_memory_map (exec.c) which map guest physical addr to host virtual addr, then see how you can do the reverse. HTH, chenwj [1] http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg03226.html -- Wei-Ren Chen (陳韋任) Computer Systems Lab, Institute of Information Science, Academia Sinica, Taiwan (R.O.C.) Tel:886-2-2788-3799 #1667 Homepage: http://people.cs.nctu.edu.tw/~chenwj
Re: [Qemu-devel] [PATCH 1/2 v1] blkdrv: Add queue limits parameters for sg block drive
On Thu, Aug 23, 2012 at 11:03 AM, Paolo Bonzini pbonz...@redhat.com wrote: Il 23/08/2012 11:31, Cong Meng ha scritto: For disks, this should be fixed simply by using scsi-block instead of scsi-generic. CD-ROMs are indeed more complicated because burning CDs cannot be done with syscalls. :/ So, as the problem exist to CD-ROM, I will continue to get these patches move on. I'm still trying to understand the extent of the problem. The problem occurs for _USB_ CD-ROMs according to Ben. Passthrough of USB storage devices should be done via USB passthrough, not virtio-scsi. If we do USB passthrough via the SCSI layer we miss on all the quirks that the OS may do based on the USB product/vendor pairs. There's no end to these, and some of the quirks may cause the device to lock up or corruption. I'd rather see a reproducer using SAS/ATA/ATAPI disks before punting. This issue affects passthrough: either an entire sg device or at least a SG_IO ioctl (e.g. a non-READ/WRITE SCSI command). To reproduce it, check host queue limits and guest virtio-scsi queue limits. Then pick a command that can exceed the limits and try it from inside the guest :). Stefan
Re: [Qemu-devel] passing translated address out in QEMU
subtracting host virtual with a fixed offset for ram. but the thing i do not know how to do is how to pass the guest physical back, can i store the guest physical in the TCGv from the guest virtual. Maybe you can store it on a host unused register, perhaps xmm0? ;) Regards, chenwj -- Wei-Ren Chen (陳韋任) Computer Systems Lab, Institute of Information Science, Academia Sinica, Taiwan (R.O.C.) Tel:886-2-2788-3799 #1667 Homepage: http://people.cs.nctu.edu.tw/~chenwj
Re: [Qemu-devel] [PATCH v2] register reset handler to write image into memory
2012/8/23 Yin Olivia-R63875 r63...@freescale.com: Dear All, I can't find MAINTAINER of hw/loader.c. Who can help review and apply this patch? Please use the script scripts/get_maintainer.pl, like: $ scripts/get_maintainer.pl your_patch_file.patch or $ scripts/get_maintainer.pl -f hw/loader.c Best Regards, Olivia Yin -- Best Regards, Dunrong Huang
Re: [Qemu-devel] [PATCH v9 5/6] introduce a new qom device to deal with panicked event
On 2012-08-23 04:32, Wen Congyang wrote: If the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target. Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang we...@cn.fujitsu.com --- hw/kvm/Makefile.objs |2 +- hw/kvm/pv_event.c| 190 ++ hw/pc_piix.c |9 +++ kvm.h|2 + 4 files changed, 202 insertions(+), 1 deletions(-) create mode 100644 hw/kvm/pv_event.c diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs index 226497a..23e3b30 100644 --- a/hw/kvm/Makefile.objs +++ b/hw/kvm/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pv_event.o diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c new file mode 100644 index 000..c03dd22 --- /dev/null +++ b/hw/kvm/pv_event.c @@ -0,0 +1,190 @@ +/* + * QEMU KVM support, paravirtual event device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang we...@cn.fujitsu.com + * + * 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 linux/kvm_para.h +#include asm/kvm_para.h +#include qobject.h +#include qjson.h +#include monitor.h +#include sysemu.h +#include kvm.h + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +#define PV_EVENT_DRIVER kvm_pv_event + +struct PVEventAction { +char *panicked_action; +int panicked_action_value; +}; + +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \ +DEFINE_PROP_STRING(panicked_action, _state, _conf.panicked_action) + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf({ 'action': %s }, action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(uint32_t panicked_action) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event(report); +break; + +case PANICKED_PAUSE: +panicked_mon_event(pause); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event(poweroff); +qemu_system_shutdown_request(); +break; + +case PANICKED_RESET: +panicked_mon_event(reset); +qemu_system_reset_request(); +break; +} +} + +static uint64_t supported_event(void) +{ +return 1 KVM_PV_FEATURE_PANICKED; +} + +static void handle_event(int event, struct PVEventAction *conf) +{ +if (event == KVM_PV_EVENT_PANICKED) { +panicked_perform_action(conf-panicked_action_value); +} +} + +static int pv_event_init(struct PVEventAction *conf) +{ +if (!conf-panicked_action) { +conf-panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf-panicked_action, none) == 0) { +conf-panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf-panicked_action, pause) == 0) { +conf-panicked_action_value = PANICKED_PAUSE; +} else if (strcasecmp(conf-panicked_action, poweroff) == 0) { +conf-panicked_action_value = PANICKED_POWEROFF; +} else if (strcasecmp(conf-panicked_action, reset) == 0) { +conf-panicked_action_value = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} + +#if defined(KVM_PV_EVENT_PORT) + +#include hw/isa.h + +typedef struct { +ISADevice dev; +struct PVEventAction conf; +MemoryRegion ioport; +} PVIOPortState; + +static uint64_t pv_io_read(void *opaque, target_phys_addr_t addr, unsigned size) +{ +return supported_event(); +} + +static void pv_io_write(void *opaque, target_phys_addr_t addr, uint64_t val, +
Re: [Qemu-devel] [PATCH 1/2 v1] blkdrv: Add queue limits parameters for sg block drive
Il 23/08/2012 12:08, Stefan Hajnoczi ha scritto: I'm still trying to understand the extent of the problem. The problem occurs for _USB_ CD-ROMs according to Ben. Passthrough of USB storage devices should be done via USB passthrough, not virtio-scsi. If we do USB passthrough via the SCSI layer we miss on all the quirks that the OS may do based on the USB product/vendor pairs. There's no end to these, and some of the quirks may cause the device to lock up or corruption. I'd rather see a reproducer using SAS/ATA/ATAPI disks before punting. This issue affects passthrough: either an entire sg device or at least a SG_IO ioctl (e.g. a non-READ/WRITE SCSI command). To reproduce it, check host queue limits and guest virtio-scsi queue limits. Then pick a command that can exceed the limits and try it from inside the guest :). Yes, so much is clear. But does it happen _in practice_? Do initiators actually issue commands that are that big? Paolo
[Qemu-devel] Race condition in char device setup causing SEGV
When testing with the new -M none arg, I've noticed that ~70% of the time libvirt starts QEMU will result in a SEGV from QEMU with the following stack trace: (gdb) bt #0 0x in ?? () #1 0x5567a37f in json_lexer_feed_char (lexer=0x5658fb20, ch=123 '{', flush=false) at json-lexer.c:324 #2 0x5567a4aa in json_lexer_feed (lexer=0x5658fb20, buffer=0x7fffe7b7 {, size=1) at json-lexer.c:356 #3 0x5567c708 in json_message_parser_feed (parser=0x5658fb18, buffer=0x7fffe7b7 {, size=1) at json-streamer.c:110 #4 0x55882861 in monitor_control_read (opaque=0x5658f6a0, buf=0x7fffe7b7 {, size=1) at /home/berrange/src/virt/qemu/monitor.c:4768 #5 0x5579b051 in qemu_chr_be_write (s=0x5658dc10, buf=0x7fffe7b7 {, len=1) at qemu-char.c:164 #6 0x5579c9c8 in stdio_read (opaque=0x5658dc10) at qemu-char.c:720 #7 0x5567941f in qemu_iohandler_poll (readfds=0x560f17c0, writefds=0x560f1840, xfds=0x560f18c0, ret=2) at iohandler.c:122 #8 0x5577166a in main_loop_wait (nonblocking=0) at main-loop.c:497 #9 0x5576956b in main_loop () at /home/berrange/src/virt/qemu/vl.c:1643 #10 0x55770239 in main (argc=10, argv=0x7fffeca8, envp=0x7fffed00) at /home/berrange/src/virt/qemu/vl.c:3755 Stack frame #1 there is doing this: lexer-emit(lexer, lexer-token, JSON_ERROR, lexer-x, lexer-y); GDB confirms that the 'emit' field has not yet been initialized. In the case of QMP, this is initialized by the following sequence: - main - chardev_init_func - qemu_chr_generic_open ...async from event loop... - main_loop - qemu_chr_generic_open_bh - monitor_control_event - json_message_parser_init - json_lexer_init The problem arises if you try to feed data to QEMU before the bottom half has run. There is a race where qemu_chr_be_write can be called to process input, before the qemu_chr_generic_open_bh has been invoked. This can actually be quite easily demonstrated (at least on my system): # echo { | qemu-system-x86_64 -nodefaults -nographic -M none -qmp stdio Segmentation fault If you remove the '-M none' call, you won't hit this race condition 99% of the time, but I have occassionally been able to see it. It isn't clear to me what to change to solve this race condition. Probably though, the I/O handlers for a char device should be registered until the open bottom half has completed. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
Re: [Qemu-devel] Race condition in char device setup causing SEGV
On Thu, Aug 23, 2012 at 12:01:05PM +0100, Daniel P. Berrange wrote: When testing with the new -M none arg, I've noticed that ~70% of the time libvirt starts QEMU will result in a SEGV from QEMU with the following stack trace: (gdb) bt #0 0x in ?? () #1 0x5567a37f in json_lexer_feed_char (lexer=0x5658fb20, ch=123 '{', flush=false) at json-lexer.c:324 #2 0x5567a4aa in json_lexer_feed (lexer=0x5658fb20, buffer=0x7fffe7b7 {, size=1) at json-lexer.c:356 #3 0x5567c708 in json_message_parser_feed (parser=0x5658fb18, buffer=0x7fffe7b7 {, size=1) at json-streamer.c:110 #4 0x55882861 in monitor_control_read (opaque=0x5658f6a0, buf=0x7fffe7b7 {, size=1) at /home/berrange/src/virt/qemu/monitor.c:4768 #5 0x5579b051 in qemu_chr_be_write (s=0x5658dc10, buf=0x7fffe7b7 {, len=1) at qemu-char.c:164 #6 0x5579c9c8 in stdio_read (opaque=0x5658dc10) at qemu-char.c:720 #7 0x5567941f in qemu_iohandler_poll (readfds=0x560f17c0, writefds=0x560f1840, xfds=0x560f18c0, ret=2) at iohandler.c:122 #8 0x5577166a in main_loop_wait (nonblocking=0) at main-loop.c:497 #9 0x5576956b in main_loop () at /home/berrange/src/virt/qemu/vl.c:1643 #10 0x55770239 in main (argc=10, argv=0x7fffeca8, envp=0x7fffed00) at /home/berrange/src/virt/qemu/vl.c:3755 Stack frame #1 there is doing this: lexer-emit(lexer, lexer-token, JSON_ERROR, lexer-x, lexer-y); GDB confirms that the 'emit' field has not yet been initialized. In the case of QMP, this is initialized by the following sequence: - main - chardev_init_func - qemu_chr_generic_open ...async from event loop... - main_loop - qemu_chr_generic_open_bh - monitor_control_event - json_message_parser_init - json_lexer_init The problem arises if you try to feed data to QEMU before the bottom half has run. There is a race where qemu_chr_be_write can be called to process input, before the qemu_chr_generic_open_bh has been invoked. This can actually be quite easily demonstrated (at least on my system): # echo { | qemu-system-x86_64 -nodefaults -nographic -M none -qmp stdio Segmentation fault If you remove the '-M none' call, you won't hit this race condition 99% of the time, but I have occassionally been able to see it. It isn't clear to me what to change to solve this race condition. Probably though, the I/O handlers for a char device should be registered until the open bottom half has completed. The following patch shows one approach to fix it. I've only addressed the 'stdio' char backend - obviously a complete patch would try todo all backends where needed. diff --git a/qemu-char.c b/qemu-char.c index 398baf1..85034de 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -118,6 +118,9 @@ void qemu_chr_be_event(CharDriverState *s, int event) break; } +if (s-chr_event_priv) + s-chr_event_priv(s, event); + if (!s-chr_event) return; s-chr_event(s-handler_opaque, event); @@ -765,6 +768,22 @@ static void qemu_chr_close_stdio(struct CharDriverState *chr) fd_chr_close(chr); } + +static void qemu_chr_event_stdio(void *opaque, int event) +{ +CharDriverState *chr = opaque; + +switch (event) { +case CHR_EVENT_OPENED: + qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr); + break; +case CHR_EVENT_CLOSED: + qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL); + break; +} +} + + static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts) { CharDriverState *chr; @@ -782,7 +801,7 @@ static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts) chr = qemu_chr_open_fd(0, 1); chr-chr_close = qemu_chr_close_stdio; chr-chr_set_echo = qemu_chr_set_echo_stdio; -qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr); +chr-chr_event_priv = qemu_chr_event_stdio; stdio_nb_clients++; stdio_allow_signal = qemu_opt_get_bool(opts, signal, display_type != DT_NOGRAPHIC); diff --git a/qemu-char.h b/qemu-char.h index 486644b..e377ae7 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -59,6 +59,7 @@ struct CharDriverState { int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); int (*get_msgfd)(struct CharDriverState *s); int (*chr_add_client)(struct CharDriverState *chr, int fd); +IOEventHandler *chr_event_priv; IOEventHandler *chr_event; IOCanReadHandler *chr_can_read; IOReadHandler *chr_read; Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
[Qemu-devel] [PATCH v3 uq/master 4/6] memory: Flush coalesced MMIO on mapping and state changes
Flush pending coalesced MMIO before performing mapping or state changes that could affect the event orderings or route the buffered requests to a wrong region. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- memory.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/memory.c b/memory.c index e29c193..c5bcf45 100644 --- a/memory.c +++ b/memory.c @@ -733,6 +733,7 @@ static void address_space_update_topology(AddressSpace *as) void memory_region_transaction_begin(void) { +qemu_flush_coalesced_mmio_buffer(); ++memory_region_transaction_depth; } -- 1.7.3.4
[Qemu-devel] [PATCH v3 uq/master 0/6] kvm: Get coalesced MMIO flushing out of the hot-path
This is just a repost, now targeting uq/master as agreed. No changes compared to v2 except that i82378: Remove bogus MMIO coalescing was dropped as it is already in QEMU upstream by now. Original description: We currently flush the coalesced MMIO buffer on every vmexit to userspace. KVM only provides a single buffer per VM, so a central lock is required to read from it. This is a contention point given a large enough VCPU set. Moreover, we need to hold the BQL while replaying the queued requests, probably for a long time until there is more fine grained locking available. Good reasons to overcome the unconditional flush. The series achieves this by flushing only on selected memory region accesses, either generically via the memory access dispatcher or directly on certain VGA PIO accesses that are not yet fully converted. Another reason to flush are remappings or other relevant region state changes. Jan Kiszka (6): memory: Flush coalesced MMIO on selected region access memory: Use transaction_begin/commit also for single-step operations memory: Fold memory_region_update_topology into memory_region_transaction_commit memory: Flush coalesced MMIO on mapping and state changes VGA: Flush coalesced MMIO on related MMIO/PIO accesses kvm: Stop flushing coalesced MMIO on vmexit hw/cirrus_vga.c |7 hw/qxl.c|1 + hw/vga-isa-mm.c |1 + hw/vga.c|5 +++ hw/vmware_vga.c |1 + kvm-all.c |2 - memory.c| 104 --- memory.h| 26 ++ 8 files changed, 102 insertions(+), 45 deletions(-) -- 1.7.3.4
[Qemu-devel] [RFC][PATCH] qemu-timer: Run timers in alarm timer handler
No need for this indirection via qemu_notify_event. On Unix, we already catch SIGALRM via signalfd (or its emulation) and run the handler synchronously. Under Win32, handlers run in separate threads. So we just need to grab the global lock around the handler execution. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- The Unix side looks safe to me, but I'm not yet 100% confident about Win32. This is part of an ongoing effort to create separate alarm timers over their own io-threads. A lengthy effort. But these bits appear useful to me already. main-loop.c |2 -- qemu-timer.c | 21 + qemu-timer.h |1 - 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/main-loop.c b/main-loop.c index eb3b6e6..1a6ea25 100644 --- a/main-loop.c +++ b/main-loop.c @@ -499,8 +499,6 @@ int main_loop_wait(int nonblocking) slirp_select_poll(rfds, wfds, xfds, (ret 0)); #endif -qemu_run_all_timers(); - /* Check bottom-halves last in case any of the earlier events triggered them. */ qemu_bh_poll(); diff --git a/qemu-timer.c b/qemu-timer.c index 5aea94e..26411a2 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -441,7 +441,7 @@ uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts) return qemu_timer_pending(ts) ? ts-expire_time : -1; } -void qemu_run_all_timers(void) +static void qemu_run_all_timers(void) { alarm_timer-pending = false; @@ -457,11 +457,7 @@ void qemu_run_all_timers(void) } } -#ifdef _WIN32 -static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused) -#else static void host_alarm_handler(int host_signum) -#endif { struct qemu_alarm_timer *t = alarm_timer; if (!t) @@ -469,7 +465,7 @@ static void host_alarm_handler(int host_signum) t-expired = true; t-pending = true; -qemu_notify_event(); +qemu_run_all_timers(); } #if defined(__linux__) @@ -613,9 +609,11 @@ static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg, if (!t) { return; } +qemu_mutex_lock_iothread(); t-expired = true; t-pending = true; -qemu_notify_event(); +qemu_run_all_timers(); +qemu_mutex_unlock_iothread(); } static int mm_start_timer(struct qemu_alarm_timer *t) @@ -668,6 +666,13 @@ static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta) } } +static void CALLBACK win32_alarm_handler(PVOID lpParam, BOOLEAN unused) +{ +qemu_mutex_lock_iothread(); +host_alarm_handler(0); +qemu_mutex_unlock_iothread(); +} + static int win32_start_timer(struct qemu_alarm_timer *t) { HANDLE hTimer; @@ -679,7 +684,7 @@ static int win32_start_timer(struct qemu_alarm_timer *t) interval in the dynticks case. */ success = CreateTimerQueueTimer(hTimer, NULL, - host_alarm_handler, + win32_alarm_handler, t, 1, 360, diff --git a/qemu-timer.h b/qemu-timer.h index f8af595..b9bf313 100644 --- a/qemu-timer.h +++ b/qemu-timer.h @@ -58,7 +58,6 @@ bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time); uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts); void qemu_run_timers(QEMUClock *clock); -void qemu_run_all_timers(void); void configure_alarms(char const *opt); void init_clocks(void); int init_timer_alarm(void); -- 1.7.3.4
[Qemu-devel] [PATCH v3 uq/master 2/6] memory: Use transaction_begin/commit also for single-step operations
Wrap also simple operations consisting only of a single step with memory_region_transaction_begin/commit. This allows to perform additional steps like coalesced MMIO flushing from a single place. This requires dropping some micro-optimizations: The skipping of topology updates after updating disabled or unregistered regions. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- memory.c | 40 +--- 1 files changed, 25 insertions(+), 15 deletions(-) diff --git a/memory.c b/memory.c index 835eb86..58583cf 100644 --- a/memory.c +++ b/memory.c @@ -1076,8 +1076,9 @@ void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) { uint8_t mask = 1 client; +memory_region_transaction_begin(); mr-dirty_log_mask = (mr-dirty_log_mask ~mask) | (log * mask); -memory_region_update_topology(mr); +memory_region_transaction_commit(); } bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr, @@ -1110,16 +,18 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr) void memory_region_set_readonly(MemoryRegion *mr, bool readonly) { if (mr-readonly != readonly) { +memory_region_transaction_begin(); mr-readonly = readonly; -memory_region_update_topology(mr); +memory_region_transaction_commit(); } } void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable) { if (mr-readable != readable) { +memory_region_transaction_begin(); mr-readable = readable; -memory_region_update_topology(mr); +memory_region_transaction_commit(); } } @@ -1230,6 +1233,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, }; unsigned i; +memory_region_transaction_begin(); for (i = 0; i mr-ioeventfd_nb; ++i) { if (memory_region_ioeventfd_before(mrfd, mr-ioeventfds[i])) { break; @@ -1241,7 +1245,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, memmove(mr-ioeventfds[i+1], mr-ioeventfds[i], sizeof(*mr-ioeventfds) * (mr-ioeventfd_nb-1 - i)); mr-ioeventfds[i] = mrfd; -memory_region_update_topology(mr); +memory_region_transaction_commit(); } void memory_region_del_eventfd(MemoryRegion *mr, @@ -1260,6 +1264,7 @@ void memory_region_del_eventfd(MemoryRegion *mr, }; unsigned i; +memory_region_transaction_begin(); for (i = 0; i mr-ioeventfd_nb; ++i) { if (memory_region_ioeventfd_equal(mrfd, mr-ioeventfds[i])) { break; @@ -1271,7 +1276,7 @@ void memory_region_del_eventfd(MemoryRegion *mr, --mr-ioeventfd_nb; mr-ioeventfds = g_realloc(mr-ioeventfds, sizeof(*mr-ioeventfds)*mr-ioeventfd_nb + 1); -memory_region_update_topology(mr); +memory_region_transaction_commit(); } static void memory_region_add_subregion_common(MemoryRegion *mr, @@ -1280,6 +1285,8 @@ static void memory_region_add_subregion_common(MemoryRegion *mr, { MemoryRegion *other; +memory_region_transaction_begin(); + assert(!subregion-parent); subregion-parent = mr; subregion-addr = offset; @@ -1312,7 +1319,7 @@ static void memory_region_add_subregion_common(MemoryRegion *mr, } QTAILQ_INSERT_TAIL(mr-subregions, subregion, subregions_link); done: -memory_region_update_topology(mr); +memory_region_transaction_commit(); } @@ -1338,10 +1345,11 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr, void memory_region_del_subregion(MemoryRegion *mr, MemoryRegion *subregion) { +memory_region_transaction_begin(); assert(subregion-parent == mr); subregion-parent = NULL; QTAILQ_REMOVE(mr-subregions, subregion, subregions_link); -memory_region_update_topology(mr); +memory_region_transaction_commit(); } void memory_region_set_enabled(MemoryRegion *mr, bool enabled) @@ -1349,8 +1357,9 @@ void memory_region_set_enabled(MemoryRegion *mr, bool enabled) if (enabled == mr-enabled) { return; } +memory_region_transaction_begin(); mr-enabled = enabled; -memory_region_update_topology(NULL); +memory_region_transaction_commit(); } void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr) @@ -1376,16 +1385,15 @@ void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr) void memory_region_set_alias_offset(MemoryRegion *mr, target_phys_addr_t offset) { -target_phys_addr_t old_offset = mr-alias_offset; - assert(mr-alias); -mr-alias_offset = offset; -if (offset == old_offset || !mr-parent) { +if (offset == mr-alias_offset) { return; } -memory_region_update_topology(mr); +memory_region_transaction_begin(); +mr-alias_offset = offset; +memory_region_transaction_commit(); } ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr) @@ -1517,14 +1525,16 @@ void
[Qemu-devel] [PATCH v3 uq/master 6/6] kvm: Stop flushing coalesced MMIO on vmexit
The memory subsystem will now take care of flushing whenever affected regions are accessed or the memory mapping changes. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index e0244b6..432b84f 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1541,8 +1541,6 @@ int kvm_cpu_exec(CPUArchState *env) qemu_mutex_lock_iothread(); kvm_arch_post_run(env, run); -kvm_flush_coalesced_mmio_buffer(); - if (run_ret 0) { if (run_ret == -EINTR || run_ret == -EAGAIN) { DPRINTF(io window exit\n); -- 1.7.3.4
[Qemu-devel] [PATCH v3 uq/master 1/6] memory: Flush coalesced MMIO on selected region access
Instead of flushing pending coalesced MMIO requests on every vmexit, this provides a mechanism to selectively flush when memory regions related to the coalesced one are accessed. This first of all includes the coalesced region itself but can also applied to other regions, e.g. of the same device, by calling memory_region_set_flush_coalesced. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- memory.c | 24 memory.h | 26 ++ 2 files changed, 50 insertions(+), 0 deletions(-) diff --git a/memory.c b/memory.c index 643871b..835eb86 100644 --- a/memory.c +++ b/memory.c @@ -311,6 +311,9 @@ static void memory_region_read_accessor(void *opaque, MemoryRegion *mr = opaque; uint64_t tmp; +if (mr-flush_coalesced_mmio) { +qemu_flush_coalesced_mmio_buffer(); +} tmp = mr-ops-read(mr-opaque, addr, size); *value |= (tmp mask) shift; } @@ -325,6 +328,9 @@ static void memory_region_write_accessor(void *opaque, MemoryRegion *mr = opaque; uint64_t tmp; +if (mr-flush_coalesced_mmio) { +qemu_flush_coalesced_mmio_buffer(); +} tmp = (*value shift) mask; mr-ops-write(mr-opaque, addr, tmp, size); } @@ -826,6 +832,7 @@ void memory_region_init(MemoryRegion *mr, mr-dirty_log_mask = 0; mr-ioeventfd_nb = 0; mr-ioeventfds = NULL; +mr-flush_coalesced_mmio = false; } static bool memory_region_access_valid(MemoryRegion *mr, @@ -1176,12 +1183,16 @@ void memory_region_add_coalescing(MemoryRegion *mr, cmr-addr = addrrange_make(int128_make64(offset), int128_make64(size)); QTAILQ_INSERT_TAIL(mr-coalesced, cmr, link); memory_region_update_coalesced_range(mr); +memory_region_set_flush_coalesced(mr); } void memory_region_clear_coalescing(MemoryRegion *mr) { CoalescedMemoryRange *cmr; +qemu_flush_coalesced_mmio_buffer(); +mr-flush_coalesced_mmio = false; + while (!QTAILQ_EMPTY(mr-coalesced)) { cmr = QTAILQ_FIRST(mr-coalesced); QTAILQ_REMOVE(mr-coalesced, cmr, link); @@ -1190,6 +1201,19 @@ void memory_region_clear_coalescing(MemoryRegion *mr) memory_region_update_coalesced_range(mr); } +void memory_region_set_flush_coalesced(MemoryRegion *mr) +{ +mr-flush_coalesced_mmio = true; +} + +void memory_region_clear_flush_coalesced(MemoryRegion *mr) +{ +qemu_flush_coalesced_mmio_buffer(); +if (QTAILQ_EMPTY(mr-coalesced)) { +mr-flush_coalesced_mmio = false; +} +} + void memory_region_add_eventfd(MemoryRegion *mr, target_phys_addr_t addr, unsigned size, diff --git a/memory.h b/memory.h index bd1bbae..e5aa028 100644 --- a/memory.h +++ b/memory.h @@ -133,6 +133,7 @@ struct MemoryRegion { bool enabled; bool rom_device; bool warning_printed; /* For reservations */ +bool flush_coalesced_mmio; MemoryRegion *alias; target_phys_addr_t alias_offset; unsigned priority; @@ -521,6 +522,31 @@ void memory_region_add_coalescing(MemoryRegion *mr, void memory_region_clear_coalescing(MemoryRegion *mr); /** + * memory_region_set_flush_coalesced: Enforce memory coalescing flush before + *accesses. + * + * Ensure that pending coalesced MMIO request are flushed before the memory + * region is accessed. This property is automatically enabled for all regions + * passed to memory_region_set_coalescing() and memory_region_add_coalescing(). + * + * @mr: the memory region to be updated. + */ +void memory_region_set_flush_coalesced(MemoryRegion *mr); + +/** + * memory_region_clear_flush_coalesced: Disable memory coalescing flush before + * accesses. + * + * Clear the automatic coalesced MMIO flushing enabled via + * memory_region_set_flush_coalesced. Note that this service has no effect on + * memory regions that have MMIO coalescing enabled for themselves. For them, + * automatic flushing will stop once coalescing is disabled. + * + * @mr: the memory region to be updated. + */ +void memory_region_clear_flush_coalesced(MemoryRegion *mr); + +/** * memory_region_add_eventfd: Request an eventfd to be triggered when a word *is written to a location. * -- 1.7.3.4
[Qemu-devel] [PATCH v3 uq/master 5/6] VGA: Flush coalesced MMIO on related MMIO/PIO accesses
In preparation of stopping to flush coalesced MMIO unconditionally on vmexits, mark VGA MMIO and PIO regions as synchronous /wrt coalesced MMIO and flush the buffer explicitly on PIO accesses that do not use generic memory regions yet. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/cirrus_vga.c |7 +++ hw/qxl.c|1 + hw/vga-isa-mm.c |1 + hw/vga.c|5 + hw/vmware_vga.c |1 + 5 files changed, 15 insertions(+), 0 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index e8dcc6b..9a0a565 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2441,6 +2441,8 @@ static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr) VGACommonState *s = c-vga; int val, index; +qemu_flush_coalesced_mmio_buffer(); + if (vga_ioport_invalid(s, addr)) { val = 0xff; } else { @@ -2534,6 +2536,8 @@ static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) VGACommonState *s = c-vga; int index; +qemu_flush_coalesced_mmio_buffer(); + /* check port range access depending on color/monochrome mode */ if (vga_ioport_invalid(s, addr)) { return; @@ -2854,6 +2858,7 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, /* I/O handler for LFB */ memory_region_init_io(s-cirrus_linear_io, cirrus_linear_io_ops, s, cirrus-linear-io, VGA_RAM_SIZE); +memory_region_set_flush_coalesced(s-cirrus_linear_io); /* I/O handler for LFB */ memory_region_init_io(s-cirrus_linear_bitblt_io, @@ -2861,10 +2866,12 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, s, cirrus-bitblt-mmio, 0x40); +memory_region_set_flush_coalesced(s-cirrus_linear_bitblt_io); /* I/O handler for memory-mapped I/O */ memory_region_init_io(s-cirrus_mmio_io, cirrus_mmio_io_ops, s, cirrus-mmio, CIRRUS_PNPMMIO_SIZE); +memory_region_set_flush_coalesced(s-cirrus_mmio_io); s-real_vram_size = (s-device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024; diff --git a/hw/qxl.c b/hw/qxl.c index c2dd3b4..05da2df 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1810,6 +1810,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) if (qxl-id == 0) { vga_dirty_log_start(qxl-vga); } +memory_region_set_flush_coalesced(qxl-io_bar); pci_register_bar(qxl-pci, QXL_IO_RANGE_INDEX, diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c index 44ae7d9..306e6ba 100644 --- a/hw/vga-isa-mm.c +++ b/hw/vga-isa-mm.c @@ -107,6 +107,7 @@ static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base, s_ioport_ctrl = g_malloc(sizeof(*s_ioport_ctrl)); memory_region_init_io(s_ioport_ctrl, vga_mm_ctrl_ops, s, vga-mm-ctrl, 0x10); +memory_region_set_flush_coalesced(s_ioport_ctrl); vga_io_memory = g_malloc(sizeof(*vga_io_memory)); /* XXX: endianness? */ diff --git a/hw/vga.c b/hw/vga.c index f82ced8..ffb5a7a 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -360,6 +360,8 @@ uint32_t vga_ioport_read(void *opaque, uint32_t addr) VGACommonState *s = opaque; int val, index; +qemu_flush_coalesced_mmio_buffer(); + if (vga_ioport_invalid(s, addr)) { val = 0xff; } else { @@ -452,6 +454,8 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) VGACommonState *s = opaque; int index; +qemu_flush_coalesced_mmio_buffer(); + /* check port range access depending on color/monochrome mode */ if (vga_ioport_invalid(s, addr)) { return; @@ -2337,6 +2341,7 @@ MemoryRegion *vga_init_io(VGACommonState *s, vga_mem = g_malloc(sizeof(*vga_mem)); memory_region_init_io(vga_mem, vga_mem_ops, s, vga-lowmem, 0x2); +memory_region_set_flush_coalesced(vga_mem); return vga_mem; } diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index f5e4f44..848ac4e 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -1185,6 +1185,7 @@ static int pci_vmsvga_initfn(PCIDevice *dev) memory_region_init_io(s-io_bar, vmsvga_io_ops, s-chip, vmsvga-io, 0x10); +memory_region_set_flush_coalesced(s-io_bar); pci_register_bar(s-card, 0, PCI_BASE_ADDRESS_SPACE_IO, s-io_bar); vmsvga_init(s-chip, pci_address_space(dev), -- 1.7.3.4
Re: [Qemu-devel] [PATCH v2] register reset handler to write image into memory
Hi, Am 23.08.2012 11:45, schrieb Yin Olivia-R63875: Dear All, I can't find MAINTAINER of hw/loader.c. Who can help review and apply this patch? This patch is not a small bugfix so it won't be applied during the v1.2 Hard Freeze. You based it onto ppc-next so the obvious answer is, Alex needs to review it, whom you forgot to cc. This patch does not answer the question why you try to avoid the ROM blobs and what ROM blobs are still being used for after your patch. I don't think it makes much sense to work around them for your use cases and to leave them behind - if there's something fundamentally wrong with them they should be ripped out completely or fixed. But maybe I'm misunderstanding in the absence of explanations? Regards, Andreas Best Regards, Olivia Yin -Original Message- From: Yin Olivia-R63875 Sent: Friday, August 17, 2012 5:08 PM To: qemu-...@nongnu.org; qemu-devel@nongnu.org Cc: Yin Olivia-R63875 Subject: [PATCH v2] register reset handler to write image into memory Instead of add rom blobs, this patch just write them directly to memory. This patch registers reset handler uimage_reset() and image_file_reset() which load images into RAM during initial bootup and VM reset. v2: use g_file_get_content() to load load image file. Signed-off-by: Olivia Yin hong-hua@freescale.com --- This patch is based on branch 'ppc-next' of Alex's upstream QEMU repo: http://repo.or.cz/r/qemu/agraf.git hw/loader.c | 88 - -- 1 files changed, 66 insertions(+), 22 deletions(-) diff --git a/hw/loader.c b/hw/loader.c index 33acc2f..0be8bf7 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -56,6 +56,12 @@ static int roms_loaded; +typedef struct ImageFile ImageFile; +struct ImageFile { +char *name; +target_phys_addr_t addr; +}; + /* return the size or -1 if error */ int get_image_size(const char *filename) { @@ -86,6 +92,24 @@ int load_image(const char *filename, uint8_t *addr) return size; } +static void image_file_reset(void *opaque) { +ImageFile *image = opaque; +GError *err = NULL; +gboolean res; +gchar *content; +gsize size; + +res = g_file_get_contents(image-name, content, size, err); +if (res == FALSE) { + error_report(failed to read image file: %s\n, image-name); + g_error_free(err); +} else { + cpu_physical_memory_rw(image-addr, (uint8_t *)content, size, 1); + g_free(content); +} +} + /* read()-like version */ ssize_t read_targphys(const char *name, int fd, target_phys_addr_t dst_addr, size_t nbytes) @@ -112,7 +136,12 @@ int load_image_targphys(const char *filename, return -1; } if (size 0) { -rom_add_file_fixed(filename, addr, -1); +ImageFile *image; +image = g_malloc0(sizeof(*image)); +image-name = g_strdup(filename); +image-addr = addr; + +qemu_register_reset(image_file_reset, image); } return size; } @@ -433,15 +462,14 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, return dstbytes; } -/* Load a U-Boot image. */ -int load_uimage(const char *filename, target_phys_addr_t *ep, -target_phys_addr_t *loadaddr, int *is_linux) +/* write uimage into memory */ +static int uimage_physical_loader(const char *filename, uint8_t **data, + target_phys_addr_t *loadaddr) { int fd; int size; uboot_image_header_t h; uboot_image_header_t *hdr = h; -uint8_t *data = NULL; int ret = -1; fd = open(filename, O_RDONLY | O_BINARY); @@ -474,18 +502,9 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, goto out; } -/* TODO: Check CPU type. */ -if (is_linux) { -if (hdr-ih_os == IH_OS_LINUX) -*is_linux = 1; -else -*is_linux = 0; -} - -*ep = hdr-ih_ep; -data = g_malloc(hdr-ih_size); +*data = g_malloc(hdr-ih_size); -if (read(fd, data, hdr-ih_size) != hdr-ih_size) { +if (read(fd, *data, hdr-ih_size) != hdr-ih_size) { fprintf(stderr, Error reading file\n); goto out; } @@ -495,11 +514,11 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, size_t max_bytes; ssize_t bytes; -compressed_data = data; +compressed_data = *data; max_bytes = UBOOT_MAX_GUNZIP_BYTES; -data = g_malloc(max_bytes); +*data = g_malloc(max_bytes); -bytes = gunzip(data, max_bytes, compressed_data, hdr-ih_size); +bytes = gunzip(*data, max_bytes, compressed_data, + hdr-ih_size); g_free(compressed_data); if (bytes 0) { fprintf(stderr, Unable to decompress gzipped image!\n); @@ -508,7 +527,6 @@ int load_uimage(const char *filename,
Re: [Qemu-devel] [RFC][PATCH] qemu-timer: Run timers in alarm timer handler
Il 23/08/2012 13:23, Jan Kiszka ha scritto: No need for this indirection via qemu_notify_event. On Unix, we already catch SIGALRM via signalfd (or its emulation) and run the handler synchronously. Under Win32, handlers run in separate threads. So we just need to grab the global lock around the handler execution. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- The Unix side looks safe to me, but I'm not yet 100% confident about Win32. This is part of an ongoing effort to create separate alarm timers over their own io-threads. A lengthy effort. Can you expand on this? The Win32 bits look fine, but it's a bit scary to make the Unix and Win32 paths so different. It works well until we have a BQL for timers, but would this complicate shrinking the scope of the BQL? Paolo
[Qemu-devel] [PATCH v3 uq/master 3/6] memory: Fold memory_region_update_topology into memory_region_transaction_commit
Simplify the code as we are using now only a subset of the original features of memory_region_update_topology. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- memory.c | 39 +++ 1 files changed, 11 insertions(+), 28 deletions(-) diff --git a/memory.c b/memory.c index 58583cf..e29c193 100644 --- a/memory.c +++ b/memory.c @@ -24,7 +24,6 @@ #include exec-obsolete.h unsigned memory_region_transaction_depth = 0; -static bool memory_region_update_pending = false; static bool global_dirty_log = false; static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners @@ -732,31 +731,6 @@ static void address_space_update_topology(AddressSpace *as) address_space_update_ioeventfds(as); } -static void memory_region_update_topology(MemoryRegion *mr) -{ -if (memory_region_transaction_depth) { -memory_region_update_pending |= !mr || mr-enabled; -return; -} - -if (mr !mr-enabled) { -return; -} - -MEMORY_LISTENER_CALL_GLOBAL(begin, Forward); - -if (address_space_memory.root) { -address_space_update_topology(address_space_memory); -} -if (address_space_io.root) { -address_space_update_topology(address_space_io); -} - -MEMORY_LISTENER_CALL_GLOBAL(commit, Forward); - -memory_region_update_pending = false; -} - void memory_region_transaction_begin(void) { ++memory_region_transaction_depth; @@ -766,8 +740,17 @@ void memory_region_transaction_commit(void) { assert(memory_region_transaction_depth); --memory_region_transaction_depth; -if (!memory_region_transaction_depth memory_region_update_pending) { -memory_region_update_topology(NULL); +if (!memory_region_transaction_depth) { +MEMORY_LISTENER_CALL_GLOBAL(begin, Forward); + +if (address_space_memory.root) { +address_space_update_topology(address_space_memory); +} +if (address_space_io.root) { +address_space_update_topology(address_space_io); +} + +MEMORY_LISTENER_CALL_GLOBAL(commit, Forward); } } -- 1.7.3.4
Re: [Qemu-devel] [PATCH v2 1/6] fix some debug printf format strings
Hi, Am 23.08.2012 08:24, schrieb Matthew Ogilvie: These are normally ifdefed out and don't matter. But if you enable them, they ought to be correct. Signed-off-by: Matthew Ogilvie mmogilvi_q...@miniinfo.net --- This version of the patch adds i8259.c. An alternative approach might be to eliminate these printf's, and/or replace them with trace*() calls, but until someone gets around to doing so... hw/cirrus_vga.c | 4 ++-- hw/i8259.c | 3 ++- hw/ide/cmd646.c | 5 +++-- hw/ide/via.c| 5 +++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index e8dcc6b..909899d 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2055,8 +2055,8 @@ static void cirrus_vga_mem_write(void *opaque, } } else { #ifdef DEBUG_CIRRUS -printf(cirrus: mem_writeb TARGET_FMT_plx value %02x\n, addr, - mem_value); +printf(cirrus: mem_writeb TARGET_FMT_plx value % PRIx64 \n, + addr, mem_value); This one is dropping 02. The other ones looks okay on brief look (declaration of value invisible). Regards, Andreas #endif } } diff --git a/hw/i8259.c b/hw/i8259.c index 53daf78..6587666 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -355,7 +355,8 @@ static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr, ret = s-imr; } } -DPRINTF(read: addr=0x%02x val=0x%02x\n, addr, ret); +DPRINTF(read: addr=0x%02 TARGET_PRIxPHYS val=0x%02x\n, +addr, ret); return ret; } diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index e0b9443..dd2855e 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -154,7 +154,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, break; } #ifdef DEBUG_IDE -printf(bmdma: readb 0x%02x : 0x%02x\n, addr, val); +printf(bmdma: readb 0x%02 TARGET_PRIxPHYS : 0x%02x\n, addr, val); #endif return val; } @@ -170,7 +170,8 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE -printf(bmdma: writeb 0x%02x : 0x%02x\n, addr, val); +printf(bmdma: writeb 0x%02 TARGET_PRIxPHYS : 0x%02 PRIx64 \n, + addr, val); #endif switch(addr 3) { case 0: diff --git a/hw/ide/via.c b/hw/ide/via.c index b20e4f0..948a469 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -55,7 +55,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, break; } #ifdef DEBUG_IDE -printf(bmdma: readb 0x%02x : 0x%02x\n, addr, val); +printf(bmdma: readb 0x%02 TARGET_PRIxPHYS : 0x%02x\n, addr, val); #endif return val; } @@ -70,7 +70,8 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE -printf(bmdma: writeb 0x%02x : 0x%02x\n, addr, val); +printf(bmdma: writeb 0x%02 TARGET_PRIxPHYS : 0x%02 PRIx64 \n, + addr, val); #endif switch (addr 3) { case 0: -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v2] kvm-all.c: Move init of irqchip_inject_ioctl out of kvm_irqchip_create()
On Tue, Aug 21, 2012 at 12:27:51PM +0200, Jan Kiszka wrote: On 2012-08-21 10:25, Peter Maydell wrote: On 21 August 2012 09:19, Jan Kiszka jan.kis...@siemens.com wrote: On 2012-08-15 13:08, Peter Maydell wrote: Move the init of the irqchip_inject_ioctl field of KVMState out of kvm_irqchip_create() and into kvm_init(), so that kvm_set_irq() can be used even when no irqchip is created (for architectures that support async interrupt notification even without an in kernel irqchip). As it's not yet merged, some late comment: irqchip_inject_ioctl should be renamed as well. irq_inject_ioctl? If we're changing it anyway, IIRC Avi didn't like the term inject here? Then irq_set_ioctl. Jan It is merged, please send a follow patch.
Re: [Qemu-devel] [PATCH] boards: add a 'none' machine type to all platforms
Am 23.08.2012 00:42, schrieb Anthony Liguori: Peter Maydell peter.mayd...@linaro.org writes: On 22 August 2012 21:24, Anthony Liguori aligu...@us.ibm.com wrote: This allows any QEMU binary to be executed with: $QEMU_BINARY -qmp stdio ...presumably you mean -qmp stdio -M none ? Without errors from missing options that are required by various boards. This also provides a mode that we can use in the future to construct machines entirely through QMP commands. How about documenting this machine (and its purpose) somewhere? Okay, but where? I don't know an obvious place. Cc: Daniel Berrange berra...@redhat.com Cc: Markus Armbruster arm...@redhat.com Signed-off-by: Anthony Liguori aligu...@us.ibm.com --- hw/Makefile.objs |2 ++ hw/null-machine.c | 40 2 files changed, 42 insertions(+), 0 deletions(-) create mode 100644 hw/null-machine.c diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 7f57ed5..6dfebd2 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -134,6 +134,8 @@ hw-obj-$(CONFIG_DP8393X) += dp8393x.o hw-obj-$(CONFIG_DS1225Y) += ds1225y.o hw-obj-$(CONFIG_MIPSNET) += mipsnet.o +hw-obj-y += null-machine.o + # Sound sound-obj-y = sound-obj-$(CONFIG_SB16) += sb16.o diff --git a/hw/null-machine.c b/hw/null-machine.c new file mode 100644 index 000..69910d3 --- /dev/null +++ b/hw/null-machine.c @@ -0,0 +1,40 @@ +/* + * Empty machine + * + * Copyright IBM, Corp. 2012 + * + * Authors: + * Anthony Liguori aligu...@us.ibm.com + * + * 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 qemu-common.h +#include hw/hw.h +#include hw/boards.h + +static void machine_none_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) +{ +} + +static QEMUMachine machine_none = { +.name = none, +.desc = empty machine, +.init = machine_none_init, +.max_cpus = 0, +}; + +static void register_machines(void) +{ +qemu_register_machine(machine_none); +} + +machine_init(register_machines); We seem to be about evenly split about whether machine_init() should have a trailing semicolon (it doesn't need one but it doesn't hurt either...) It's obviously superior to use a semicolon... C is completely consistent synactically about the usage of semicolons afterall :-) I disagree. This macro does not turn into a statement but a full function definition. Neither our Coding Style nor any other that I know does void foo(bar baz) { }; with a trailing semicolon. For type_init() I cleaned this up, and I attribute the existing semicolons to people's ignorance of what these macros actually do. You might remember that Eduardo and I wanted to QOM'ify machines so that machine_init() would get replaced with type_init() but you stopped us at the time, leaving it untouched. So there's no strict need to go through and change existing users, but I believe in setting good examples. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 1/2 v1] blkdrv: Add queue limits parameters for sg block drive
On Thu, Aug 23, 2012 at 11:52 AM, Paolo Bonzini pbonz...@redhat.com wrote: Il 23/08/2012 12:08, Stefan Hajnoczi ha scritto: I'm still trying to understand the extent of the problem. The problem occurs for _USB_ CD-ROMs according to Ben. Passthrough of USB storage devices should be done via USB passthrough, not virtio-scsi. If we do USB passthrough via the SCSI layer we miss on all the quirks that the OS may do based on the USB product/vendor pairs. There's no end to these, and some of the quirks may cause the device to lock up or corruption. I'd rather see a reproducer using SAS/ATA/ATAPI disks before punting. This issue affects passthrough: either an entire sg device or at least a SG_IO ioctl (e.g. a non-READ/WRITE SCSI command). To reproduce it, check host queue limits and guest virtio-scsi queue limits. Then pick a command that can exceed the limits and try it from inside the guest :). Yes, so much is clear. But does it happen _in practice_? Do initiators actually issue commands that are that big? Here I think we need to err on the side of caution. A user passes through a tape drive or exotic SCSI device. They run a vendor utility inside the guest that issues a command that exceeds the host block queue limits. Passing through limits is intended to make SCSI device passthrough work, in all cases. Is the number of real cases where it happens small? Probably. I still think we should make passthrough bulletproof. Stefan
Re: [Qemu-devel] [RFC][PATCH] qemu-timer: Run timers in alarm timer handler
On 2012-08-23 13:39, Paolo Bonzini wrote: Il 23/08/2012 13:23, Jan Kiszka ha scritto: No need for this indirection via qemu_notify_event. On Unix, we already catch SIGALRM via signalfd (or its emulation) and run the handler synchronously. Under Win32, handlers run in separate threads. So we just need to grab the global lock around the handler execution. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- The Unix side looks safe to me, but I'm not yet 100% confident about Win32. This is part of an ongoing effort to create separate alarm timers over their own io-threads. A lengthy effort. Can you expand on this? Well, this patch removes an indirection from timer event deliveries. So it reduces overhead, though only noticeable if you have high-rate timers. The Win32 bits look fine, but it's a bit scary to make the Unix and Win32 paths so different. It works well until we have a BQL for timers, but would this complicate shrinking the scope of the BQL? Nope, not yet. We continue to hold the BQL across qemu_run_all_timers. Under Unix, this happens as qemu_iohandler_poll-sigfd_handler- host_alarm_handler runs under BQL, under win32 due to explicit locking. The plan is to only pull specifically marked alarm timers out of this standard path, in the future. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [RFC][PATCH] qemu-timer: Run timers in alarm timer handler
Il 23/08/2012 14:10, Jan Kiszka ha scritto: Can you expand on this? Well, this patch removes an indirection from timer event deliveries. So it reduces overhead, though only noticeable if you have high-rate timers. Actually, timers (and bottom halves) are always run after iohandlers. So the qemu_notify_event should already be completely useless for Unix, even if we leave the host_alarm_handler indirection. But this leaves out Windows, where your next task of (IIUC) having multiple instances of struct qemu_alarm_timer would be complicated by the qemu_notify_event. I guess this is the original reason for your patch. So, in order to remove the qemu_notify_event completely, what about not using signals anymore for timers? You could just tweak the select timeout and drop all the -clock madness. Zero syscalls, practically no overhead. If this is not precise enough, use timerfd on Linux only (BTW, switching to an absolute deadline would be useful too). The Win32 bits look fine, but it's a bit scary to make the Unix and Win32 paths so different. It works well until we have a BQL for timers, but would this complicate shrinking the scope of the BQL? Nope, not yet. We continue to hold the BQL across qemu_run_all_timers. Under Unix, this happens as qemu_iohandler_poll-sigfd_handler- host_alarm_handler runs under BQL, under win32 due to explicit locking. The plan is to only pull specifically marked alarm timers out of this standard path, in the future. Ok, thanks for clarifying. Paolo
[Qemu-devel] [PATCH 0/2] Add file url support to migration
This patchset add support of file: urls allowing a user to save to and restore from disk the state of a vm in an easy way. An fflush was added before closing the fd for this use case in order to be sure that all data have reached stable storage. One new usage would be migrating between two virtualizer which share only the storage but do not see each other on the network. (cisco pvlan for example) Benoît Canet (2): migration: Allow the migrate command to work on file: urls migration: Allow -incoming to work on file: urls migration-fd.c |9 - migration.c| 34 -- migration.h|4 ++-- 3 files changed, 38 insertions(+), 9 deletions(-) -- 1.7.9.5
[Qemu-devel] [PATCH 1/2] migration: Allow the migrate command to work on file: urls
Usage: (qemu) migrate file:/path/to/vm_statefile Signed-off-by: Benoit Canet ben...@irqsave.net --- migration-fd.c |4 ++-- migration.c| 20 +++- migration.h|2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/migration-fd.c b/migration-fd.c index 50138ed..d39e44a 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -73,9 +73,9 @@ static int fd_close(MigrationState *s) return 0; } -int fd_start_outgoing_migration(MigrationState *s, const char *fdname) +int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd) { -s-fd = monitor_get_fd(cur_mon, fdname); +s-fd = fd ? fd : monitor_get_fd(cur_mon, fdname); if (s-fd == -1) { DPRINTF(fd_migration: invalid file descriptor identifier\n); goto err_after_get_fd; diff --git a/migration.c b/migration.c index 1edeec5..679847d 100644 --- a/migration.c +++ b/migration.c @@ -239,9 +239,14 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; +struct stat st; qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL); +if (!fstat(s-fd, st) S_ISREG(st.st_mode)) { +fsync(s-fd); +} + if (s-file) { DPRINTF(closing file\n); ret = qemu_fclose(s-file); @@ -475,6 +480,17 @@ void migrate_del_blocker(Error *reason) migration_blockers = g_slist_remove(migration_blockers, reason); } +static int file_start_outgoing_migration(MigrationState *s, + const char *filename) +{ +int fd; +fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR); +if (fd 0) { +return -errno; +} +return fd_start_outgoing_migration(s, NULL, fd); +} + void qmp_migrate(const char *uri, bool has_blk, bool blk, bool has_inc, bool inc, bool has_detach, bool detach, Error **errp) @@ -511,7 +527,9 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, } else if (strstart(uri, unix:, p)) { ret = unix_start_outgoing_migration(s, p); } else if (strstart(uri, fd:, p)) { -ret = fd_start_outgoing_migration(s, p); +ret = fd_start_outgoing_migration(s, p, 0); +} else if (strstart(uri, file:, p)) { +ret = file_start_outgoing_migration(s, p); #endif } else { error_set(errp, QERR_INVALID_PARAMETER_VALUE, uri, a valid migration protocol); diff --git a/migration.h b/migration.h index a9852fc..d431284 100644 --- a/migration.h +++ b/migration.h @@ -69,7 +69,7 @@ int unix_start_outgoing_migration(MigrationState *s, const char *path); int fd_start_incoming_migration(const char *path); -int fd_start_outgoing_migration(MigrationState *s, const char *fdname); +int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd); void migrate_fd_error(MigrationState *s); -- 1.7.9.5
[Qemu-devel] [PATCH 2/2] migration: Allow -incoming to work on file: urls
Usage: -incoming file:/path/to/vm_statefile Signed-off-by: Benoit Canet ben...@irqsave.net --- migration-fd.c |5 ++--- migration.c| 14 +- migration.h|2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/migration-fd.c b/migration-fd.c index d39e44a..bf500a0 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -108,14 +108,13 @@ static void fd_accept_incoming_migration(void *opaque) qemu_fclose(f); } -int fd_start_incoming_migration(const char *infd) +int fd_start_incoming_migration(const char *infd, int fd) { -int fd; QEMUFile *f; DPRINTF(Attempting to start an incoming migration via fd\n); -fd = strtol(infd, NULL, 0); +fd = fd ? fd : strtol(infd, NULL, 0); f = qemu_fdopen(fd, rb); if(f == NULL) { DPRINTF(Unable to apply qemu wrapper to file descriptor\n); diff --git a/migration.c b/migration.c index 679847d..e4b228e 100644 --- a/migration.c +++ b/migration.c @@ -64,6 +64,16 @@ static MigrationState *migrate_get_current(void) return current_migration; } +static int file_start_incoming_migration(const char *filename) +{ +int fd; +fd = open(filename, O_RDONLY); +if (fd 0) { +return -errno; +} +return fd_start_incoming_migration(NULL, fd); +} + int qemu_start_incoming_migration(const char *uri, Error **errp) { const char *p; @@ -77,7 +87,9 @@ int qemu_start_incoming_migration(const char *uri, Error **errp) else if (strstart(uri, unix:, p)) ret = unix_start_incoming_migration(p); else if (strstart(uri, fd:, p)) -ret = fd_start_incoming_migration(p); +ret = fd_start_incoming_migration(p, 0); +else if (strstart(uri, file:, p)) +ret = file_start_incoming_migration(p); #endif else { fprintf(stderr, unknown migration protocol: %s\n, uri); diff --git a/migration.h b/migration.h index d431284..dbdaf72 100644 --- a/migration.h +++ b/migration.h @@ -67,7 +67,7 @@ int unix_start_incoming_migration(const char *path); int unix_start_outgoing_migration(MigrationState *s, const char *path); -int fd_start_incoming_migration(const char *path); +int fd_start_incoming_migration(const char *path, int fd); int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd); -- 1.7.9.5
Re: [Qemu-devel] [PATCH 2/5] trace-cmd: Use tracing directory to count CPUs
(2012/08/23 18:08), Steven Rostedt wrote: On Thu, 2012-08-23 at 12:00 +0900, Masami Hiramatsu wrote: (2012/08/23 11:01), Masami Hiramatsu wrote: (2012/08/22 22:41), Steven Rostedt wrote: On Wed, 2012-08-22 at 17:43 +0900, Yoshihiro YUNOMAE wrote: From: Masami Hiramatsu masami.hiramatsu...@hitachi.com Count debugfs/tracing/per_cpu/cpu* to determine the number of CPUs. I'm curious, do you find that sysconf doesn't return the # of CPUs the system has? No, sysconf returns the number of hosts CPUs, not guests. I've had boxes where the per_cpu/cpu* had more cpus than the box actually holds. But this was a bug in the kernel, not the tool. This change log needs to have rational instead of just explaining what the patch does. Ah, I see. Hmm, then this should be enabled by a command line option or an environment variable. Oops, I misunderstood. I'll add more comment for why this should be tried instead of sysconf. And now that I understand why you are doing this, why not only do this if the TRACE_AGENT or DEBUG_TRACING_DIR is defined. That is, if we are doing it against a bare metal system, then sysconf should suffice, but if we are tracing against a guest, then it should use the tracing directory to determine the buffers. We could add options to override this, but I would think the default should just Do The Right Thing(tm). Yeah, so I'd like to push this is the default method, and fix the kernel bug (but I'm not sure that is a bug). Thank you, -- Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: masami.hiramatsu...@hitachi.com
Re: [Qemu-devel] [PATCH 1/2] migration: Allow the migrate command to work on file: urls
On Thu, Aug 23, 2012 at 02:28:07PM +0200, Benoît Canet wrote: Usage: (qemu) migrate file:/path/to/vm_statefile Signed-off-by: Benoit Canet ben...@irqsave.net --- migration-fd.c |4 ++-- migration.c| 20 +++- migration.h|2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/migration-fd.c b/migration-fd.c index 50138ed..d39e44a 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -73,9 +73,9 @@ static int fd_close(MigrationState *s) return 0; } -int fd_start_outgoing_migration(MigrationState *s, const char *fdname) +int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd) { -s-fd = monitor_get_fd(cur_mon, fdname); +s-fd = fd ? fd : monitor_get_fd(cur_mon, fdname); if (s-fd == -1) { DPRINTF(fd_migration: invalid file descriptor identifier\n); goto err_after_get_fd; diff --git a/migration.c b/migration.c index 1edeec5..679847d 100644 --- a/migration.c +++ b/migration.c @@ -239,9 +239,14 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; +struct stat st; qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL); +if (!fstat(s-fd, st) S_ISREG(st.st_mode)) { +fsync(s-fd); +} + if (s-file) { DPRINTF(closing file\n); ret = qemu_fclose(s-file); @@ -475,6 +480,17 @@ void migrate_del_blocker(Error *reason) migration_blockers = g_slist_remove(migration_blockers, reason); } +static int file_start_outgoing_migration(MigrationState *s, + const char *filename) +{ +int fd; +fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR); +if (fd 0) { +return -errno; +} +return fd_start_outgoing_migration(s, NULL, fd); 'fd_start_outgoing_migration' requires that the FD you give it supports non-blocking I/O. File descriptors opened from plain files or block devices do not honour that requirement. So this proposed code will cause the entire QEMU process to block while migration is taking place. This is why no on has ever implemented the 'file:' protocol in QEMU before. To deal with this issue you'd either have to use the POSIX async I/O APIs (or QEMU's internal equivalent), or spawn a separate 'dd' helper process and give QEMU a pipe FD instead. The latter is what libvirt does to implement migrate to file. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
[Qemu-devel] [PATCH V5 1/2] qapi: Add SnapshotInfo and ImageInfo.
Signed-off-by: Benoit Canet ben...@irqsave.net --- qapi-schema.json | 64 ++ 1 file changed, 64 insertions(+) diff --git a/qapi-schema.json b/qapi-schema.json index a92adb1..ffe3a0a 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -126,6 +126,70 @@ 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } ## +# @SnapshotInfo +# +# @id: unique snapshot id +# +# @name: user chosen name +# +# @vm-state-size: size of the VM state +# +# @date-sec: UTC date of the snapshot in seconds +# +# @date-nsec: fractional part in nano seconds to be used with date-sec +# +# @vm-clock-sec: VM clock relative to boot in seconds +# +# @vm-clock-nsec: fractional part in nano seconds to be used with vm-clock-sec +# +# Since: 1.3 +# +## + +{ 'type': 'SnapshotInfo', + 'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int', +'date-sec': 'int', 'date-nsec': 'int', +'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } } + +## +# @ImageInfo: +# +# Information about a QEMU image file +# +# @filename: name of the image file +# +# @format: format of the image file +# +# @virtual-size: maximum capacity in bytes of the image +# +# @actual-size: #optional actual size on disk in bytes of the image +# +# @dirty-flag: #optional true if image is not cleanly closed +# +# @cluster-size: #optional size of a cluster in bytes +# +# @encrypted: #optional true if the image is encrypted +# +# @backing-filename: #optional name of the backing file +# +# @full-backing-filename: #optional full path of the backing file +# +# @backing-filename-format: #optional the format of the backing file +# +# @snapshots: #optional list of VM snapshots +# +# Since: 1.3 +# +## + +{ 'type': 'ImageInfo', + 'data': {'filename': 'str', 'format': 'str', '*dirty-flag': 'bool', + '*actual-size': 'int', 'virtual-size': 'int', + '*cluster-size': 'int', '*encrypted': 'bool', + '*backing-filename': 'str', '*full-backing-filename': 'str', + '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'] } } + +## # @StatusInfo: # # Information about VCPU run state -- 1.7.9.5
[Qemu-devel] [PATCH V5 0/2] Add JSON output to qemu-img info
This patchset add a JSON output mode to the qemu-img info command. It's a rewrite from scratch of the original patchset by Wenchao Xia following Anthony Liguori advices on JSON formating. the --output=(json|human) option is now mandatory on the command line. Benoît Canet (3): qapi: Add SnapshotInfo. qapi: Add ImageInfo. qemu-img: Add json output option to the info command. in v2: eblake: make some field optionals squash the two qapi patchs together fix a typo on vm_clock_nsec bcanet: fix a potential memory leak in v3: lcapitulino: remove unneeded test put '\n' at the end of json in printf statement drop the uneeded head pointer in collect_snapshots in v4: Wenchao Xia Kevin Wolf: -Refactor to separate rate ImageInfo collection from human printing. Kevin Wolf: -Use --output=(json|human). -make the two choice exclusive and print a message if none is specified. -cosmetic '=' alignement in collect snapshots. Benoît Canet: -add full-backing-filename to the ImageInfo structure (needed for human printing) -make ImageInfo-actual_size optional depending on the context. in v5: Eric Blake: -use a constant for getopt parsing to avoid future short options collision. -make the command default to --output=human. -fix spurious whitespace change. -split vm-clock-nsec in two fields vm-clock-sec and vm-clock-nsec. -declare JSON structure as Since 1.3 Benoît Canet (2): qapi: Add SnapshotInfo and ImageInfo. qemu-img: Add json output option to the info command. Makefile |3 +- qapi-schema.json | 64 ++ qemu-img.c | 256 +- 3 files changed, 279 insertions(+), 44 deletions(-) -- 1.7.9.5
[Qemu-devel] [PATCH V5 2/2] qemu-img: Add json output option to the info command.
This option --output=[human|json] make qemu-img info output on human or JSON representation at the choice of the user. example: { snapshots: [ { vm-clock-nsec: 637102488, name: vm-20120821145509, date-sec: 1345553709, date-nsec: 220289000, vm-clock-sec: 20, id: 1, vm-state-size: 96522745 }, { vm-clock-nsec: 28210866, name: vm-20120821154059, date-sec: 1345556459, date-nsec: 171392000, vm-clock-sec: 46, id: 2, vm-state-size: 101208714 } ], virtual-size: 1073741824, filename: snap.qcow2, cluster-size: 65536, format: qcow2, actual-size: 985587712, dirty-flag: false } Signed-off-by: Benoit Canet ben...@irqsave.net --- Makefile |3 +- qemu-img.c | 256 ++-- 2 files changed, 215 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index ab82ef3..9ba064b 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,8 @@ tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \ iohandler.o cutils.o iov.o async.o tools-obj-$(CONFIG_POSIX) += compatfd.o -qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y) +qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y) $(qapi-obj-y) \ + qapi-visit.o qapi-types.o qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y) qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) diff --git a/qemu-img.c b/qemu-img.c index 80cfb9b..b2374f1 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -21,12 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include qapi-visit.h +#include qapi/qmp-output-visitor.h +#include qjson.h #include qemu-common.h #include qemu-option.h #include qemu-error.h #include osdep.h #include sysemu.h #include block_int.h +#include getopt.h #include stdio.h #ifdef _WIN32 @@ -84,6 +88,7 @@ static void help(void) '-p' show progress of command (only certain commands)\n '-S' indicates the consecutive number of bytes that must contain only zeros\n for qemu-img to create a sparse image during conversion\n + '--output' takes the format in which the output must be done (human or json)\n \n Parameters to check subcommand:\n '-r' tries to repair any inconsistencies that are found during the check.\n @@ -1102,21 +1107,191 @@ static void dump_snapshots(BlockDriverState *bs) g_free(sn_tab); } -static int img_info(int argc, char **argv) +static void collect_snapshots(BlockDriverState *bs , ImageInfo *info) +{ +int i, sn_count; +QEMUSnapshotInfo *sn_tab = NULL; +SnapshotInfoList *info_list, *cur_item = NULL; +sn_count = bdrv_snapshot_list(bs, sn_tab); + +for (i = 0; i sn_count; i++) { +info-has_snapshots = true; +info_list = g_new0(SnapshotInfoList, 1); + +info_list-value= g_new0(SnapshotInfo, 1); +info_list-value-id= g_strdup(sn_tab[i].id_str); +info_list-value-name = g_strdup(sn_tab[i].name); +info_list-value-vm_state_size = sn_tab[i].vm_state_size; +info_list-value-date_sec = sn_tab[i].date_sec; +info_list-value-date_nsec = sn_tab[i].date_nsec; +info_list-value-vm_clock_sec = sn_tab[i].vm_clock_nsec / 10; +info_list-value-vm_clock_nsec = sn_tab[i].vm_clock_nsec % 10; + +/* XXX: waiting for the qapi to support GSList */ +if (!cur_item) { +info-snapshots = cur_item = info_list; +} else { +cur_item-next = info_list; +cur_item = info_list; +} + +} + +g_free(sn_tab); +} + +static void dump_json_image_info(ImageInfo *info) +{ +Error *errp = NULL; +QString *str; +QmpOutputVisitor *ov = qmp_output_visitor_new(); +QObject *obj; +visit_type_ImageInfo(qmp_output_get_visitor(ov), + info, NULL, errp); +obj = qmp_output_get_qobject(ov); +str = qobject_to_json_pretty(obj); +assert(str != NULL); +printf(%s\n, qstring_get_str(str)); +qobject_decref(obj); +qmp_output_visitor_cleanup(ov); +QDECREF(str); +} + +static void collect_backing_file_format(ImageInfo *info, char *filename) +{ +BlockDriverState *bs = NULL; +bs = bdrv_new_open(filename, NULL, + BDRV_O_FLAGS | BDRV_O_NO_BACKING); +if (!bs) { +return; +} +info-backing_filename_format = +g_strdup(bdrv_get_format_name(bs)); +bdrv_delete(bs); +info-has_backing_filename_format = true; +} + +static void collect_image_info(BlockDriverState *bs, + ImageInfo *info, + const char
Re: [Qemu-devel] [PATCH] Add guest-get-hostname to retrieve the guests current hostname
On Tue, 21 Aug 2012 13:57:54 +0200 Guido Günther a...@sigxcpu.org wrote: This allows to retrieve the guest's hostname via gethostname(2). This can be useful to identify a VM e.g. one without network. Signed-off-by: Guido Günther a...@sigxcpu.org --- We have an API in libvirt for that (virDomainGetHostname). Cheers -- Guido qapi-schema-guest.json | 12 qga/commands-posix.c | 12 qga/commands-win32.c |6 ++ 3 files changed, 30 insertions(+) diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json index d955cf1..8c7a4a5 100644 --- a/qapi-schema-guest.json +++ b/qapi-schema-guest.json @@ -515,3 +515,15 @@ ## { 'command': 'guest-network-get-interfaces', 'returns': ['GuestNetworkInterface'] } + +## +# @guest-get-hostname: +# +# Get the guest's hostname +# +# Returns: The guest's hostname +# +# Since: 1.2 Won't make it for 1.2 because we're in hard-freeze. +## +{ 'command': 'guest-get-hostname', + 'returns': 'str' } diff --git a/qga/commands-posix.c b/qga/commands-posix.c index ce90421..9223f18 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -15,6 +15,7 @@ #include sys/types.h #include sys/ioctl.h #include sys/wait.h +#include unistd.h #include qga/guest-agent-core.h #include qga-qmp-commands.h #include qerror.h @@ -993,6 +994,17 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err) } #endif +char *qmp_guest_get_hostname(Error **err) +{ +char hostname[HOST_NAME_MAX]; + +if (gethostname(hostname, HOST_NAME_MAX)) { +error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno)); You shouldn't use that macro, you can do something like this instead: error_set(err, can't get hostname: %s, strerror(errno)); Michael, do you think that's fine for new error messages or do you think it's worth it to add a guest-agent: prefix to all guest agent error messages? +return NULL; +} +return g_strdup(hostname); +} + /* register init/cleanup routines for stateful command groups */ void ga_command_state_init(GAState *s, GACommandState *cs) { diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 54bc546..55e8162 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -280,6 +280,12 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **err) return NULL; } +char *qmp_guest_get_hostname(Error **err) +{ +error_set(err, QERR_UNSUPPORTED); +return NULL; +} + /* register init/cleanup routines for stateful command groups */ void ga_command_state_init(GAState *s, GACommandState *cs) {
Re: [Qemu-devel] [PATCH] i2c: factor out VMSD to parent class
Peter Crosthwaite peter.crosthwa...@petalogix.com wrote: - I guess there is same reasy why you want to split the device state, it could be on the other series where I haven't read it though. So this is exactly what I have done in the SSI. Correct me if I am wrong but it is the same setup as PCI where the VMSTATE_PCI_DEVICE (VMSTATE_SSI_SLAVE in my case) is the first field. All I need to do is bump version numbers? I think so. What boards normally use SSI? Tracing all the calls to ssi_create_bus() at the moment we have stellaris, spitz, highbank, gumstix, mainstone, z2, tosa collie. Then we can change it without regards to backwards compatibility (migration is still not working correctly there), so backwards compatibility is the less of the troubles. Later, Juan.
Re: [Qemu-devel] [PATCH 1/2] migration: Allow the migrate command to work on file: urls
Le Thursday 23 Aug 2012 à 13:34:01 (+0100), Daniel P. Berrange a écrit : On Thu, Aug 23, 2012 at 02:28:07PM +0200, Benoît Canet wrote: Usage: (qemu) migrate file:/path/to/vm_statefile Signed-off-by: Benoit Canet ben...@irqsave.net --- migration-fd.c |4 ++-- migration.c| 20 +++- migration.h|2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/migration-fd.c b/migration-fd.c index 50138ed..d39e44a 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -73,9 +73,9 @@ static int fd_close(MigrationState *s) return 0; } -int fd_start_outgoing_migration(MigrationState *s, const char *fdname) +int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd) { -s-fd = monitor_get_fd(cur_mon, fdname); +s-fd = fd ? fd : monitor_get_fd(cur_mon, fdname); if (s-fd == -1) { DPRINTF(fd_migration: invalid file descriptor identifier\n); goto err_after_get_fd; diff --git a/migration.c b/migration.c index 1edeec5..679847d 100644 --- a/migration.c +++ b/migration.c @@ -239,9 +239,14 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; +struct stat st; qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL); +if (!fstat(s-fd, st) S_ISREG(st.st_mode)) { +fsync(s-fd); +} + if (s-file) { DPRINTF(closing file\n); ret = qemu_fclose(s-file); @@ -475,6 +480,17 @@ void migrate_del_blocker(Error *reason) migration_blockers = g_slist_remove(migration_blockers, reason); } +static int file_start_outgoing_migration(MigrationState *s, + const char *filename) +{ +int fd; +fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR); +if (fd 0) { +return -errno; +} +return fd_start_outgoing_migration(s, NULL, fd); 'fd_start_outgoing_migration' requires that the FD you give it supports non-blocking I/O. File descriptors opened from plain files or block devices do not honour that requirement. So this proposed code will cause the entire QEMU process to block while migration is taking place. This is why no on has ever implemented the 'file:' protocol in QEMU before. When I run the code it appear it does not block all the time. (guest is still interactive most of the time needed to complete migration) How can it be ? Benoît To deal with this issue you'd either have to use the POSIX async I/O APIs (or QEMU's internal equivalent), or spawn a separate 'dd' helper process and give QEMU a pipe FD instead. The latter is what libvirt does to implement migrate to file. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
[Qemu-devel] [PATCH v4] ivshmem: add 64bit option
This patch adds a use64 property which will make the ivshmem driver register a 64bit memory bar when set, so you have something to play with when testing 64bit pci bits. It also allows to have quite big shared memory regions, like this: [root@fedora ~]# lspci -vs1:1 01:01.0 RAM memory: Red Hat, Inc Device 1110 Subsystem: Red Hat, Inc Device 1100 Physical Slot: 1-1 Flags: fast devsel Memory at fd40 (32-bit, non-prefetchable) [disabled] [size=256] Memory at 804000 (64-bit, prefetchable) [size=1G] [ v4: rebase adapt to latest master again ] [ v3: rebase adapt to latest master ] [ v2: default to on as suggested by avi, turn off for pc-$old using compat property ] Signed-off-by: Gerd Hoffmann kra...@redhat.com Tested-by: Cam Macdonell c...@cs.ualberta.ca --- hw/ivshmem.c | 13 ++--- hw/pc_piix.c |4 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/hw/ivshmem.c b/hw/ivshmem.c index b4d65a6..8c45aa6 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -71,6 +71,8 @@ typedef struct IVShmemState { MemoryRegion bar; MemoryRegion ivshmem; uint64_t ivshmem_size; /* size of shared memory region */ +uint32_t ivshmem_attr; +uint32_t ivshmem_64bit; int shm_fd; /* shared memory file descriptor */ Peer *peers; @@ -339,7 +341,7 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) { memory_region_add_subregion(s-bar, 0, s-ivshmem); /* region for shared memory */ -pci_register_bar(s-dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, s-bar); +pci_register_bar(s-dev, 2, s-ivshmem_attr, s-bar); } static void ivshmem_add_eventfd(IVShmemState *s, int posn, int i) @@ -701,6 +703,11 @@ static int pci_ivshmem_init(PCIDevice *dev) s-ivshmem_mmio); memory_region_init(s-bar, ivshmem-bar2-container, s-ivshmem_size); +s-ivshmem_attr = PCI_BASE_ADDRESS_SPACE_MEMORY | +PCI_BASE_ADDRESS_MEM_PREFETCH; +if (s-ivshmem_64bit) { +s-ivshmem_attr |= PCI_BASE_ADDRESS_MEM_TYPE_64; +} if ((s-server_chr != NULL) (strncmp(s-server_chr-filename, unix:, 5) == 0)) { @@ -726,8 +733,7 @@ static int pci_ivshmem_init(PCIDevice *dev) /* allocate/initialize space for interrupt handling */ s-peers = g_malloc0(s-nb_peers * sizeof(Peer)); -pci_register_bar(s-dev, 2, - PCI_BASE_ADDRESS_SPACE_MEMORY, s-bar); +pci_register_bar(s-dev, 2, s-ivshmem_attr, s-bar); s-eventfd_chr = g_malloc0(s-vectors * sizeof(CharDriverState *)); @@ -797,6 +803,7 @@ static Property ivshmem_properties[] = { DEFINE_PROP_BIT(msi, IVShmemState, features, IVSHMEM_MSI, true), DEFINE_PROP_STRING(shm, IVShmemState, shmobj), DEFINE_PROP_STRING(role, IVShmemState, role), +DEFINE_PROP_UINT32(use64, IVShmemState, ivshmem_64bit, 1), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 88ff041..c7fbaa0 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -387,6 +387,10 @@ static QEMUMachine pc_machine_v1_2 = { .driver = virtio-blk-pci,\ .property = config-wce,\ .value= off,\ +},{\ +.driver = ivshmem,\ +.property = use64,\ +.value= 0,\ } static QEMUMachine pc_machine_v1_1 = { -- 1.7.1
Re: [Qemu-devel] [PATCH 1/2] migration: Allow the migrate command to work on file: urls
On Thu, Aug 23, 2012 at 02:48:19PM +0200, Benoît Canet wrote: Le Thursday 23 Aug 2012 à 13:34:01 (+0100), Daniel P. Berrange a écrit : On Thu, Aug 23, 2012 at 02:28:07PM +0200, Benoît Canet wrote: Usage: (qemu) migrate file:/path/to/vm_statefile Signed-off-by: Benoit Canet ben...@irqsave.net --- migration-fd.c |4 ++-- migration.c| 20 +++- migration.h|2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/migration-fd.c b/migration-fd.c index 50138ed..d39e44a 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -73,9 +73,9 @@ static int fd_close(MigrationState *s) return 0; } -int fd_start_outgoing_migration(MigrationState *s, const char *fdname) +int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd) { -s-fd = monitor_get_fd(cur_mon, fdname); +s-fd = fd ? fd : monitor_get_fd(cur_mon, fdname); if (s-fd == -1) { DPRINTF(fd_migration: invalid file descriptor identifier\n); goto err_after_get_fd; diff --git a/migration.c b/migration.c index 1edeec5..679847d 100644 --- a/migration.c +++ b/migration.c @@ -239,9 +239,14 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; +struct stat st; qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL); +if (!fstat(s-fd, st) S_ISREG(st.st_mode)) { +fsync(s-fd); +} + if (s-file) { DPRINTF(closing file\n); ret = qemu_fclose(s-file); @@ -475,6 +480,17 @@ void migrate_del_blocker(Error *reason) migration_blockers = g_slist_remove(migration_blockers, reason); } +static int file_start_outgoing_migration(MigrationState *s, + const char *filename) +{ +int fd; +fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR); +if (fd 0) { +return -errno; +} +return fd_start_outgoing_migration(s, NULL, fd); 'fd_start_outgoing_migration' requires that the FD you give it supports non-blocking I/O. File descriptors opened from plain files or block devices do not honour that requirement. So this proposed code will cause the entire QEMU process to block while migration is taking place. This is why no on has ever implemented the 'file:' protocol in QEMU before. When I run the code it appear it does not block all the time. (guest is still interactive most of the time needed to complete migration) How can it be ? The default migration bandwidth limit means qemu throttles the rate at which it sends data, so you won't notice the flaw with I/O blocking. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
Re: [Qemu-devel] [RFC][PATCH] qemu-timer: Run timers in alarm timer handler
On 2012-08-23 14:24, Paolo Bonzini wrote: Il 23/08/2012 14:10, Jan Kiszka ha scritto: Can you expand on this? Well, this patch removes an indirection from timer event deliveries. So it reduces overhead, though only noticeable if you have high-rate timers. Actually, timers (and bottom halves) are always run after iohandlers. So the qemu_notify_event should already be completely useless for Unix, even if we leave the host_alarm_handler indirection. Is there anything that requires this ordering for timers? But this leaves out Windows, where your next task of (IIUC) having multiple instances of struct qemu_alarm_timer would be complicated by the qemu_notify_event. I guess this is the original reason for your patch. I'm not heading for multi-instance alarm timers or any kind of optimization on Windows. It should just continue to work. Windows is neither a high-performance nor a real-time platform for QEMU, IMHO. So, in order to remove the qemu_notify_event completely, what about not using signals anymore for timers? You could just tweak the select timeout and drop all the -clock madness. Zero syscalls, practically no overhead. If this is not precise enough, use timerfd on Linux only Need to think about it. At least, real-time tasks will get proper precision on Linux. Not sure if it will be sufficient on other hosts. (BTW, switching to an absolute deadline would be useful too). Why? We aren't affected by clock adjustment with relative timeouts. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH] boards: add a 'none' machine type to all platforms
Andreas Färber afaer...@suse.de writes: Am 23.08.2012 00:42, schrieb Anthony Liguori: Peter Maydell peter.mayd...@linaro.org writes: On 22 August 2012 21:24, Anthony Liguori aligu...@us.ibm.com wrote: We seem to be about evenly split about whether machine_init() should have a trailing semicolon (it doesn't need one but it doesn't hurt either...) It's obviously superior to use a semicolon... C is completely consistent synactically about the usage of semicolons afterall :-) I disagree. This macro does not turn into a statement but a full function definition. Neither our Coding Style nor any other that I know does I was only responding to be funny. This is not something worth anyone arguing about. We've got *much* more important things to sort through. Regards, Anthony Liguori void foo(bar baz) { }; with a trailing semicolon. For type_init() I cleaned this up, and I attribute the existing semicolons to people's ignorance of what these macros actually do. You might remember that Eduardo and I wanted to QOM'ify machines so that machine_init() would get replaced with type_init() but you stopped us at the time, leaving it untouched. So there's no strict need to go through and change existing users, but I believe in setting good examples. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [RFC][PATCH] qemu-timer: Run timers in alarm timer handler
Il 23/08/2012 15:01, Jan Kiszka ha scritto: On 2012-08-23 14:24, Paolo Bonzini wrote: Il 23/08/2012 14:10, Jan Kiszka ha scritto: Can you expand on this? Well, this patch removes an indirection from timer event deliveries. So it reduces overhead, though only noticeable if you have high-rate timers. Actually, timers (and bottom halves) are always run after iohandlers. So the qemu_notify_event should already be completely useless for Unix, even if we leave the host_alarm_handler indirection. Is there anything that requires this ordering for timers? No, I don't think so. (And also not for bottom halves, since those always do a qemu_notify_event). But this leaves out Windows, where your next task of (IIUC) having multiple instances of struct qemu_alarm_timer would be complicated by the qemu_notify_event. I guess this is the original reason for your patch. I'm not heading for multi-instance alarm timers or any kind of optimization on Windows. It should just continue to work. Windows is neither a high-performance nor a real-time platform for QEMU, IMHO. Yeah, making multi-instance alarm timers optional does it as well. (As long as it doesn't bit rot). So, in order to remove the qemu_notify_event completely, what about not using signals anymore for timers? You could just tweak the select timeout and drop all the -clock madness. Zero syscalls, practically no overhead. If this is not precise enough, use timerfd on Linux only Need to think about it. At least, real-time tasks will get proper precision on Linux. Not sure if it will be sufficient on other hosts. Do we care (I put non-Linux POSIX just a little above Windows but not much)? (BTW, switching to an absolute deadline would be useful too). Why? We aren't affected by clock adjustment with relative timeouts. Just the usual fact that the deadline is incorrect if QEMU is pre-empted between computing the deadline and applying it. It shouldn't really matter for the iothread, because it's not CPU bound, but it's cleaner since internally we store absolute deadlines anyway. Paolo
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH V2 01/17] hvm: Modify interface to support multiple ioreq server
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h index 27b3de5..49d1ca0 100644 --- a/xen/include/asm-x86/hvm/domain.h +++ b/xen/include/asm-x86/hvm/domain.h [...] struct hvm_domain { +/* Use for the IO handles by Xen */ struct hvm_ioreq_page ioreq; -struct hvm_ioreq_page buf_ioreq; +struct hvm_ioreq_server *ioreq_server_list; +uint32_t nr_ioreq_server; +spinlock_t ioreq_server_lock; There's some whitespace weirdness here plus some in xen/include/asm-x86/hvm/vcpu.h and xen/include/public/hvm/hvm_op.h. diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 4022a1d..87aacd3 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -34,6 +34,7 @@ #define IOREQ_TYPE_PIO 0 /* pio */ #define IOREQ_TYPE_COPY 1 /* mmio ops */ +#define IOREQ_TYPE_PCI_CONFIG 2 /* pci config space ops */ #define IOREQ_TYPE_TIMEOFFSET 7 #define IOREQ_TYPE_INVALIDATE 8 /* mapcache */ I wonder why we skip 2-6 now -- perhaps they used to be something else and we are avoiding them to avoid strange errors? In which case adding the new on as 9 might be a good idea. Ian.
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH V2 09/17] xc: Add the hypercall for multiple servers
On Wed, 2012-08-22 at 13:31 +0100, Julien Grall wrote: This patch add 5 hypercalls to register server, io range and PCI. Signed-off-by: Julien Grall julien.gr...@citrix.com Looks correct to me at least so far as the use of the hypercall buffers goes, thanks. Acked-by: Ian Campbell ian.campb...@citrix.com
[Qemu-devel] [PATCH] monitor: move json init from OPEN event to init
At some point in the past, the OPEN event was changed to be issued from a bottom half. This creates a small window whereas a data callback registered in init may be invoked before the OPEN event has been issued. This is reproducible with: echo {'execute': 'qmp_capabilities'} | qemu-system-x86_64 -M none -qmp stdio We can fix this for the monitor by moving the parser initialization to init. The remaining state that is set in OPEN appears harmless. Reported-by: Daniel Berrange berra...@redhat.com Signed-off-by: Anthony Liguori aligu...@us.ibm.com --- monitor.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index 480f583..b188582 100644 --- a/monitor.c +++ b/monitor.c @@ -4832,7 +4832,6 @@ static void monitor_control_event(void *opaque, int event) switch (event) { case CHR_EVENT_OPENED: mon-mc-command_mode = 0; -json_message_parser_init(mon-mc-parser, handle_qmp_command); data = get_qmp_greeting(); monitor_json_emitter(mon, data); qobject_decref(data); @@ -4840,6 +4839,7 @@ static void monitor_control_event(void *opaque, int event) break; case CHR_EVENT_CLOSED: json_message_parser_destroy(mon-mc-parser); +json_message_parser_init(mon-mc-parser, handle_qmp_command); mon_refcount--; monitor_fdsets_cleanup(); break; @@ -4951,6 +4951,8 @@ void monitor_init(CharDriverState *chr, int flags) monitor_event, mon); } +json_message_parser_init(mon-mc-parser, handle_qmp_command); + QLIST_INSERT_HEAD(mon_list, mon, entry); if (!default_mon || (flags MONITOR_IS_DEFAULT)) default_mon = mon; -- 1.7.5.4
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH V2 11/17] xc: modify save/restore to support multiple device models
On Wed, 2012-08-22 at 13:31 +0100, Julien Grall wrote: - add save/restore new special pages and remove unused - modify save file structure to allow multiple qemu states Signed-off-by: Julien Grall julien.gr...@citrix.com --- tools/libxc/xc_domain_restore.c | 150 +-- tools/libxc/xc_domain_save.c|6 +- As you've changed the protocol olease can you update the docs in xg_save_restore.h. @@ -103,6 +103,9 @@ static ssize_t rdexact(xc_interface *xch, struct restore_ctx *ctx, #else #define RDEXACT read_exact #endif + +#define QEMUSIG_SIZE 21 + /* ** In the state file (or during transfer), all page-table pages are ** converted into a 'canonical' form where references to actual mfns @@ -467,7 +522,7 @@ static int buffer_tail_hvm(xc_interface *xch, struct restore_ctx *ctx, int vcpuextstate, uint32_t vcpuextstate_size) { uint8_t *tmp; -unsigned char qemusig[21]; +unsigned char qemusig[QEMUSIG_SIZE + 1]; An extra + 1 here? [...] -qemusig[20] = '\0'; +qemusig[QEMUSIG_SIZE] = '\0'; This is one bigger than it used to be now. Perhaps this is an unrelated bug fix (I haven't check the real length of the sig), in which case please can you split it out and submit separately? Ian.
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH V2 12/17] xl: Add interface to handle qemu disaggregation
On Wed, 2012-08-22 at 13:31 +0100, Julien Grall wrote: This patch modifies libxl interface for qemu disaggregation. I'd rather see the interfaces changes in the same patch as the implementation of the new interfaces. For the moment, due to some dependencies between devices, we can't let the user choose which QEMU emulate a device. Moreoever this patch adds an id field to nic interface. It will be used in config file to specify which QEMU handle the network card. Is domid+devid not sufficient to identify which nic? A possible disaggregation is: - UI: Emulate graphic card, USB, keyboard, mouse, default devices (PIIX4, root bridge, ...) - IDE: Emulate disk - Serial: Emulate serial port - Audio: Emulate audio card - Net: Emulate one or more network cards, multiple QEMU can emulate different card. The emulated card is specified with its nic ID. Signed-off-by: Julien Grall julien.gr...@citrix.com --- tools/libxl/libxl.h |3 +++ tools/libxl/libxl_types.idl | 15 +++ 2 files changed, 18 insertions(+), 0 deletions(-) diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index c614d6f..71d4808 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -307,6 +307,7 @@ void libxl_cpuid_dispose(libxl_cpuid_policy_list *cpuid_list); #define LIBXL_PCI_FUNC_ALL (~0U) typedef uint32_t libxl_domid; +typedef uint32_t libxl_dmid; /* * Formatting Enumerations. @@ -478,12 +479,14 @@ typedef struct { libxl_domain_build_info b_info; int num_disks, num_nics, num_pcidevs, num_vfbs, num_vkbs; +int num_dms; libxl_device_disk *disks; libxl_device_nic *nics; libxl_device_pci *pcidevs; libxl_device_vfb *vfbs; libxl_device_vkb *vkbs; +libxl_dm *dms; libxl_action_on_shutdown on_poweroff; libxl_action_on_shutdown on_reboot; diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index daa8c79..36c802a 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -246,6 +246,20 @@ libxl_domain_sched_params = Struct(domain_sched_params,[ (extratime,integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT'}), ]) +libxl_dm_cap = Enumeration(dm_cap, [ +(1, UI), # Emulate all UI + default device What does default device equate too? +(2, IDE), # Emulate IDE +(4, SERIAL), # Emulate Serial +(8, AUDIO), # Emulate audio +]) + +libxl_dm = Struct(dm, [ +(name, string), +(path, string), +(capabilities, uint64), uint64 and not libxl_dm_cap? +(vifs, libxl_string_list), +]) + libxl_domain_build_info = Struct(domain_build_info,[ (max_vcpus, integer), (avail_vcpus, libxl_bitmap), @@ -367,6 +381,7 @@ libxl_device_nic = Struct(device_nic, [ (nictype, libxl_nic_type), (rate_bytes_per_interval, uint64), (rate_interval_usecs, uint32), +(id, string), ]) libxl_device_pci = Struct(device_pci, [
Re: [Qemu-devel] Race condition in char device setup causing SEGV
Daniel P. Berrange berra...@redhat.com writes: When testing with the new -M none arg, I've noticed that ~70% of the time libvirt starts QEMU will result in a SEGV from QEMU with the following stack trace: (gdb) bt #0 0x in ?? () #1 0x5567a37f in json_lexer_feed_char (lexer=0x5658fb20, ch=123 '{', flush=false) at json-lexer.c:324 #2 0x5567a4aa in json_lexer_feed (lexer=0x5658fb20, buffer=0x7fffe7b7 {, size=1) at json-lexer.c:356 #3 0x5567c708 in json_message_parser_feed (parser=0x5658fb18, buffer=0x7fffe7b7 {, size=1) at json-streamer.c:110 #4 0x55882861 in monitor_control_read (opaque=0x5658f6a0, buf=0x7fffe7b7 {, size=1) at /home/berrange/src/virt/qemu/monitor.c:4768 #5 0x5579b051 in qemu_chr_be_write (s=0x5658dc10, buf=0x7fffe7b7 {, len=1) at qemu-char.c:164 #6 0x5579c9c8 in stdio_read (opaque=0x5658dc10) at qemu-char.c:720 #7 0x5567941f in qemu_iohandler_poll (readfds=0x560f17c0, writefds=0x560f1840, xfds=0x560f18c0, ret=2) at iohandler.c:122 #8 0x5577166a in main_loop_wait (nonblocking=0) at main-loop.c:497 #9 0x5576956b in main_loop () at /home/berrange/src/virt/qemu/vl.c:1643 #10 0x55770239 in main (argc=10, argv=0x7fffeca8, envp=0x7fffed00) at /home/berrange/src/virt/qemu/vl.c:3755 Stack frame #1 there is doing this: lexer-emit(lexer, lexer-token, JSON_ERROR, lexer-x, lexer-y); GDB confirms that the 'emit' field has not yet been initialized. In the case of QMP, this is initialized by the following sequence: - main - chardev_init_func - qemu_chr_generic_open ...async from event loop... - main_loop - qemu_chr_generic_open_bh - monitor_control_event - json_message_parser_init - json_lexer_init The problem arises if you try to feed data to QEMU before the bottom half has run. There is a race where qemu_chr_be_write can be called to process input, before the qemu_chr_generic_open_bh has been invoked. The char layer really just needs to be thrown away and rewritten :-( It really is a giant steaming pile... I sent a simple patch that fixes this problem for the monitor. Regards, Anthony Liguori This can actually be quite easily demonstrated (at least on my system): # echo { | qemu-system-x86_64 -nodefaults -nographic -M none -qmp stdio Segmentation fault If you remove the '-M none' call, you won't hit this race condition 99% of the time, but I have occassionally been able to see it. It isn't clear to me what to change to solve this race condition. Probably though, the I/O handlers for a char device should be registered until the open bottom half has completed. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
Re: [Qemu-devel] [PATCH v6 01/13] target-mips-ase-dsp: Add internal functions
On Tue, Aug 21, 2012 at 02:53:07PM +0800, Jia Liu wrote: Add internal functions using by MIPS ASE DSP instructions. Signed-off-by: Jia Liu pro...@gmail.com --- target-mips/Makefile.objs |2 +- target-mips/dsp_helper.c | 1277 + 2 files changed, 1278 insertions(+), 1 deletion(-) create mode 100644 target-mips/dsp_helper.c Looks fine to me. Signed-off-by: Aurelien Jarno aurel...@aurel32.net diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs index 2e0e093..55b252d 100644 --- a/target-mips/Makefile.objs +++ b/target-mips/Makefile.objs @@ -1,4 +1,4 @@ -obj-y += translate.o op_helper.o helper.o cpu.o +obj-y += translate.o dsp_helper.o op_helper.o helper.o cpu.o obj-$(CONFIG_SOFTMMU) += machine.o $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c new file mode 100644 index 000..a7d6c7e --- /dev/null +++ b/target-mips/dsp_helper.c @@ -0,0 +1,1277 @@ +/* + * MIPS ASE DSP Instruction emulation helpers for QEMU. + * + * Copyright (c) 2012 Jia Liu pro...@gmail.com + * Dongxue Zhang elat@gmail.com + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include cpu.h +#include helper.h + +/*** MIPS DSP internal functions begin ***/ +static inline int not_word_value(target_long value) +{ +target_ulong temp; + +temp = (target_long)(int32_t)(value 0x); +if (value == temp) { +return 0; +} else { +return 1; +} +} + +static inline void set_DSPControl_overflow_flag(CPUMIPSState *env, +uint32_t flag, int position) +{ +env-active_tc.DSPControl |= (target_ulong)flag position; +} + +static inline void set_DSPControl_carryflag(CPUMIPSState *env, uint32_t flag) +{ +env-active_tc.DSPControl |= (target_ulong)flag 13; +} + +static inline uint32_t get_DSPControl_carryflag(CPUMIPSState *env) +{ +uint32_t flag; + +flag = (env-active_tc.DSPControl 13) 0x01; + +return flag; +} + +static inline void set_DSPControl_24(CPUMIPSState *env, uint32_t flag, int len) +{ + uint32_t filter; + + filter = ((0x01 len) - 1) 24; + filter = ~filter; + + env-active_tc.DSPControl = filter; + env-active_tc.DSPControl |= (target_ulong)flag 24; +} + +static inline uint32_t get_DSPControl_24(CPUMIPSState *env, int len) +{ + uint32_t cond; + uint32_t filter; + + filter = (0x01 len) - 1; + + cond = (env-active_tc.DSPControl 24) filter; + + return cond; +} + +static inline void set_DSPControl_pos(CPUMIPSState *env, uint32_t pos) +{ +target_ulong dspc; + +dspc = env-active_tc.DSPControl; +#ifndef TARGET_MIPS64 +dspc = dspc 0xFFC0; +dspc |= pos; +#else +dspc = dspc 0xFF80; +dspc |= pos; +#endif +env-active_tc.DSPControl = dspc; +} + +static inline uint32_t get_DSPControl_pos(CPUMIPSState *env) +{ +target_ulong dspc; +uint32_t pos; + +dspc = env-active_tc.DSPControl; + +#ifndef TARGET_MIPS64 +pos = dspc 0x3F; +#else +pos = dspc 0x7F; +#endif + +return pos; +} + +static inline void set_DSPControl_efi(CPUMIPSState *env, uint32_t flag) +{ +env-active_tc.DSPControl = 0xBFFF; +env-active_tc.DSPControl |= (target_ulong)flag 14; +} + +/* get abs value */ +static inline int8_t mipsdsp_sat_abs_u8(CPUMIPSState *env, uint8_t a) +{ +int8_t temp; +temp = a; + +if (a == 0x80) { +set_DSPControl_overflow_flag(env, 1, 20); +temp = 0x7f; +} else { +if ((a 0x80) == 0x80) { +temp = -temp; +} +} + +return temp; +} + +static inline int16_t mipsdsp_sat_abs_u16(CPUMIPSState *env, uint16_t a) +{ +int16_t temp; +temp = a; + +if (a == 0x8000) { +set_DSPControl_overflow_flag(env, 1, 20); +temp = 0x7fff; +} else { +if ((a 0x8000) == 0x8000) { +temp = -temp; +} +} + +return temp; +} + +static inline int32_t mipsdsp_sat_abs_u32(CPUMIPSState *env, uint32_t a) +{ +int32_t temp; +temp = a; + +if (a == 0x8000) { +set_DSPControl_overflow_flag(env, 1, 20); +temp =
Re: [Qemu-devel] [PATCH v6 02/13] target-mips-ase-dsp: Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number
On Tue, Aug 21, 2012 at 02:53:08PM +0800, Jia Liu wrote: Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number. Signed-off-by: Jia Liu pro...@gmail.com --- target-mips/translate.c | 107 +++ 1 file changed, 81 insertions(+), 26 deletions(-) This code assume that the DSP ASE is always available and enabled, while when it is not the case, it should trigger an exception. diff --git a/target-mips/translate.c b/target-mips/translate.c index 47daf85..0793153 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -5,6 +5,7 @@ * Copyright (c) 2006 Marius Groeger (FPU operations) * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) + * Copyright (c) 2012 Jia Liu Dongxue Zhang (MIPS ASE DSP support) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1972,6 +1973,7 @@ static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) { const char *opn = hilo; +unsigned int acc; if (reg == 0 (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as NOP. */ @@ -1980,25 +1982,71 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) } switch (opc) { case OPC_MFHI: -tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]); +acc = ((ctx-opcode) 21) 0x03; +#if defined(TARGET_MIPS64) +if (acc == 0) { +tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); +} else { +tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); +} +#else +tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); +#endif opn = mfhi; break; case OPC_MFLO: -tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]); +acc = ((ctx-opcode) 21) 0x03; +#if defined(TARGET_MIPS64) +if (acc == 0) { +tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); +} else { +tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); +} +#else +tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); +#endif opn = mflo; break; case OPC_MTHI: -if (reg != 0) -tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]); -else -tcg_gen_movi_tl(cpu_HI[0], 0); +acc = ((ctx-opcode) 11) 0x03; +#if defined(TARGET_MIPS64) +if (reg != 0) { +if (acc == 0) { +tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); +} else { +tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); +} +} else { +tcg_gen_movi_tl(cpu_HI[acc], 0); +} +#else +if (reg != 0) { +tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); +} else { +tcg_gen_movi_tl(cpu_HI[acc], 0); +} +#endif opn = mthi; break; case OPC_MTLO: -if (reg != 0) -tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]); -else -tcg_gen_movi_tl(cpu_LO[0], 0); +acc = ((ctx-opcode) 11) 0x03; +#if defined(TARGET_MIPS64) +if (reg != 0) { +if (acc == 0) { +tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); +} else { +tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); +} +} else { +tcg_gen_movi_tl(cpu_LO[acc], 0); +} +#else +if (reg != 0) { +tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); +} else { +tcg_gen_movi_tl(cpu_LO[acc], 0); +} +#endif opn = mtlo; break; } @@ -2011,6 +2059,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { const char *opn = mul/div; TCGv t0, t1; +unsigned int acc; switch (opc) { case OPC_DIV: @@ -2073,6 +2122,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { TCGv_i64 t2 = tcg_temp_new_i64(); TCGv_i64 t3 = tcg_temp_new_i64(); +acc = ((ctx-opcode) 11) 0x03; tcg_gen_ext_tl_i64(t2, t0); tcg_gen_ext_tl_i64(t3, t1); @@ -2082,8 +2132,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, tcg_gen_shri_i64(t2, t2, 32); tcg_gen_trunc_i64_tl(t1, t2); tcg_temp_free_i64(t2); -tcg_gen_ext32s_tl(cpu_LO[0], t0); -tcg_gen_ext32s_tl(cpu_HI[0], t1); +tcg_gen_ext32s_tl(cpu_LO[acc], t0); +tcg_gen_ext32s_tl(cpu_HI[acc], t1); } opn = mult; break; @@ -2091,6 +2141,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { TCGv_i64 t2 = tcg_temp_new_i64(); TCGv_i64 t3 = tcg_temp_new_i64(); +acc =
Re: [Qemu-devel] [PATCH 1/2] migration: Allow the migrate command to work on file: urls
Le Thursday 23 Aug 2012 à 14:48:19 (+0200), Benoît Canet a écrit : Le Thursday 23 Aug 2012 à 13:34:01 (+0100), Daniel P. Berrange a écrit : On Thu, Aug 23, 2012 at 02:28:07PM +0200, Benoît Canet wrote: Usage: (qemu) migrate file:/path/to/vm_statefile Signed-off-by: Benoit Canet ben...@irqsave.net --- migration-fd.c |4 ++-- migration.c| 20 +++- migration.h|2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/migration-fd.c b/migration-fd.c index 50138ed..d39e44a 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -73,9 +73,9 @@ static int fd_close(MigrationState *s) return 0; } -int fd_start_outgoing_migration(MigrationState *s, const char *fdname) +int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd) { -s-fd = monitor_get_fd(cur_mon, fdname); +s-fd = fd ? fd : monitor_get_fd(cur_mon, fdname); if (s-fd == -1) { DPRINTF(fd_migration: invalid file descriptor identifier\n); goto err_after_get_fd; diff --git a/migration.c b/migration.c index 1edeec5..679847d 100644 --- a/migration.c +++ b/migration.c @@ -239,9 +239,14 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; +struct stat st; qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL); +if (!fstat(s-fd, st) S_ISREG(st.st_mode)) { +fsync(s-fd); +} + if (s-file) { DPRINTF(closing file\n); ret = qemu_fclose(s-file); @@ -475,6 +480,17 @@ void migrate_del_blocker(Error *reason) migration_blockers = g_slist_remove(migration_blockers, reason); } +static int file_start_outgoing_migration(MigrationState *s, + const char *filename) +{ +int fd; +fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR); +if (fd 0) { +return -errno; +} +return fd_start_outgoing_migration(s, NULL, fd); 'fd_start_outgoing_migration' requires that the FD you give it supports non-blocking I/O. File descriptors opened from plain files or block devices do not honour that requirement. So this proposed code will cause the entire QEMU process to block while migration is taking place. This is why no on has ever implemented the 'file:' protocol in QEMU before. When I run the code it appear it does not block all the time. (guest is still interactive most of the time needed to complete migration) How can it be ? Benoît To deal with this issue you'd either have to use the POSIX async I/O APIs (or QEMU's internal equivalent) I don't see how AIO could fit in this scheme. , or spawn a separate 'dd' helper process and give QEMU a pipe FD instead. The latter is what libvirt does to implement migrate to file. I could subvert a exec_start_outgoing_migration clone to be fork_start_outgoing_migration doing a for then writing to disk the incoming data. Does any QEMU developper have an idea on this ? Benoît Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH V2 14/17] xl-parsing: Parse new device_models option
On Wed, 2012-08-22 at 13:32 +0100, Julien Grall wrote: Add new option device_models. The user can specify the capability of the QEMU (ui, vifs, ...). This option only works with QEMU upstream (qemu-xen). For instance: device_models= [ 'name=all,vifs=nic1', 'name=qvga,ui', 'name=qide,ide' ] Please can you patch docs/man/xl.cfg.pod.5 with a description of this syntax. Possibly just a stub referencing docs/man/xl-device-models.markdown in the same manner as xl-disk-configuration.txt, xl-numa-placement.markdown, xl-network-configuration.markdown etc. iirc you can give multiple vifs -- what does that syntax look like? I didn't ask before -- what does naming the dm give you? Is it just used for ui things like logging or can you cross reference this in some way? Each device model can also take a path argument which override the default one. It's usefull for debugging. useful Signed-off-by: Julien Grall julien.gr...@citrix.com --- tools/libxl/Makefile |2 +- tools/libxl/libxlu_dm.c | 96 ++ tools/libxl/libxlutil.h |5 ++ tools/libxl/xl_cmdimpl.c | 29 +- 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 tools/libxl/libxlu_dm.c diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 47fb110..2b58721 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -79,7 +79,7 @@ AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h _libxl_list.h _paths.h \ AUTOSRCS= libxlu_cfg_y.c libxlu_cfg_l.c AUTOSRCS += _libxl_save_msgs_callout.c _libxl_save_msgs_helper.c LIBXLU_OBJS = libxlu_cfg_y.o libxlu_cfg_l.o libxlu_cfg.o \ - libxlu_disk_l.o libxlu_disk.o libxlu_vif.o libxlu_pci.o + libxlu_disk_l.o libxlu_disk.o libxlu_vif.o libxlu_pci.o libxlu_dm.o $(LIBXLU_OBJS): CFLAGS += $(CFLAGS_libxenctrl) # For xentoollog.h CLIENTS = xl testidl libxl-save-helper diff --git a/tools/libxl/libxlu_dm.c b/tools/libxl/libxlu_dm.c new file mode 100644 index 000..9f0a347 --- /dev/null +++ b/tools/libxl/libxlu_dm.c @@ -0,0 +1,96 @@ +#include libxl_osdeps.h /* must come before any other headers */ +#include stdlib.h +#include libxlu_internal.h +#include libxlu_cfg_i.h + +static void split_string_into_string_list(const char *str, + const char *delim, + libxl_string_list *psl) Is this a cut-n-paste of the one in xl_cmdimpl.c or did it change? Probably better to add this as a common utility function somewhere. +{ [...] +} + +int xlu_dm_parse(XLU_Config *cfg, const char *spec, + libxl_dm *dm) +{ +char *buf = strdup(spec); +char *p, *p2; +int rc = 0; + +p = strtok(buf, ,); +if (!p) +goto skip_dm; +do { +while (*p == ' ') +p++; +if ((p2 = strchr(p, '=')) == NULL) { +if (!strcmp(p, ui)) libxl provides a libxl_BLAH_from_string for enums in the idl, which might be helpful here? +dm-capabilities |= LIBXL_DM_CAP_UI; +else if (!strcmp(p, ide)) +dm-capabilities |= LIBXL_DM_CAP_IDE; +else if (!strcmp(p, serial)) +dm-capabilities |= LIBXL_DM_CAP_SERIAL; +else if (!strcmp(p, audio)) +dm-capabilities |= LIBXL_DM_CAP_AUDIO; +} else { +*p2 = '\0'; +if (!strcmp(p, name)) +dm-name = strdup(p2 + 1); +else if (!strcmp(p, path)) +dm-path = strdup(p2 + 1); +else if (!strcmp(p, vifs)) +split_string_into_string_list(p2 + 1, ;, dm-vifs); + } +} while ((p = strtok(NULL, ,)) != NULL); + +if (!dm-name dm-path) +{ +fprintf(stderr, xl: Unable to parse device_deamon\n); +exit(-ERROR_FAIL); +} +skip_dm: +free(buf); + +return rc; +} diff --git a/tools/libxl/libxlutil.h b/tools/libxl/libxlutil.h index 0333e55..db22715 100644 --- a/tools/libxl/libxlutil.h +++ b/tools/libxl/libxlutil.h @@ -93,6 +93,11 @@ int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs, */ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str); +/* + * Daemon specification parsing. + */ +int xlu_dm_parse(XLU_Config *cfg, const char *spec, + libxl_dm *dm); /* * Vif rate parsing. diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 138cd72..2a26fa4 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -561,7 +561,7 @@ static void parse_config_data(const char *config_source, const char *buf; long l; XLU_Config *config; -XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids; +XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *dms; int pci_power_mgmt = 0; int pci_msitranslate = 0; int
Re: [Qemu-devel] [PATCH] monitor: move json init from OPEN event to init
On Thu, Aug 23, 2012 at 08:22:35AM -0500, Anthony Liguori wrote: At some point in the past, the OPEN event was changed to be issued from a bottom half. This creates a small window whereas a data callback registered in init may be invoked before the OPEN event has been issued. This is reproducible with: echo {'execute': 'qmp_capabilities'} | qemu-system-x86_64 -M none -qmp stdio We can fix this for the monitor by moving the parser initialization to init. The remaining state that is set in OPEN appears harmless. Reported-by: Daniel Berrange berra...@redhat.com Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Daniel P. Berrange berra...@redhat.com Works in my testing. I have also fixed libvirt so that it does not try to send commands to QMP, until QMP has sent out its initial greeting, thus avoiding the flaw too. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH V2 15/17] xl: support spawn/destroy on multiple device model
On Wed, 2012-08-22 at 13:32 +0100, Julien Grall wrote: Old configuration file is still working with qemu disaggregation. Before to spawn any QEMU, the toolstack will fill correctly, if needed, configuration structure. For the moment, the toolstack spawns device models one by one. Signed-off-by: Julien Grall julien.gr...@citrix.com --- tools/libxl/libxl.c | 16 ++- tools/libxl/libxl_create.c | 150 +- tools/libxl/libxl_device.c |7 +- tools/libxl/libxl_dm.c | 369 ++ tools/libxl/libxl_dom.c |4 +- tools/libxl/libxl_internal.h | 36 +++-- 6 files changed, 421 insertions(+), 161 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 8ea3478..60718b6 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1330,7 +1330,8 @@ static void stubdom_destroy_callback(libxl__egc *egc, } dds-stubdom_finished = 1; -savefile = libxl__device_model_savefile(gc, dis-domid); +/* FIXME: get dmid */ +savefile = libxl__device_model_savefile(gc, dis-domid, 0); rc = libxl__remove_file(gc, savefile); /* * On suspend libxl__domain_save_device_model will have already @@ -1423,10 +1424,8 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis) LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, xc_domain_pause failed for %d, domid); } if (dm_present) { -if (libxl__destroy_device_model(gc, domid) 0) -LIBXL__LOG(ctx, LIBXL__LOG_ERROR, libxl__destroy_device_model failed for %d, domid); - -libxl__qmp_cleanup(gc, domid); +if (libxl__destroy_device_models(gc, domid) 0) +LIBXL__LOG(ctx, LIBXL__LOG_ERROR, libxl__destroy_device_models failed for %d, domid); } dis-drs.ao = ao; dis-drs.domid = domid; @@ -1725,6 +1724,13 @@ out: /**/ +int libxl__dm_setdefault(libxl__gc *gc, libxl_dm *dm) +{ +return 0; +} + +/**/ + int libxl__device_disk_setdefault(libxl__gc *gc, libxl_device_disk *disk) { int rc; diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index 5f0d26f..7160c78 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -35,6 +35,10 @@ void libxl_domain_config_dispose(libxl_domain_config *d_config) { int i; +for (i=0; id_config-num_dms; i++) +libxl_dm_dispose(d_config-dms[i]); +free(d_config-dms); We are adding libxl_FOO_list_free functions for new ones of these as we introduce new ones), can you do that for the dm type please. + for (i=0; id_config-num_disks; i++) libxl_device_disk_dispose(d_config-disks[i]); free(d_config-disks); @@ -59,6 +63,50 @@ void libxl_domain_config_dispose(libxl_domain_config *d_config) libxl_domain_build_info_dispose(d_config-b_info); } +static int libxl__domain_config_setdefault(libxl__gc *gc, + libxl_domain_config *d_config) +{ +libxl_domain_build_info *b_info = d_config-b_info; +uint64_t cap = 0; +int i = 0; +int ret = 0; +libxl_dm *default_dm = NULL; + +if (b_info-device_model_version == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL + (d_config-num_dms 1)) +return ERROR_INVAL; + +if (!d_config-num_dms) { +d_config-dms = malloc(sizeof (*d_config-dms)); You should use libxl__zalloc or libxl__calloc or something here with the NO_GC argument to get the expected error handling. @@ -991,12 +1057,11 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, libxl__device_console_dispose(console); if (need_qemu) { -dcs-dmss.dm.guest_domid = domid; -libxl__spawn_local_dm(egc, dcs-dmss.dm); +assert(dcs-dmss); +domcreate_spawn_devmodel(egc, dcs, dcs-current_dmid); return; } else { -assert(!dcs-dmss.dm.guest_domid); -domcreate_devmodel_started(egc, dcs-dmss.dm, 0); +assert(!dcs-dmss); Doesn't this stop progress in this case meaning we'll never get to the end of the async op? return; } } [..] @@ -1044,7 +1044,8 @@ int libxl__wait_for_device_model(libxl__gc *gc, void *check_callback_userdata) { char *path; -path = libxl__sprintf(gc, /local/domain/0/device-model/%d/state, domid); +path = libxl__sprintf(gc, /local/domain/0/dms/%u/%u/state, + domid, dmid); Isn't this control path shared with qemu? I'm not sure we can just change it like that? We need to at least retain compatibility with pre-disag qemus. return
[Qemu-devel] [PATCH 0/2] Add TPCI200 and IP-Octal 232 IndustryPack emulation
Hello, I have been working on the emulation of the IP-Octal 232 IndustryPack module, a device that implements eight RS-232 serial ports. IndustryPack modules are small boards that are attached to a carrier board, so in order to have a complete and working system I also wrote an emulation of the TEWS TPCI200 carrier, which is a PCI board to which up to 4 IndustryPack modules can be attached. I have been using this virtual device to test and debug the ipoctal driver in the Linux kernel. I'm publishing the code now, the emulation is not 100% complete but it's fairly functional, and it can be used to easily implement more IndustryPack modules. So the work consists on three parts: - TPCI200, the bridge between PCI and IndustryPack. - The IndustryPack bus. - IP-Octal, the IndustryPack module. Basic usage: $ qemu -device tpci200 -device ipoctal Each one of the serial ports in the ipoctal device can be redirected to a character device in the host using the functionality provided by QEMU. The 'serial0' to 'serial7' parameters can be used to specify each one of the redirections. Suggestions, comments, etc, will be appreciated. Alberto Garcia (2): Add TEWS TPCI200 IndustryPack emulation Add IP-Octal 232 IndustryPack emulation default-configs/pci.mak |1 + hw/Makefile.objs|3 + hw/ipack.c | 106 hw/ipack.h | 75 ++ hw/ipoctal.c| 662 +++ hw/pci_ids.h|3 + hw/tpci200.c| 630 7 ficheiros modificados, 1480 adições(+) create mode 100644 hw/ipack.c create mode 100644 hw/ipack.h create mode 100644 hw/ipoctal.c create mode 100644 hw/tpci200.c -- 1.7.10.4
[Qemu-devel] [PATCH 1/2] Add TEWS TPCI200 IndustryPack emulation
The TPCI200 is a PCI board that supports up to 4 IndustryPack modules. A new bus type called 'IndustryPack' has been created so any compatible module can be attached to this board. Signed-off-by: Alberto Garcia agar...@igalia.com --- default-configs/pci.mak |1 + hw/Makefile.objs|3 + hw/ipack.c | 106 hw/ipack.h | 75 ++ hw/pci_ids.h|3 + hw/tpci200.c| 630 +++ 6 ficheiros modificados, 818 adições(+) create mode 100644 hw/ipack.c create mode 100644 hw/ipack.h create mode 100644 hw/tpci200.c diff --git a/default-configs/pci.mak b/default-configs/pci.mak index 69e18f1..7753a4f 100644 --- a/default-configs/pci.mak +++ b/default-configs/pci.mak @@ -19,3 +19,4 @@ CONFIG_IDE_PCI=y CONFIG_AHCI=y CONFIG_ESP=y CONFIG_ESP_PCI=y +CONFIG_IPACK=y diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 7f57ed5..f4a3a9b 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -99,6 +99,9 @@ hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o hw-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o +# IndustryPack +hw-obj-$(CONFIG_IPACK) += tpci200.o ipack.o + # PCI network cards hw-obj-$(CONFIG_NE2000_PCI) += ne2000.o hw-obj-$(CONFIG_EEPRO100_PCI) += eepro100.o diff --git a/hw/ipack.c b/hw/ipack.c new file mode 100644 index 000..59e272b --- /dev/null +++ b/hw/ipack.c @@ -0,0 +1,106 @@ +/* + * QEMU IndustryPack emulation + * + * Copyright (C) 2012 Igalia, S.L. + * Author: Alberto Garcia agar...@igalia.com + * + * This code is licensed under the GNU GPL v2 or (at your option) any + * later version. + */ + +#include ipack.h + +IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot) +{ +BusChild *kid; + +QTAILQ_FOREACH(kid, bus-qbus.children, sibling) { +DeviceState *qdev = kid-child; +IPackDevice *ip = DO_UPCAST(IPackDevice, qdev, qdev); +if (ip-slot == slot) { +return ip; +} +} +return NULL; +} + +static int ipack_device_dev_init(DeviceState *qdev) +{ +IPackBus *bus = DO_UPCAST(IPackBus, qbus, qdev-parent_bus); +IPackDevice *dev = DO_UPCAST(IPackDevice, qdev, qdev); +IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev); + +if (dev-slot 0) { +dev-slot = bus-free_slot; +} +if (dev-slot = bus-n_slots) { +return -1; +} +bus-free_slot = dev-slot + 1; + +dev-irq = qemu_allocate_irqs(bus-set_irq, dev, 2); + +return k-init(dev); +} + +static int ipack_device_dev_exit(DeviceState *qdev) +{ +IPackDevice *dev = DO_UPCAST(IPackDevice, qdev, qdev); +IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev); + +if (k-exit) { +k-exit(dev); +} + +qemu_free_irqs(dev-irq); + +return 0; +} + +static Property ipack_device_props[] = { +DEFINE_PROP_INT32(slot, IPackDevice, slot, -1), +DEFINE_PROP_END_OF_LIST() +}; + +static void ipack_device_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *k = DEVICE_CLASS(klass); +k-bus_type = TYPE_IPACK_BUS; +k-init = ipack_device_dev_init; +k-exit = ipack_device_dev_exit; +k-props = ipack_device_props; +} + +const VMStateDescription vmstate_ipack_device = { +.name = ipack_device, +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_INT32(slot, IPackDevice), +VMSTATE_END_OF_LIST() +} +}; + +static const TypeInfo ipack_device_info = { +.name = TYPE_IPACK_DEVICE, +.parent= TYPE_DEVICE, +.instance_size = sizeof(IPackDevice), +.class_size= sizeof(IPackDeviceClass), +.class_init= ipack_device_class_init, +.abstract = true, +}; + +static const TypeInfo ipack_bus_info = { +.name = TYPE_IPACK_BUS, +.parent = TYPE_BUS, +.instance_size = sizeof(IPackBus), +}; + +static void ipack_register_types(void) +{ +type_register_static(ipack_device_info); +type_register_static(ipack_bus_info); +} + +type_init(ipack_register_types) diff --git a/hw/ipack.h b/hw/ipack.h new file mode 100644 index 000..61a9019 --- /dev/null +++ b/hw/ipack.h @@ -0,0 +1,75 @@ +/* + * QEMU IndustryPack emulation + * + * Copyright (C) 2012 Igalia, S.L. + * Author: Alberto Garcia agar...@igalia.com + * + * This code is licensed under the GNU GPL v2 or (at your option) any + * later version. + */ + +#ifndef QEMU_IPACK_H +#define QEMU_IPACK_H + +#include qdev.h + +typedef struct IPackBus IPackBus; + +#define TYPE_IPACK_BUS IndustryPack +#define IPACK_BUS(obj) OBJECT_CHECK(IPackBus, (obj), TYPE_IPACK_BUS) + +struct IPackBus { +BusState qbus; +uint8_t n_slots; +uint8_t free_slot; +qemu_irq_handler set_irq; +}; + +typedef struct IPackDevice IPackDevice; +typedef struct IPackDeviceClass IPackDeviceClass; + +#define TYPE_IPACK_DEVICE ipack-device +#define IPACK_DEVICE(obj) \ + OBJECT_CHECK(IPackDevice, (obj), TYPE_IPACK_DEVICE) +#define
Re: [Qemu-devel] [PATCH v3 uq/master 0/6] kvm: Get coalesced MMIO flushing out of the hot-path
On Thu, Aug 23, 2012 at 01:02:28PM +0200, Jan Kiszka wrote: This is just a repost, now targeting uq/master as agreed. No changes compared to v2 except that i82378: Remove bogus MMIO coalescing was dropped as it is already in QEMU upstream by now. Original description: We currently flush the coalesced MMIO buffer on every vmexit to userspace. KVM only provides a single buffer per VM, so a central lock is required to read from it. This is a contention point given a large enough VCPU set. Moreover, we need to hold the BQL while replaying the queued requests, probably for a long time until there is more fine grained locking available. Good reasons to overcome the unconditional flush. The series achieves this by flushing only on selected memory region accesses, either generically via the memory access dispatcher or directly on certain VGA PIO accesses that are not yet fully converted. Another reason to flush are remappings or other relevant region state changes. Jan Kiszka (6): memory: Flush coalesced MMIO on selected region access memory: Use transaction_begin/commit also for single-step operations memory: Fold memory_region_update_topology into memory_region_transaction_commit memory: Flush coalesced MMIO on mapping and state changes VGA: Flush coalesced MMIO on related MMIO/PIO accesses kvm: Stop flushing coalesced MMIO on vmexit hw/cirrus_vga.c |7 hw/qxl.c|1 + hw/vga-isa-mm.c |1 + hw/vga.c|5 +++ hw/vmware_vga.c |1 + kvm-all.c |2 - memory.c| 104 --- memory.h| 26 ++ 8 files changed, 102 insertions(+), 45 deletions(-) -- 1.7.3.4 Applied, thanks.
Re: [Qemu-devel] [PATCH] Add guest-get-hostname to retrieve the guests current hostname
On Thu, Aug 23, 2012 at 09:48:54AM -0300, Luiz Capitulino wrote: On Tue, 21 Aug 2012 13:57:54 +0200 Guido Günther a...@sigxcpu.org wrote: This allows to retrieve the guest's hostname via gethostname(2). This can be useful to identify a VM e.g. one without network. Signed-off-by: Guido Günther a...@sigxcpu.org --- We have an API in libvirt for that (virDomainGetHostname). Cheers -- Guido qapi-schema-guest.json | 12 qga/commands-posix.c | 12 qga/commands-win32.c |6 ++ 3 files changed, 30 insertions(+) diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json index d955cf1..8c7a4a5 100644 --- a/qapi-schema-guest.json +++ b/qapi-schema-guest.json @@ -515,3 +515,15 @@ ## { 'command': 'guest-network-get-interfaces', 'returns': ['GuestNetworkInterface'] } + +## +# @guest-get-hostname: +# +# Get the guest's hostname +# +# Returns: The guest's hostname +# +# Since: 1.2 Won't make it for 1.2 because we're in hard-freeze. +## +{ 'command': 'guest-get-hostname', + 'returns': 'str' } diff --git a/qga/commands-posix.c b/qga/commands-posix.c index ce90421..9223f18 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -15,6 +15,7 @@ #include sys/types.h #include sys/ioctl.h #include sys/wait.h +#include unistd.h #include qga/guest-agent-core.h #include qga-qmp-commands.h #include qerror.h @@ -993,6 +994,17 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err) } #endif +char *qmp_guest_get_hostname(Error **err) +{ +char hostname[HOST_NAME_MAX]; + +if (gethostname(hostname, HOST_NAME_MAX)) { +error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno)); You shouldn't use that macro, you can do something like this instead: error_set(err, can't get hostname: %s, strerror(errno)); Michael, do you think that's fine for new error messages or do you think it's worth it to add a guest-agent: prefix to all guest agent error messages? I think that's fine. libvirt or QMP (if we integrate the qemu-ga commands with QMP) can tack on a prefix for cases where we need to distinguish where in the stack the error occurred, but for direct communication with qemu-ga it's unambiguous, so might as well save the keystrokes. +return NULL; +} +return g_strdup(hostname); +} + /* register init/cleanup routines for stateful command groups */ void ga_command_state_init(GAState *s, GACommandState *cs) { diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 54bc546..55e8162 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -280,6 +280,12 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **err) return NULL; } +char *qmp_guest_get_hostname(Error **err) +{ +error_set(err, QERR_UNSUPPORTED); +return NULL; +} + /* register init/cleanup routines for stateful command groups */ void ga_command_state_init(GAState *s, GACommandState *cs) {
Re: [Qemu-devel] [PATCH v2] kvm-all.c: Move init of irqchip_inject_ioctl out of kvm_irqchip_create()
On 23 August 2012 10:13, Marcelo Tosatti mtosa...@redhat.com wrote: On Tue, Aug 21, 2012 at 12:27:51PM +0200, Jan Kiszka wrote: On 2012-08-21 10:25, Peter Maydell wrote: On 21 August 2012 09:19, Jan Kiszka jan.kis...@siemens.com wrote: As it's not yet merged, some late comment: irqchip_inject_ioctl should be renamed as well. irq_inject_ioctl? If we're changing it anyway, IIRC Avi didn't like the term inject here? Then irq_set_ioctl. Jan It is merged, please send a follow patch. Sure, no problem (I was hovering on the edge of suggesting that the field rename should be a separate patch anyhow.) -- PMM
Re: [Qemu-devel] [PATCH v6 03/13] target-mips-ase-dsp: Add branch instructions
On Tue, Aug 21, 2012 at 02:53:09PM +0800, Jia Liu wrote: Add MIPS ASE DSP Branch instructions. Signed-off-by: Jia Liu pro...@gmail.com --- target-mips/translate.c | 52 +++ 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 0793153..b049238 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -332,6 +332,14 @@ enum { OPC_DSHD = (0x05 6) | OPC_DBSHFL, }; +/* MIPS DSP REGIMM opcodes */ +enum { +OPC_BPOSGE32 = (0x1C 16) | OPC_REGIMM, +#if defined(TARGET_MIPS64) +OPC_BPOSGE64 = (0x1D 16) | OPC_REGIMM, +#endif +}; + /* Coprocessor 0 (rs field) */ #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op (0x1F 21)) @@ -2798,6 +2806,24 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, } btgt = ctx-pc + insn_bytes + offset; break; +case OPC_BPOSGE32: +tcg_gen_mov_tl(t0, cpu_dspctrl); +#if defined(TARGET_MIPS64) +tcg_gen_andi_tl(t0, t0, 0x7F); +#else +tcg_gen_andi_tl(t0, t0, 0x3F); +#endif You can directly use cpu_dspctrl as the second argument of andi_tl. I know this is optimized later by TCG, but it will still be faster if you use less instructions. +bcond_compute = 1; +btgt = ctx-pc + insn_bytes + offset; +break; +#if defined(TARGET_MIPS64) +case OPC_BPOSGE64: +tcg_gen_mov_tl(t0, cpu_dspctrl); +tcg_gen_andi_tl(t0, t0, 0x7F); Same here. +bcond_compute = 1; +btgt = ctx-pc + insn_bytes + offset; +break; +#endif case OPC_J: case OPC_JAL: case OPC_JALX: @@ -2986,6 +3012,16 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); MIPS_DEBUG(bltzl %s, TARGET_FMT_lx, regnames[rs], btgt); goto likely; +case OPC_BPOSGE32: +tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); +MIPS_DEBUG(bposge32 %s, TARGET_FMT_lx, t0, btgt); +goto not_likely; +#if defined(TARGET_MIPS64) +case OPC_BPOSGE64: +tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); +MIPS_DEBUG(bposge64 %s, TARGET_FMT_lx, t0, btgt); +goto not_likely; +#endif case OPC_BLTZALS: case OPC_BLTZAL: ctx-hflags |= (opc == OPC_BLTZALS @@ -11222,10 +11258,6 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx, (ctx-opcode 18) 0x7, imm 1); *is_branch = 1; break; -case BPOSGE64: -case BPOSGE32: -/* MIPS DSP: not implemented */ -/* Fall through */ default: MIPS_INVAL(pool32i); generate_exception(ctx, EXCP_RI); @@ -12134,6 +12166,18 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) check_insn(env, ctx, ISA_MIPS32R2); /* Treat as NOP. */ break; +case OPC_BPOSGE32:/* MIPS DSP branch */ +check_insn(env, ctx, ASE_DSP); check_insn() is not enough there. It only checks if the CPU support the instruction set, while the DSP ASE manual says that the DSPEn bit should be set to allow execution of DSP instructions, otherwise a State Disabled Exception should be generated. It's something important so that the OS can do lazy context switching. Please look for example at the check_cop1x() instruction to see how to do that. +gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm 2); +*is_branch = 1; +break; +#if defined(TARGET_MIPS64) +case OPC_BPOSGE64: +check_insn(env, ctx, ASE_DSP); +gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm 2); +*is_branch = 1; +break; +#endif default:/* Invalid */ MIPS_INVAL(regimm); generate_exception(ctx, EXCP_RI); -- 1.7.9.5 -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
[Qemu-devel] [PATCH 2/2] Add IP-Octal 232 IndustryPack emulation
The IP-Octal 232 is an IndustryPack module that implements eight RS-232 serial ports, each one of which can be redirected to a character device in the host. Signed-off-by: Alberto Garcia agar...@igalia.com --- hw/Makefile.objs |2 +- hw/ipoctal.c | 662 ++ 2 ficheiros modificados, 663 adições(+), 1 eliminado(-) create mode 100644 hw/ipoctal.c diff --git a/hw/Makefile.objs b/hw/Makefile.objs index f4a3a9b..dfb3042 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -100,7 +100,7 @@ hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o hw-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o # IndustryPack -hw-obj-$(CONFIG_IPACK) += tpci200.o ipack.o +hw-obj-$(CONFIG_IPACK) += tpci200.o ipoctal.o ipack.o # PCI network cards hw-obj-$(CONFIG_NE2000_PCI) += ne2000.o diff --git a/hw/ipoctal.c b/hw/ipoctal.c new file mode 100644 index 000..e655bf2 --- /dev/null +++ b/hw/ipoctal.c @@ -0,0 +1,662 @@ +/* + * QEMU IP-Octal 232 IndustryPack emulation + * + * Copyright (C) 2012 Igalia, S.L. + * Author: Alberto Garcia agar...@igalia.com + * + * This code is licensed under the GNU GPL v2 or (at your option) any + * later version. + */ + +#include ipack.h +#include qemu-timer.h +#include glib.h + +/* #define DEBUG_IPOCTAL */ + +#ifdef DEBUG_IPOCTAL +#define DPRINTF2(fmt, ...) \ +do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF2(fmt, ...) do { } while (0) +#endif + +#define DPRINTF(fmt, ...) DPRINTF2(IP-Octal: fmt, ## __VA_ARGS__) + +#define TIMER_INTERVAL (qemu_get_clock_ms(vm_clock) + 1) + +/* The IP-Octal has 8 channels (a-h) + divided into 4 blocks (A-D) */ +#define N_CHANNELS 8 +#define N_BLOCKS 4 + +#define REG_MRa 0x01 +#define REG_MRb 0x11 +#define REG_SRa 0x03 +#define REG_SRb 0x13 +#define REG_CSRa 0x03 +#define REG_CSRb 0x13 +#define REG_CRa 0x05 +#define REG_CRb 0x15 +#define REG_RHRa 0x07 +#define REG_RHRb 0x17 +#define REG_THRa 0x07 +#define REG_THRb 0x17 +#define REG_ACR 0x09 +#define REG_ISR 0x0B +#define REG_IMR 0x0B +#define REG_OPCR 0x1B + +#define CR_ENABLE_RX(1 0) +#define CR_DISABLE_RX (1 1) +#define CR_ENABLE_TX(1 2) +#define CR_DISABLE_TX (1 3) +#define CR_CMD(cr) ((cr) 4) +#define CR_NO_OP0 +#define CR_RESET_MR 1 +#define CR_RESET_RX 2 +#define CR_RESET_TX 3 +#define CR_RESET_ERR4 +#define CR_RESET_BRKINT 5 +#define CR_START_BRK6 +#define CR_STOP_BRK 7 +#define CR_ASSERT_RTSN 8 +#define CR_NEGATE_RTSN 9 +#define CR_TIMEOUT_ON 10 +#define CR_TIMEOUT_OFF 12 + +#define SR_RXRDY (1 0) +#define SR_FFULL (1 1) +#define SR_TXRDY (1 2) +#define SR_TXEMT (1 3) +#define SR_OVERRUN (1 4) +#define SR_PARITY (1 5) +#define SR_FRAMING (1 6) +#define SR_BREAK (1 7) + +#define ISR_TXRDYA (1 0) +#define ISR_RXRDYA (1 1) +#define ISR_BREAKA (1 2) +#define ISR_CNTRDY (1 3) +#define ISR_TXRDYB (1 4) +#define ISR_RXRDYB (1 5) +#define ISR_BREAKB (1 6) +#define ISR_MPICHG (1 7) +#define ISR_TXRDY(CH) (1 (((CH) 1) ? 4 : 0)) +#define ISR_RXRDY(CH) (1 (((CH) 1) ? 5 : 1)) +#define ISR_BREAK(CH) (1 (((CH) 1) ? 6 : 2)) + +typedef struct IPOctalState IPOctalState; +typedef struct SCC2698Channel SCC2698Channel; +typedef struct SCC2698Block SCC2698Block; + +struct SCC2698Channel { +IPOctalState *ipoctal; +CharDriverState *dev; +char *devpath; +bool tx_enabled; +bool rx_enabled; +bool tx_data; +bool rx_data; +uint8_t mr[2]; +uint8_t mr_idx; +uint8_t sr; +uint8_t thr; +uint8_t rhr; +}; + +struct SCC2698Block { +uint8_t imr; +uint8_t isr; +}; + +struct IPOctalState { +IPackDevice dev; +SCC2698Channel ch[N_CHANNELS]; +SCC2698Block blk[N_BLOCKS]; +uint8_t irq_vector; +QEMUTimer *timer; +}; + +static const VMStateDescription vmstate_scc2698_channel = { +.name = scc2698_channel, +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_BOOL(tx_enabled, SCC2698Channel), +VMSTATE_BOOL(rx_enabled, SCC2698Channel), +VMSTATE_BOOL(tx_data, SCC2698Channel), +VMSTATE_BOOL(rx_data, SCC2698Channel), +VMSTATE_UINT8_ARRAY(mr, SCC2698Channel, 2), +VMSTATE_UINT8(mr_idx, SCC2698Channel), +VMSTATE_UINT8(sr, SCC2698Channel), +VMSTATE_UINT8(thr, SCC2698Channel), +VMSTATE_UINT8(rhr, SCC2698Channel), +VMSTATE_END_OF_LIST() +} +}; + +static const VMStateDescription vmstate_scc2698_block = { +.name = scc2698_block, +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT8(imr, SCC2698Block), +VMSTATE_UINT8(isr, SCC2698Block), +VMSTATE_END_OF_LIST() +} +}; + +static const VMStateDescription vmstate_ipoctal = { +.name = ipoctal, +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old
Re: [Qemu-devel] [PATCH v6 04/13] target-mips-ase-dsp: Add load instructions
On Tue, Aug 21, 2012 at 02:53:10PM +0800, Jia Liu wrote: Add MIPS ASE DSP Load instructions. Signed-off-by: Jia Liu pro...@gmail.com --- target-mips/translate.c | 69 +++ 1 file changed, 69 insertions(+) diff --git a/target-mips/translate.c b/target-mips/translate.c index b049238..f154f09 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -313,6 +313,9 @@ enum { OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3, OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3, OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3, + +/* MIPS DSP Load */ +OPC_LX_DSP = 0x0A | OPC_SPECIAL3, }; /* BSHFL opcodes */ @@ -340,6 +343,17 @@ enum { #endif }; +#define MASK_LX(op) (MASK_SPECIAL3(op) | (op (0x1F 6))) +/* MIPS DSP Load */ +enum { +OPC_LBUX = (0x06 6) | OPC_LX_DSP, +OPC_LHX = (0x04 6) | OPC_LX_DSP, +OPC_LWX = (0x00 6) | OPC_LX_DSP, +#if defined(TARGET_MIPS64) +OPC_LDX = (0x08 6) | OPC_LX_DSP, +#endif +}; + /* Coprocessor 0 (rs field) */ #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op (0x1F 21)) @@ -12124,6 +12138,61 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) check_insn(env, ctx, INSN_LOONGSON2E); gen_loongson_integer(ctx, op1, rd, rs, rt); break; +case OPC_LX_DSP: +op2 = MASK_LX(ctx-opcode); +switch (op2) { +case OPC_LBUX: +check_insn(env, ctx, ASE_DSP); How about factorizing the check_insn() code one level above? +{ +TCGv addr = tcg_temp_new(); + +save_cpu_state(ctx, 1); I don't think you need to save pc here, they are normal load instructions. +gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]); +op_ld_lbu(cpu_gpr[rd], addr, ctx); +tcg_temp_free(addr); +break; +} +case OPC_LHX: +check_insn(env, ctx, ASE_DSP); +{ +TCGv addr = tcg_temp_new(); + +save_cpu_state(ctx, 1); +gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]); +op_ld_lh(cpu_gpr[rd], addr, ctx); +tcg_temp_free(addr); +break; +} +case OPC_LWX: +check_insn(env, ctx, ASE_DSP); +{ +TCGv addr = tcg_temp_new(); + +save_cpu_state(ctx, 1); +gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]); +op_ld_lw(cpu_gpr[rd], addr, ctx); +tcg_temp_free(addr); +break; +} +#if defined(TARGET_MIPS64) +case OPC_LDX: +check_insn(env, ctx, ASE_DSP); +{ +TCGv addr = tcg_temp_new(); + +save_cpu_state(ctx, 1); +gen_op_addr_add(ctx, addr, cpu_gpr[rs], cpu_gpr[rt]); +op_ld_ld(cpu_gpr[rd], addr, ctx); +tcg_temp_free(addr); +break; +} +#endif +default:/* Invalid */ +MIPS_INVAL(MASK LX); +generate_exception(ctx, EXCP_RI); +break; +} +break; #if defined(TARGET_MIPS64) case OPC_DEXTM ... OPC_DEXT: case OPC_DINSM ... OPC_DINS: -- 1.7.9.5 -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [QEMU][RFC V2 01/10] xen: add new machine options to support QEMU disaggregation in Xen environment
On Wed, 22 Aug 2012, Julien Grall wrote: - xen_dmid: specify the id of QEMU. It will be used to retrieve/store information inside XenStore. - xen_default_dev (on/off): as default devices need to be create in each QEMU (due to code dependency), this option specifies if it will register range/PCI of default device via xen hypercall. (Root bridge, south bridge, ...). - xen_emulate_ide (on/off): enable/disable emulation in QEMU. Signed-off-by: Julien Grall julien.gr...@citrix.com --- qemu-config.c | 12 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/qemu-config.c b/qemu-config.c index c05ffbc..7740442 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -612,6 +612,18 @@ static QemuOptsList qemu_machine_opts = { .name = dump-guest-core, .type = QEMU_OPT_BOOL, .help = Include guest memory in a core dump, +}, { +.name = xen_dmid, +.type = QEMU_OPT_NUMBER, +.help = Xen device model id, +}, { +.name = xen_default_dev, +.type = QEMU_OPT_BOOL, +.help = emulate Xen default device (South Bridge, IDE, ...) ^devices It would be good to document exactly which ones are these (the default devices) +}, { +.name = xen_emulate_ide, +.type = QEMU_OPT_BOOL, +.help = emulate IDE with XEN }, Is this really a Xen specific option? Couldn't be used for example by people that wants to use virtio-scsi on KVM without IDE emulation? { /* End of list */ } }, -- Julien Grall
Re: [Qemu-devel] [QEMU][RFC V2 05/10] xen-memory: register memory/IO range in Xen
On Wed, 22 Aug 2012, Julien Grall wrote: Add Memory listener on IO and modify the one on memory. Becareful, the first listener is not called is the range is still register with register_ioport*. So Xen will never know that this QEMU is handle the range. I don't understand what you mean here. Could you please elaborate? IO request works as before, the only thing is QEMU will never receive IO request that it can't handle. y Changes to be committed: Just remove this line from the commit message. Signed-off-by: Julien Grall julien.gr...@citrix.com --- xen-all.c | 113 + 1 files changed, 113 insertions(+), 0 deletions(-) diff --git a/xen-all.c b/xen-all.c index 5f05838..14e5d3d 100644 --- a/xen-all.c +++ b/xen-all.c @@ -152,6 +152,7 @@ typedef struct XenIOState { struct xs_handle *xenstore; MemoryListener memory_listener; +MemoryListener io_listener; QLIST_HEAD(, XenPhysmap) physmap; target_phys_addr_t free_phys_offset; const XenPhysmap *log_for_dirtybit; @@ -195,6 +196,31 @@ void xen_hvm_inject_msi(uint64_t addr, uint32_t data) xen_xc_hvm_inject_msi(xen_xc, xen_domid, addr, data); } +static void xen_map_iorange(target_phys_addr_t addr, uint64_t size, +int is_mmio, const char *name) +{ +/* Don't register xen.ram */ +if (is_mmio !strncmp(name, xen.ram, 7)) { +return; +} + +DPRINTF(map %s %s 0xTARGET_FMT_plx - 0xTARGET_FMT_plx\n, +(is_mmio) ? mmio : io, name, addr, addr + size - 1); + +xen_xc_hvm_map_io_range_to_ioreq_server(xen_xc, xen_domid, serverid, +is_mmio, addr, addr + size - 1); +} + +static void xen_unmap_iorange(target_phys_addr_t addr, uint64_t size, + int is_mmio) +{ +DPRINTF(unmap %s %s 0xTARGET_FMT_plx - 0xTARGET_FMT_plx\n, +(is_mmio) ? mmio : io, name, addr, addr + size - 1); + +xen_xc_hvm_unmap_io_range_from_ioreq_server(xen_xc, xen_domid, serverid, +is_mmio, addr); +} + static void xen_suspend_notifier(Notifier *notifier, void *data) { xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3); @@ -527,12 +553,16 @@ static void xen_region_add(MemoryListener *listener, MemoryRegionSection *section) { xen_set_memory(listener, section, true); +xen_map_iorange(section-offset_within_address_space, +section-size, 1, section-mr-name); } static void xen_region_del(MemoryListener *listener, MemoryRegionSection *section) { xen_set_memory(listener, section, false); +xen_unmap_iorange(section-offset_within_address_space, + section-size, 1); } static void xen_region_nop(MemoryListener *listener, @@ -651,6 +681,86 @@ static MemoryListener xen_memory_listener = { .priority = 10, }; +static void xen_io_begin(MemoryListener *listener) +{ +} + +static void xen_io_commit(MemoryListener *listener) +{ +} + +static void xen_io_region_add(MemoryListener *listener, + MemoryRegionSection *section) +{ +xen_map_iorange(section-offset_within_address_space, +section-size, 0, section-mr-name); +} + +static void xen_io_region_del(MemoryListener *listener, + MemoryRegionSection *section) +{ +xen_unmap_iorange(section-offset_within_address_space, + section-size, 0); +} + +static void xen_io_region_nop(MemoryListener *listener, + MemoryRegionSection *section) +{ +} + +static void xen_io_log_start(MemoryListener *listener, + MemoryRegionSection *section) +{ +} + +static void xen_io_log_stop(MemoryListener *listener, +MemoryRegionSection *section) +{ +} + +static void xen_io_log_sync(MemoryListener *listener, +MemoryRegionSection *section) +{ +} + +static void xen_io_log_global_start(MemoryListener *listener) +{ +} + +static void xen_io_log_global_stop(MemoryListener *listener) +{ +} + +static void xen_io_eventfd_add(MemoryListener *listener, + MemoryRegionSection *section, + bool match_data, uint64_t data, + EventNotifier *e) +{ +} + +static void xen_io_eventfd_del(MemoryListener *listener, + MemoryRegionSection *section, + bool match_data, uint64_t data, + EventNotifier *e) +{ +} + +static MemoryListener xen_io_listener = { +.begin = xen_io_begin, +.commit = xen_io_commit, +.region_add = xen_io_region_add, +
Re: [Qemu-devel] [QEMU][RFC V2 06/10] xen-pci: register PCI device in Xen and handle IOREQ_TYPE_PCI_CONFIG
On Wed, 22 Aug 2012, Julien Grall wrote: With QEMU disaggregation QEMU needs to specify which PCI device it's able to handle. It will use the device place in the topology (domain, bus, device, function). When Xen will trap an access for the config space, it will forge a new ioreq and forward it to the right QEMU. Signed-off-by: Julien Grall julien.gr...@citrix.com --- hw/pci.c |6 ++ hw/xen.h |1 + xen-all.c | 38 ++ xen-stub.c |5 + 4 files changed, 50 insertions(+), 0 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 4d95984..0112edf 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -33,6 +33,7 @@ #include qmp-commands.h #include msi.h #include msix.h +#include xen.h //#define DEBUG_PCI #ifdef DEBUG_PCI @@ -781,6 +782,11 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, pci_dev-devfn = devfn; pstrcpy(pci_dev-name, sizeof(pci_dev-name), name); pci_dev-irq_state = 0; + +if (xen_enabled() xen_register_pcidev(pci_dev)) { +return NULL; Is this an error condition? If so we should print an error message, right? +} + pci_config_alloc(pci_dev); pci_config_set_vendor_id(pci_dev-config, pc-vendor_id); diff --git a/hw/xen.h b/hw/xen.h index e5926b7..663731a 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -35,6 +35,7 @@ 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_hvm_inject_msi(uint64_t addr, uint32_t data); +int xen_register_pcidev(PCIDevice *pci_dev); 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 14e5d3d..485c312 100644 --- a/xen-all.c +++ b/xen-all.c @@ -174,6 +174,16 @@ void xen_piix3_set_irq(void *opaque, int irq_num, int level) irq_num 3, level); } +int xen_register_pcidev(PCIDevice *pci_dev) +{ +DPRINTF(register pci %x:%x.%x %s\n, 0, (pci_dev-devfn 3) 0x1f, +pci_dev-devfn 0x7, pci_dev-name); + +return xen_xc_hvm_register_pcidev(xen_xc, xen_domid, serverid, + 0, 0, pci_dev-devfn 3, + pci_dev-devfn 0x7); +} + void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) { int i; @@ -943,6 +953,29 @@ static void cpu_ioreq_move(ioreq_t *req) } } +#if __XEN_LATEST_INTERFACE_VERSION__ = 0x00040300 +static void cpu_ioreq_config_space(ioreq_t *req) +{ +uint64_t cf8 = req-addr; +uint32_t tmp = req-size; +uint16_t size = req-size 0xff; +uint16_t off = req-size 16; + +if ((size + off + 0xcfc) 0xd00) { +hw_error(Invalid ioreq config space size = %u off = %u\n, + size, off); +} + +req-addr = 0xcfc + off; +req-size = size; + +do_outp(0xcf8, 4, cf8); +cpu_ioreq_pio(req); +req-addr = cf8; +req-size = tmp; +} +#endif + static void handle_ioreq(ioreq_t *req) { if (!req-data_is_ptr (req-dir == IOREQ_WRITE) @@ -962,6 +995,11 @@ static void handle_ioreq(ioreq_t *req) case IOREQ_TYPE_INVALIDATE: xen_invalidate_map_cache(); break; +#if __XEN_LATEST_INTERFACE_VERSION__ = 0x00040300 +case IOREQ_TYPE_PCI_CONFIG: +cpu_ioreq_config_space(req); +break; +#endif default: hw_error(Invalid ioreq type 0x%x\n, req-type); } diff --git a/xen-stub.c b/xen-stub.c index 8ff2b79..0128965 100644 --- a/xen-stub.c +++ b/xen-stub.c @@ -25,6 +25,11 @@ void xen_piix3_set_irq(void *opaque, int irq_num, int level) { } +int xen_register_pcidev(PCIDevice *pci_dev) +{ +return 1; +} + void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) { } -- Julien Grall
Re: [Qemu-devel] [QEMU][RFC V2 07/10] xen: specify which device is part of default devices
On Wed, 22 Aug 2012, Julien Grall wrote: One major problem of QEMU disaggregation is that some devices needs to be emulate in each QEMU, but only one need to register it in Xen. This patch introduces helpers that can be used in QEMU code (for instance hw/pc_piix.c) to specify if the device is part of default sets. Signed-off-by: Julien Grall julien.gr...@citrix.com --- hw/pc_piix.c |2 ++ hw/xen.h | 20 xen-all.c| 29 +++-- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 0c0096f..6cb0a2a 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -342,9 +342,11 @@ static void pc_xen_hvm_init(ram_addr_t ram_size, if (xen_hvm_init() != 0) { hw_error(xen hardware virtual machine initialisation failed); } +xen_set_register_default_dev(1, NULL); pc_init_pci_no_kvmclock(ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model); +xen_set_register_default_dev(0, NULL); xen_vcpu_init(); } Honestly I don't like this interface, I would rather have an explicit list of default devices and then go through them in xen_register_pcidev and xen_map_iorange. #endif diff --git a/hw/xen.h b/hw/xen.h index 663731a..3c8724f 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -21,6 +21,7 @@ extern uint32_t xen_domid; extern enum xen_mode xen_mode; extern int xen_allowed; +extern int xen_register_default_dev; static inline int xen_enabled(void) { @@ -31,6 +32,25 @@ static inline int xen_enabled(void) #endif } +static inline int xen_is_registered_default_dev(void) +{ +#if defined(CONFIG_XEN) +return xen_register_default_dev; +#else +return 1; +#endif +} + +static inline void xen_set_register_default_dev(int val, int *old) +{ +#if defined(CONFIG_XEN) +if (old) { +*old = xen_register_default_dev; +} +xen_register_default_dev = val; +#endif +} + 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); diff --git a/xen-all.c b/xen-all.c index 485c312..afa9bcc 100644 --- a/xen-all.c +++ b/xen-all.c @@ -39,6 +39,10 @@ static MemoryRegion *framebuffer; static unsigned int serverid; static uint32_t xen_dmid = ~0; +/* Use to tell if we register pci/mmio/pio of default devices */ +int xen_register_default_dev = 0; +static int xen_emulate_default_dev = 1; /* Compatibility with older version */ #if __XEN_LATEST_INTERFACE_VERSION__ 0x0003020a static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i) @@ -176,6 +180,10 @@ void xen_piix3_set_irq(void *opaque, int irq_num, int level) int xen_register_pcidev(PCIDevice *pci_dev) { +if (xen_register_default_dev !xen_emulate_default_dev) { +return 0; +} DPRINTF(register pci %x:%x.%x %s\n, 0, (pci_dev-devfn 3) 0x1f, pci_dev-devfn 0x7, pci_dev-name); @@ -214,6 +222,18 @@ static void xen_map_iorange(target_phys_addr_t addr, uint64_t size, return; } +/* Handle the registration of all default io range */ +if (xen_register_default_dev) { +/* Register ps/2 only if we emulate VGA */ +if (!strcmp(name, i8042-data) || !strcmp(name, i8042-cmd)) { +if (display_type == DT_NOGRAPHIC) { +return; +} +} else if (!xen_emulate_default_dev strcmp(name, serial)) { +return; +} +} It seems to be that you are acting upon xen_register_default_dev only in xen_map_iorange and xen_register_pcidev, so it shouldn't be difficult to have a real list of default devices instead. DPRINTF(map %s %s 0xTARGET_FMT_plx - 0xTARGET_FMT_plx\n, (is_mmio) ? mmio : io, name, addr, addr + size - 1); @@ -1300,6 +1320,8 @@ int xen_hvm_init(void) if (!QTAILQ_EMPTY(list-head)) { xen_dmid = qemu_opt_get_number(QTAILQ_FIRST(list-head), xen_dmid, ~0); +xen_emulate_default_dev = qemu_opt_get_bool(QTAILQ_FIRST(list-head), +xen_default_dev, 1); } state = g_malloc0(sizeof (XenIOState)); @@ -1395,9 +1417,12 @@ int xen_hvm_init(void) fprintf(stderr, %s: xen backend core setup failed\n, __FUNCTION__); exit(1); } -xen_be_register(console, xen_console_ops); -xen_be_register(vkbd, xen_kbdmouse_ops); xen_be_register(qdisk, xen_blkdev_ops); + +if (xen_emulate_default_dev) { +xen_be_register(console, xen_console_ops); +xen_be_register(vkbd, xen_kbdmouse_ops); +} xen_read_physmap(state);
Re: [Qemu-devel] [QEMU][RFC V2 08/10] xen: audio is not a part of default devices
On Wed, 22 Aug 2012, Julien Grall wrote: Signed-off-by: Julien Grall julien.gr...@citrix.com --- arch_init.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/arch_init.c b/arch_init.c index 9b46bfc..1077b16 100644 --- a/arch_init.c +++ b/arch_init.c @@ -44,6 +44,7 @@ #include exec-memory.h #include hw/pcspk.h #include qemu/page_cache.h +#include hw/xen.h #ifdef DEBUG_ARCH_INIT #define DPRINTF(fmt, ...) \ @@ -976,6 +977,9 @@ void select_soundhw(const char *optarg) void audio_init(ISABus *isa_bus, PCIBus *pci_bus) { struct soundhw *c; +int register_default_dev; + +xen_set_register_default_dev(0, register_default_dev); for (c = soundhw; c-name; ++c) { if (c-enabled) { @@ -990,6 +994,8 @@ void audio_init(ISABus *isa_bus, PCIBus *pci_bus) } } } + +xen_set_register_default_dev(register_default_dev, NULL); } #else void select_soundhw(const char *optarg) and this is why it is better to have a list rather than a stateful register_default_dev integer. This stuff is really easy to break.
Re: [Qemu-devel] [QEMU][RFC V2 10/10] xen: emulate IDE outside default device set
On Wed, 22 Aug 2012, Julien Grall wrote: IDE can be emulate in a different QEMU that the default. This patch also fixes ide_get_geometry. When QEMU didn't emulate IDE, ^doesn't it try to derefence a NULL bus. ^tries to dereference Signed-off-by: Julien Grall julien.gr...@citrix.com --- hw/ide/qdev.c |8 +++- hw/pc_piix.c | 38 -- hw/xen.h | 10 ++ xen-all.c |8 +++- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 5ea9b8f..473acd7 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -115,7 +115,13 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive) int ide_get_geometry(BusState *bus, int unit, int16_t *cyls, int8_t *heads, int8_t *secs) { -IDEState *s = DO_UPCAST(IDEBus, qbus, bus)-ifs[unit]; +IDEState *s = NULL; + +if (!bus) { +return -1; +} + +s = DO_UPCAST(IDEBus, qbus, bus)-ifs[unit]; if (s-drive_kind != IDE_HD || !s-bs) { return -1; diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 6cb0a2a..b904100 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -148,6 +148,7 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; +int register_default_dev = 0; pc_cpus_init(cpu_model); @@ -242,23 +243,32 @@ static void pc_init1(MemoryRegion *system_memory, pci_nic_init_nofail(nd, e1000, NULL); } -ide_drive_get(hd, MAX_IDE_BUS); -if (pci_enabled) { -PCIDevice *dev; -if (xen_enabled()) { -dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1); +if (!xen_enabled() || xen_is_emulated_ide()) { +xen_set_register_default_dev(0, register_default_dev); +ide_drive_get(hd, MAX_IDE_BUS); +if (pci_enabled) { +PCIDevice *dev; +if (xen_enabled()) { +dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1); +} else { +dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); +} +idebus[0] = qdev_get_child_bus(dev-qdev, ide.0); +idebus[1] = qdev_get_child_bus(dev-qdev, ide.1); } else { -dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); +for (i = 0; i MAX_IDE_BUS; i++) { +ISADevice *dev; +dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], + ide_irq[i], + hd[MAX_IDE_DEVS * i], + hd[MAX_IDE_DEVS * i + 1]); +idebus[i] = qdev_get_child_bus(dev-qdev, ide.0); +} } -idebus[0] = qdev_get_child_bus(dev-qdev, ide.0); -idebus[1] = qdev_get_child_bus(dev-qdev, ide.1); +xen_set_register_default_dev(register_default_dev, NULL); } else { -for(i = 0; i MAX_IDE_BUS; i++) { -ISADevice *dev; -dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], - ide_irq[i], - hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); -idebus[i] = qdev_get_child_bus(dev-qdev, ide.0); +for (i = 0; i MAX_IDE_BUS; i++) { +idebus[i] = NULL; } } I think it would be better to have a non-xen specific option to enable/disable ide emulation, something like hpet/no_hpet. diff --git a/hw/xen.h b/hw/xen.h index 3c8724f..3c89fb9 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -22,6 +22,7 @@ extern enum xen_mode xen_mode; extern int xen_allowed; extern int xen_register_default_dev; +extern int xen_emulate_ide; static inline int xen_enabled(void) { @@ -32,6 +33,15 @@ static inline int xen_enabled(void) #endif } +static inline int xen_is_emulated_ide(void) +{ +#if defined(CONFIG_XEN) +return xen_emulate_ide; +#else +return 1; +#endif +} + static inline int xen_is_registered_default_dev(void) { #if defined(CONFIG_XEN) diff --git a/xen-all.c b/xen-all.c index f424cce..f091908 100644 --- a/xen-all.c +++ b/xen-all.c @@ -43,6 +43,8 @@ static uint32_t xen_dmid = ~0; int xen_register_default_dev = 0; static int xen_emulate_default_dev = 1; +int xen_emulate_ide = 0; + /* Compatibility with older version */ #if __XEN_LATEST_INTERFACE_VERSION__ 0x0003020a static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i) @@ -1342,6 +1344,8 @@ int xen_hvm_init(void) xen_dmid, ~0); xen_emulate_default_dev = qemu_opt_get_bool(QTAILQ_FIRST(list-head), xen_default_dev, 1); +xen_emulate_ide =
Re: [Qemu-devel] [PATCH v6 08/13] target-mips-ase-dsp: Add bit/manipulation instructions
On Tue, Aug 21, 2012 at 02:53:14PM +0800, Jia Liu wrote: Add MIPS ASE DSP Bit/Manipulation instructions. Signed-off-by: Jia Liu pro...@gmail.com --- target-mips/dsp_helper.c | 79 + target-mips/helper.h |7 ++ target-mips/translate.c | 289 +- 3 files changed, 374 insertions(+), 1 deletion(-) diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c index ff51d2f..4564d9c 100644 --- a/target-mips/dsp_helper.c +++ b/target-mips/dsp_helper.c @@ -6211,6 +6211,85 @@ void helper_dmsubu(CPUMIPSState *env, } #endif +/** DSP Bit/Manipulation Sub-class insns **/ +target_ulong helper_bitrev(target_ulong rt) +{ +int32_t temp; +uint32_t rd; +int i, last; + +temp = rt MIPSDSP_LO; +rd = 0; +for (i = 0; i 16; i++) { +last = temp % 2; +temp = temp 1; +rd = rd | (last (15 - i)); +} + +return (target_ulong)rd; +} + +target_ulong helper_insv(CPUMIPSState *env, target_ulong rs, target_ulong rt) +{ +uint32_t pos, size, msb, lsb, rs_f, rt_f; +uint32_t temp, temprs, temprt; +uint32_t rs_notword, rt_notword; +target_ulong dspc; + +dspc = env-active_tc.DSPControl; +pos = dspc 0x1F; +size = (dspc 7) 0x1F; +msb = pos + size - 1; +lsb = pos; + +rs_notword = not_word_value(rs); +rt_notword = not_word_value(rt); + +if ((lsb msb) || (rs_notword == 1) || (rt_notword == 1)) { +return rt; +} + +rs_f = (((int32_t)0x01 (msb - lsb + 1 + 1)) - 1) lsb; +rt_f = rs_f ^ 0x; +temprs = rs rs_f; +temprt = rt rt_f; +temp = temprs | temprt; + +return (target_long)(int32_t)temp; +} + +#if defined(TARGET_MIPS64) +target_ulong helper_dinsv(CPUMIPSState *env, target_ulong rs, target_ulong rt) +{ +target_ulong dspctrl; +target_ulong filter; +uint8_t pos, size; +uint8_t msb, lsb; +uint64_t temp; + +temp = rt; +dspctrl = env-active_tc.DSPControl; +pos = dspctrl 0x7F; +size = (dspctrl 7) 0x3F; + +msb = pos + size - 1; +lsb = pos; + +if ((lsb msb) || (msb 63)) { +return temp; +} + +temp = 0; +filter = ((target_ulong)0x01 size) - 1; +filter = filter pos; + +temp |= rs filter; +temp |= rt (~filter); + +return temp; +} +#endif + #undef MIPSDSP_LHI #undef MIPSDSP_LLO #undef MIPSDSP_HI diff --git a/target-mips/helper.h b/target-mips/helper.h index 69bcb6c..df86ef9 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -582,4 +582,11 @@ DEF_HELPER_FLAGS_4(dmsub, 0, void, env, tl, tl, i32) DEF_HELPER_FLAGS_4(dmsubu, 0, void, env, tl, tl, i32) #endif +/* DSP Bit/Manipulation Sub-class insns */ +DEF_HELPER_FLAGS_1(bitrev, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl) +DEF_HELPER_FLAGS_3(insv, 0, tl, env, tl, tl) +#if defined(TARGET_MIPS64) +DEF_HELPER_FLAGS_3(dinsv, 0, tl, env, tl, tl); +#endif + #include def-helper.h diff --git a/target-mips/translate.c b/target-mips/translate.c index d8f83e0..1a9df0f 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -343,6 +343,11 @@ enum { #if defined(TARGET_MIPS64) OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, #endif +/* DSP Bit/Manipulation Sub-class */ +OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, +#if defined(TARGET_MIPS64) +OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, +#endif }; /* BSHFL opcodes */ @@ -450,6 +455,12 @@ enum { OPC_PRECEU_PH_QBR = (0x1D 6) | OPC_ABSQ_S_PH_DSP, OPC_PRECEU_PH_QBLA = (0x1E 6) | OPC_ABSQ_S_PH_DSP, OPC_PRECEU_PH_QBRA = (0x1F 6) | OPC_ABSQ_S_PH_DSP, +/* DSP Bit/Manipulation Sub-class */ +OPC_BITREV = (0x1B 6) | OPC_ABSQ_S_PH_DSP, +OPC_REPL_QB = (0x02 6) | OPC_ABSQ_S_PH_DSP, +OPC_REPLV_QB= (0x03 6) | OPC_ABSQ_S_PH_DSP, +OPC_REPL_PH = (0x0A 6) | OPC_ABSQ_S_PH_DSP, +OPC_REPLV_PH= (0x0B 6) | OPC_ABSQ_S_PH_DSP, }; #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op (0x1F 6))) @@ -518,6 +529,12 @@ enum { OPC_MULSA_W_PH= (0x02 6) | OPC_DPA_W_PH_DSP, }; +#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op (0x1F 6))) +enum { +/* DSP Bit/Manipulation Sub-class */ +OPC_INSV = (0x00 6) | OPC_INSV_DSP, +}; + #if defined(TARGET_MIPS64) #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op (0x1F 6))) enum { @@ -539,6 +556,13 @@ enum { OPC_ABSQ_S_OB = (0x01 6) | OPC_ABSQ_S_QH_DSP, OPC_ABSQ_S_PW = (0x11 6) | OPC_ABSQ_S_QH_DSP, OPC_ABSQ_S_QH = (0x09 6) | OPC_ABSQ_S_QH_DSP, +/* DSP Bit/Manipulation Sub-class */ +OPC_REPL_OB = (0x02 6) | OPC_ABSQ_S_QH_DSP, +OPC_REPL_PW = (0x12 6) | OPC_ABSQ_S_QH_DSP, +OPC_REPL_QH = (0x0A 6) | OPC_ABSQ_S_QH_DSP, +OPC_REPLV_OB= (0x03 6) |
Re: [Qemu-devel] [PATCH for-1.2 v2] target-mips: Enable access to required RDHWR hardware registers
On Tue, Aug 21, 2012 at 12:31:37PM -0500, Meador Inge wrote: While running in the usermode emulator all of the required* MIPS32r2 RDHWR hardware registers should be accessible (the Linux kernel enables access to these same registers). Note that these registers are still enabled when the MIPS ISA is not release 2. This is OK since the Linux kernel emulates access to them when they are not available in hardware. * There is also the ULR register which is only recommended for full release 2 compliance. Incidentally, accessing this register in the current implementation works fine without flipping its access bit. Signed-off-by: Meador Inge mead...@codesourcery.com --- v1 - v2: * Removed (env-insn_flags ISA_MIPS32R2) condition per feedback from Andreas and Aurelien. target-mips/translate.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 47daf85..d643676 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -12768,8 +12768,9 @@ void cpu_state_reset(CPUMIPSState *env) #if defined(CONFIG_USER_ONLY) env-hflags = MIPS_HFLAG_UM; -/* Enable access to the SYNCI_Step register. */ -env-CP0_HWREna |= (1 1); +/* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR + hardware registers. */ +env-CP0_HWREna |= 0x000F; if (env-CP0_Config1 (1 CP0C1_FP)) { env-hflags |= MIPS_HFLAG_FPU; } Thanks, applied. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] passing translated address out in QEMU
I am emulating arm on x86. i want to track the virt and physical address of last memory operation. so i put 2 fields in the CPUState and make tcg_global_mem_new_i32 on them Therefore, before every translation i generate code to save the virtual address as follow: static inline void gen_st32(TCGv val, TCGv addr, int index) { tcg_gen_mov_i32(cpu_last_vaddr, addr); tcg_gen_qemu_st32(val, addr, index); // tcg_gen_mov_i32(cpu_last_paddr, addr); tcg_temp_free_i32(val); } But i do not know how to save the physical, as the physical address is never passed out of tcg_gen_qemu_st32. what would be the best way to get the physical address here ? i want to pass it out by the TCGv addr here but it did not work ... Xin 0xf3753166: moveax,DWORD PTR [ebp+0x18] 0xf3753169: movedx,eax 0xf375316b: movecx,eax 0xf375316d: movDWORD PTR [ebp+0x6ccc],eax 0xf3753173: movDWORD PTR [ebp+0x3d4],edx 0xf3753179: moveax,0x4 0xf375317e: movDWORD PTR [ebp+0x3dc],eax 0xf3753184: xoreax,eax 0xf3753186: movDWORD PTR [ebp+0x3e0],eax 0xf375318c: movedx,ecx 0xf375318e: moveax,ecx 0xf3753190: shredx,0x6 0xf3753193: andeax,0xfc03 0xf3753199: andedx,0xff0 0xf375319f: leaedx,[ebp+edx*1+0x4c4] 0xf37531a6: cmpeax,DWORD PTR [edx] 0xf37531a8: moveax,ecx 0xf37531aa: jne0xf37531b3 0xf37531ac: addeax,DWORD PTR [edx+0xc] 0xf37531af: moveax,DWORD PTR [eax] 0xf37531b1: jmp0xf37531bc 0xf37531b3: xoredx,edx 0xf37531b5: call 0x8184cb0 __ldl_mmu 0xf37531ba: movedx,eax 0xf37531bc: movedx,DWORD PTR [ebp+0x6ccc] 0xf37531c2: movDWORD PTR [esp],ebp 0xf37531c5: movecx,0xf7d034ac 0xf37531ca: movDWORD PTR [esp+0x4],ecx 0xf37531ce: xorecx,ecx 0xf37531d0: movDWORD PTR [esp+0x8],ecx 0xf37531d4: movecx,DWORD PTR [ebp+0x3d4] 0xf37531da: movDWORD PTR [esp+0xc],ecx 0xf37531de: movDWORD PTR [esp+0x10],edx 0xf37531e2: movDWORD PTR [ebp+0x4],eax 0xf37531e5: movDWORD PTR [ebp+0x3d8],edx On Thu, Aug 23, 2012 at 3:11 AM, 陳韋任 (Wei-Ren Chen) che...@iis.sinica.edu.tw wrote: subtracting host virtual with a fixed offset for ram. but the thing i do not know how to do is how to pass the guest physical back, can i store the guest physical in the TCGv from the guest virtual. Maybe you can store it on a host unused register, perhaps xmm0? ;) Regards, chenwj -- Wei-Ren Chen (陳韋任) Computer Systems Lab, Institute of Information Science, Academia Sinica, Taiwan (R.O.C.) Tel:886-2-2788-3799 #1667 Homepage: http://people.cs.nctu.edu.tw/~chenwj
[Qemu-devel] [PATCH ] lan9118: fix multicast filtering
The lan9118 emulation tries to compute the multicast index by calling directly the crc32() function from zlib, but fails to get the correct result. Use the common compute_mcast_idx() function instead, which gives the correct result. This fixes IPv6 support. Signed-off-by: Aurelien Jarno aurel...@aurel32.net --- hw/lan9118.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/lan9118.c b/hw/lan9118.c index ff0a50b..ceaf96f 100644 --- a/hw/lan9118.c +++ b/hw/lan9118.c @@ -500,7 +500,7 @@ static int lan9118_filter(lan9118_state *s, const uint8_t *addr) } } else { /* Hash matching */ -hash = (crc32(~0, addr, 6) 26); +hash = compute_mcast_idx(addr); if (hash 0x20) { return (s-mac_hashh (hash 0x1f)) 1; } else { -- 1.7.10.4
Re: [Qemu-devel] passing translated address out in QEMU
On 23 August 2012 16:34, Xin Tong xerox.time.t...@gmail.com wrote: I am emulating arm on x86. i want to track the virt and physical address of last memory operation. so i put 2 fields in the CPUState and make tcg_global_mem_new_i32 on them Therefore, before every translation i generate code to save the virtual address as follow: static inline void gen_st32(TCGv val, TCGv addr, int index) { tcg_gen_mov_i32(cpu_last_vaddr, addr); tcg_gen_qemu_st32(val, addr, index); // tcg_gen_mov_i32(cpu_last_paddr, addr); tcg_temp_free_i32(val); } But i do not know how to save the physical, as the physical address is never passed out of tcg_gen_qemu_st32. what would be the best way to get the physical address here ? i want to pass it out by the TCGv addr here but it did not work ... This is quite difficult because our fast-path code doesn't actually deal with the guest physical address at all: we create a TLB which maps directly from guest virtual address to host virtual address and use that most of the time. In general you are running into the problem that QEMU is designed to run code fast, not to be easy to instrument. -- PMM
[Qemu-devel] [ANNOUNCE] QEMU 1.2.0-rc3 release
Hi, On behalf of the QEMU Team, I'd like to announce the availability of the first release candidate for the QEMU 1.2 release. This release is meant for testing purposes and should not be used in a production environment. http://wiki.qemu.org/download/qemu-1.2.0-rc1.tar.bz2 You can help improve the quality of the QEMU 1.2 release by testing this release and reporting bugs on Launchpad: https://bugs.launchpad.net/qemu/ The release plan for the 1.2 release is available at: http://wiki.qemu.org/Planning/1.2 And a detailed change log is available at: http://wiki.qemu.org/ChangeLog/Next Known Issues: - There is a potential for a SEGV during usb_del, this will be fixed in -rc2 - References are not completely released during device removal which may lead to internal memory leaks. Changelog since -rc0: - Update version for 1.2.0-rc1 release (Anthony Liguori) - qapi: add 'query-target' command to return target arch (Daniel P. Berrange) - pci: Tidy up PCI host bridges (Andreas Färber) - pci: Derive PCI host bridges from TYPE_PCI_HOST_BRIDGE (Andreas Färber) - pci_host: Turn into SysBus-derived QOM type (Andreas Färber) - unin_pci: QOM'ify UniNorth PCI host bridges (Andreas Färber) - spapr_pci: QOM'ify sPAPR PCI host bridge (Andreas Färber) - prep_pci: QOM'ify Raven PCI host bridge (Andreas Färber) - ppce500_pci: QOM'ify e500 PCI host bridge (Andreas Färber) - ppc4xx_pci: QOM'ify ppc4xx PCI host bridge (Andreas Färber) - gt64xxx: QOM'ify GT64120 PCI host bridge (Andreas Färber) - grackle_pci: QOM'ify Grackle PCI host bridge (Andreas Färber) - dec_pci: QOM'ify DEC 21154 PCI-PCI bridge (Andreas Färber) - bonito: QOM'ify Bonito PCI host bridge (Andreas Färber) - alpha_typhoon: QOM'ify Typhoon PCI host bridge (Andreas Färber) - pci: Make host bridge TypeInfos const (Andreas Färber) - virtio-blk: hide VIRTIO_BLK_F_CONFIG_WCE from old machine types (Stefan Hajnoczi) - softmmu-semi: fix lock_user* functions not to deref NULL upon OOM (Jim Meyering) - arm-semi: don't leak 1KB user string lock buffer upon TARGET_SYS_OPEN (Jim Meyering) - sheepdog: don't leak socket file descriptor upon connection failure (Jim Meyering) - linux-user: do_msgrcv: don't leak host_mb upon TARGET_EFAULT failure (Jim Meyering) - qemu-ga: don't leak a file descriptor upon failed lockf (Jim Meyering) - xen-all.c: fix multiply issue for int and uint types (Dongxiao Xu) - Fix invalidate if memory requested was not bucket aligned (Frediano Ziglio) - i82378: Remove bogus MMIO coalescing (Jan Kiszka) - eventfd: making it thread safe (Alexey Kardashevskiy) - migration: move total_time from ram stats to migration info (Juan Quintela) - monitor: avoid declaring unused variables (Blue Swirl) - qapi: Fix memory leak (Stefan Weil) - virtio-scsi: add backwards-compatibility properties for 1.1 and earlier machines (Paolo Bonzini) - iscsi: fix races between task completion and abort (Paolo Bonzini) - iscsi: simplify iscsi_schedule_bh (Paolo Bonzini) - iscsi: move iscsi_schedule_bh and iscsi_readv_writev_bh_cb (Paolo Bonzini) - Revert iscsi: Fix NULL dereferences / races between task completion and abort (Paolo Bonzini) - Update OpenBIOS images (Blue Swirl) - pc: Fix RTC CMOS info on RAM for ram_size 1MiB (Markus Armbruster) - vl: Round argument of -m up to multiple of 8KiB (Markus Armbruster) - scsi: fix warning (Gerd Hoffmann) - Avoid asprintf() which is not available on mingw (Gerd Hoffmann) - virtio-blk: hide VIRTIO_BLK_F_CONFIG_WCE from old machine types (Stefan Hajnoczi) - Documentation: Warn against qemu-img on active image (Kevin Wolf) - vmdk: Read footer for streamOptimized images (Kevin Wolf) - vmdk: Fix header structure (Kevin Wolf) - ehci: Fix setting of halt bit from usbcmd register updates (Hans de Goede) - ehci: fix Interrupt Threshold Control implementation (Gerd Hoffmann) - usb: update uas product id (Gerd Hoffmann) - usb: async control xfer fixup (Gerd Hoffmann) Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH for-1.2] linux-user: Clarify Unable to reserve guest address space error
Ping! This didn't get into rc1. thanks -- PMM On 20 August 2012 11:36, Peter Maydell peter.mayd...@linaro.org wrote: Now that we default to reserving nearly 4GB of RAM for the guest address space when running a 32 bit linux-user guest on 64 bit hosts, users are much more likely to run into it. Reword the message to be more informative about what failed and provide suggestions for how to fix things. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- I've had several people run into this and have no idea what the problem was (generally they were running with a ulimit -v setting), so I think it is worth putting this into 1.2. linux-user/main.c |5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/linux-user/main.c b/linux-user/main.c index 7dea084..d4dc015 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3519,7 +3519,10 @@ int main(int argc, char **argv, char **envp) guest_base = init_guest_space(guest_base, reserved_va, 0, have_guest_base); if (guest_base == (unsigned long)-1) { -fprintf(stderr, Unable to reserve guest address space\n); +fprintf(stderr, Unable to reserve 0x%lx bytes of virtual address +space for use as guest address space (check your virtual +memory ulimit setting or reserve less using -R option)\n, +reserved_va); exit(1); } -- 1.7.9.5
Re: [Qemu-devel] passing translated address out in QEMU
On Thu, Aug 23, 2012 at 8:52 AM, Peter Maydell peter.mayd...@linaro.org wrote: On 23 August 2012 16:34, Xin Tong xerox.time.t...@gmail.com wrote: I am emulating arm on x86. i want to track the virt and physical address of last memory operation. so i put 2 fields in the CPUState and make tcg_global_mem_new_i32 on them Therefore, before every translation i generate code to save the virtual address as follow: static inline void gen_st32(TCGv val, TCGv addr, int index) { tcg_gen_mov_i32(cpu_last_vaddr, addr); tcg_gen_qemu_st32(val, addr, index); // tcg_gen_mov_i32(cpu_last_paddr, addr); tcg_temp_free_i32(val); } But i do not know how to save the physical, as the physical address is never passed out of tcg_gen_qemu_st32. what would be the best way to get the physical address here ? i want to pass it out by the TCGv addr here but it did not work ... This is quite difficult because our fast-path code doesn't actually deal with the guest physical address at all: we create a TLB which maps directly from guest virtual address to host virtual address and use that most of the time. In general you are running into the problem that QEMU is designed to run code fast, not to be easy to instrument. even that. is it possible to pass host virtual out. the fast path add the addend to get host virtual ? so it must be in a register, most likely eax in i386. what do you think would be the best way to get that out ? Xin -- PMM
Re: [Qemu-devel] qemu-kvm 1.1.1 hangs using 100% CPU when using ES1370 emulation
[likely not kvm related, CC'ing the appropriate community] On 2012-08-23 18:16, Mike Gerber wrote: Hi, I'm using a KVM guest to stream audio using darkice to an icecast2 server on the same guest. The guest uses an emulated ES1370 sound card to capture the host's audio input (ASUS Xonar DX) using the ALSA backend. After 1 or 2 days, the qemu-kvm process locks up, using up 100% CPU, apparently spinning in audio/rate_template.h (See gdb session below). Do you have any advice on how to solve this problem? I haven't tried the -no-kvm-* switches, please advice if that would be useful in this case. Unfortunately it takes up to 2 days for the bug to happen, so trying all possible configurations is a bit time-consuming. More information here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=685353 Thank you for your time, Mike cpu model: AMD Turion(tm) II Neo N40L Dual-Core Processor qemu-kvm version: 1.1.1 (Debian package by Michael Tokarev), happened also with 1.1.0 host: Debian wheezy, 3.2.23, x86_64 guest: Debian wheezy, 3.2.23, x86_64 /usr/bin/kvm -S -M pc-1.1 -enable-kvm -m 1024 -smp 1,sockets=1,cores=1,threads=1 -name mp3 -uuid 25d2b76c-9533-c55a-b5e2-07da213886f1 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/mp3.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive file=/dev/vg_vms/lv_mp3,if=none,id=drive-virtio-disk0,format=raw -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -netdev tap,fd=20,id=hostnet0 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:b1:e7:80,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -vnc 127.0.0.1:0 -vga cirrus -device ES1370,id=sound0,bus=pci.0,addr=0x6 -device i6300esb,id=watchdog0,bus=pci.0,addr=0x7 -watchdog-action reset -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 gdb output (truncated, full output at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=685353) (gdb) info threads Id Target Id Frame 2Thread 0x7fccec446700 (LWP 19893) kvm 0x7fccf3f5fcec in __lll_lock_wait () from /lib/x86_64-linux-gnu/libpthread.so.0 * 1Thread 0x7fccf7c8c8e0 (LWP 19892) kvm st_rate_flow (opaque=0x7fccf9248f40, ibuf=0x7fccf9150320, obuf=0x7fccf91975b0, isamp=isamp@entry=0x7fffe9ff6550, osamp=osamp@entry=0x7fffe9ff6554) at /tmp/buildd/qemu-kvm-1.1.1+dfsg/audio/rate_template.h:75 (gdb) thread apply all bt full Thread 2 (Thread 0x7fccec446700 (LWP 19893)): #0 0x7fccf3f5fcec in __lll_lock_wait () from /lib/x86_64-linux-gnu/libpthread.so.0 No symbol table info available. #1 0x7fccf3f5b339 in _L_lock_926 () from /lib/x86_64-linux-gnu/libpthread.so.0 No symbol table info available. #2 0x7fccf3f5b15b in pthread_mutex_lock () from /lib/x86_64-linux-gnu/libpthread.so.0 No symbol table info available. #3 0x7fccf7f18c29 in qemu_mutex_lock (mutex=mutex@entry=0x7fccf8c39a80) at /tmp/buildd/qemu-kvm-1.1.1+dfsg/qemu-thread-posix.c:54 err = optimized out __func__ = qemu_mutex_lock #4 0x7fccf7f729f0 in qemu_mutex_lock_iothread () at /tmp/buildd/qemu-kvm-1.1.1+dfsg/cpus.c:897 No locals. #5 0x7fccf7f9a0b6 in kvm_cpu_exec (env=env@entry=0x7fccf902d510) at /tmp/buildd/qemu-kvm-1.1.1+dfsg/kvm-all.c:1268 run = 0x7fccf7d8 ret = optimized out run_ret = 0 #6 0x7fccf7f71591 in qemu_kvm_cpu_thread_fn (arg=0x7fccf902d510) at /tmp/buildd/qemu-kvm-1.1.1+dfsg/cpus.c:752 env = 0x7fccf902d510 r = optimized out #7 0x7fccf3f58b50 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0 No symbol table info available. #8 0x7fccf3ca370d in clone () from /lib/x86_64-linux-gnu/libc.so.6 No symbol table info available. #9 0x in ?? () No symbol table info available. Thread 1 (Thread 0x7fccf7c8c8e0 (LWP 19892)): #0 st_rate_flow (opaque=0x7fccf9248f40, ibuf=0x7fccf9150320, obuf=0x7fccf91975b0, isamp=isamp@entry=0x7fffe9ff6550, osamp=osamp@entry=0x7fffe9ff6554) at /tmp/buildd/qemu-kvm-1.1.1+dfsg/audio/rate_template.h:75 rate = 0x7fccf9248f40 istart = 0x7fccf9148810 iend = 0x7fccf91730c0 ostart = 0x7fccf91975b0 oend = 0x7fccf9197870 ilast = {l = -50003968, r = 171704320} icur = optimized out out = optimized out t = optimized out #1 0x7fccf7e08a96 in audio_pcm_sw_read (sw=0x7fccf9260bf0, buf=0x7fffe9ff65d0, size=optimized out) at /tmp/buildd/qemu-kvm-1.1.1+dfsg/audio/audio.c:952 hw = 0x7fccf924aa20 samples = optimized out live
[Qemu-devel] [PATCH] Better name usb braille device
Windows users need to know that they have to use the Baum driver to make the qemu braille device work. Signed-off-by: Samuel Thibault samuel.thiba...@ens-lyon.org diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index 56743ee..20d60ba 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -113,7 +113,7 @@ enum { static const USBDescStrings desc_strings = { [STR_MANUFACTURER]= QEMU QEMU_VERSION, [STR_PRODUCT_SERIAL] = QEMU USB SERIAL, -[STR_PRODUCT_BRAILLE] = QEMU USB BRAILLE, +[STR_PRODUCT_BRAILLE] = QEMU USB BAUM BRAILLE, [STR_SERIALNUMBER]= 1, };
Re: [Qemu-devel] [QEMU][RFC V2 05/10] xen-memory: register memory/IO range in Xen
On 08/23/2012 03:41 PM, Stefano Stabellini wrote: On Wed, 22 Aug 2012, Julien Grall wrote: Add Memory listener on IO and modify the one on memory. Becareful, the first listener is not called is the range is still register with register_ioport*. So Xen will never know that this QEMU is handle the range. I don't understand what you mean here. Could you please elaborate? I made a patch series to remove all ioport_register_* function in differents devices (dma, cirrus, ...): https://lists.gnu.org/archive/html/qemu-devel/2012-08/msg04007.html ioport_register_* don' t use the new memory API, so listener is not called when a new range is registered. I will rework the commit message and send it back. -- Julien