Re: [Qemu-devel] [PATCH v15 2/2] patch dsdt to use passed-in pvpanic ioport
Il 26/03/2013 02:59, Hu Tao ha scritto: Why doesn't it work with q35? ACPI_EXTRACT_NAME_WORD_CONST dsdt_isa_pest generates two dsdt_isa_pest, one in out/acpi-dsdt.hex the other in out/q35-acpi-dsdt.hex. We should use the one in q35-acpi-dsdt.hex to patch DSDT for q35. But including q35-acpi-dsdt.hex, along with acpi-dsdt.hex, will result in redefinition of dsdt_isa_pest. I didn't see a simple way to solve this. Compile it in a separate file and include it in the SSDT (build_ssdt in src/acpi.c). Paolo
Re: [Qemu-devel] coroutine: hung when using gthread backend
Il 26/03/2013 03:50, Wenchao Xia ha scritto: When I using tcg with coroutine backend = gthread, x86_64-softmmu/qemu-system-x86_64 will hung. Any one working on it? coroutine backend gthread hardly works for qemu, only qemu-io and qemu-img. Paolo
Re: [Qemu-devel] [RFC PATCH 04/10] qemu-ga: Add Windows VSS provider to quiesce applications on fsfreeze
Il 25/03/2013 21:50, Tomoki Sekiyama ha scritto: Hi, Paolo Bonzini pbonz...@redhat.com wrote: Il 14/02/2013 07:10, Tomoki Sekiyama ha scritto: diff --git a/qga/vss-win32-provider/qga-provider.idl b/qga/vss-win32-provider/qga-provider.idl new file mode 100644 index 000..17abca0 --- /dev/null +++ b/qga/vss-win32-provider/qga-provider.idl @@ -0,0 +1,20 @@ +import oaidl.idl; +import ocidl.idl; + +[ +uuid(103B8142-6CE5-48A7-BDE1-794D3192FCF1), +version(1.0), +helpstring(QGAVSSProvider Type Library) +] +library QGAVSSHWProviderLib +{ +importlib(stdole2.tlb); +[ +uuid(6E6A3492-8D4D-440C-9619-5E5D0CC31CA8), +helpstring(QGAVSSProvider Class) +] +coclass QGAVSSHWProvider +{ +[default] interface IUnknown; +}; +}; Ok, I checked widl and it chokes on the importlib line. If that can be removed, it's fine to use widl. The invocation is widl -m32/-m64 -o qga-provider.tlb -t qga-provider.idl where code to choose between -m32 and -m64 is already in the configure script (search for `case $cpu`). Paolo Unfortunately, if I remove importlib(stdole2.tlb), generated .tlb seems rejected to register into Windows COM+ Catalog. Wine has stdole2.tlb in its fakedlls directory, but widl does not accept this by error: Wrong or unsupported typelib magic 405a4d Even if I copied native stdole2.tlb, widl fails with the same error. Do you have any idea about this error? No, I suggest you ask on the Wine mailing lists. In the meanwhile we can include a precompiled .tlb file in the QEMU repository and use midl. Paolo
Re: [Qemu-devel] [PATCH 0/5] Add some tracepoints for clarification of the cause of troubles
(2013/03/22 20:13), Paolo Bonzini wrote: Il 22/03/2013 09:25, Kazuya Saito ha scritto: This series adds tracepoints for helping us clarify the cause of troubles. Virtualization on Linux is composed of some components such as qemu, kvm, libvirt, and so on. So it is very important to clarify firstly and swiftly the cause of troubles is on what component of them. Although qemu has useful information of this because it stands among kvm, libvirt and guest, it doesn't output the information by trace or log system. These patches add tracepoints which lead to reduce the time of the clarification. We'd like to add the tracepoints as the first set because, based on our experience, we've found out they must be useful for an investigation in the future. Without those tracepoints, we had a really hard time investigating a problem since the problem's reproducibility was quite low and there was no clue in the dump of qemu. Kazuya Saito (5): vl: add runstate_set tracepoint kvm-all: add kvm_ioctl, kvm_vm_ioctl, kvm_vcpu_ioctl tracepoints kvm-all: add kvm_run_exit tracepoint qdev: add qdev_{create,free} tracepoints qdev-monitor: add device_add tracepoint I'm not sure 4-5 are that useful, but the first 3 patches are definitely good stuff. Thanks. I'll modify the patch you pointed out about CPU number and re-post it. I'd like to add tracepoints to the virtual device creation/deletion part. I had an issue that when a Windows guest OS booted up, it didn't have a virtual NIC device which it should have had. It took us time to figure out which the guest OS or the QEMU had the issue. If I have had the tracepoints in the virtual device creation/deletion should have eased the situation much better. Kazuya
Re: [Qemu-devel] [PATCH v3] New QMP command query-cpu-max and HMP command cpu_max
Il 25/03/2013 17:31, Michal Novotny ha scritto: These commands return the maximum number of CPUs supported by the currently running emulator instance, as defined in its QEMUMachine struct. For HMP, I think the output could be added to info cpus. Paolo Signed-off-by: Michal Novotny minov...@redhat.com --- hmp-commands.hx | 14 ++ hmp.c| 8 hmp.h| 1 + qapi-schema.json | 11 +++ qmp-commands.hx | 22 ++ vl.c | 5 + 6 files changed, 61 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index df44906..c976459 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -690,6 +690,20 @@ Set the default CPU. ETEXI { +.name = cpu_max, +.args_type = , +.params = , +.help = Get maximum number of VCPUs supported by machine, +.mhandler.cmd = hmp_query_cpu_max, +}, + +STEXI +@item cpu_max +@findex cpu_max +Returns the number of CPUs supported by the machine being emulated. +ETEXI + +{ .name = mouse_move, .args_type = dx_str:s,dy_str:s,dz_str:s?, .params = dx dy [dz], diff --git a/hmp.c b/hmp.c index b0a861c..205db8f 100644 --- a/hmp.c +++ b/hmp.c @@ -748,6 +748,14 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict) g_free(data); } +void hmp_query_cpu_max(Monitor *mon, const QDict *qdict) +{ +int cpu_max; + +cpu_max = qmp_query_cpu_max(NULL); +monitor_printf(mon, Maximum number of CPUs is %d\n, cpu_max); +} + static void hmp_cont_cb(void *opaque, int err) { if (!err) { diff --git a/hmp.h b/hmp.h index 95fe76e..80e8b41 100644 --- a/hmp.h +++ b/hmp.h @@ -42,6 +42,7 @@ void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); void hmp_system_powerdown(Monitor *mon, const QDict *qdict); void hmp_cpu(Monitor *mon, const QDict *qdict); +void hmp_query_cpu_max(Monitor *mon, const QDict *qdict); void hmp_memsave(Monitor *mon, const QDict *qdict); void hmp_pmemsave(Monitor *mon, const QDict *qdict); void hmp_ringbuf_write(Monitor *mon, const QDict *qdict); diff --git a/qapi-schema.json b/qapi-schema.json index 088f4e1..a8187fd 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1832,6 +1832,17 @@ { 'command': 'query-migrate-cache-size', 'returns': 'int' } ## +## @query-cpu-max +## +## query maximum number of CPUs supported by machine +## +## Returns: number of CPUs +## +## Since: 1.5 +### +{ 'command': 'query-cpu-max', 'returns': 'int' } + +## # @ObjectPropertyInfo: # # @name: the name of the property diff --git a/qmp-commands.hx b/qmp-commands.hx index b370060..9c6b802 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -385,6 +385,28 @@ Note: CPUs' indexes are obtained with the 'query-cpus' command. EQMP { +.name = query-cpu-max, +.args_type = , +.mhandler.cmd_new = qmp_marshal_input_query_cpu_max, +}, + +SQMP +query-cpu-max +- + +Get the maximum CPUs supported by the machine being currently +emulated. + +Returns json-int. + +Example: + +- { execute: query-cpu-max } +- { return: 255 } + +EQMP + +{ .name = memsave, .args_type = val:l,size:i,filename:s,cpu:i?, .mhandler.cmd_new = qmp_marshal_input_memsave, diff --git a/vl.c b/vl.c index aeed7f4..7643f16 100644 --- a/vl.c +++ b/vl.c @@ -662,6 +662,11 @@ StatusInfo *qmp_query_status(Error **errp) return info; } +int64_t qmp_query_cpu_max(Error **errp) +{ +return current_machine-max_cpus; +} + /***/ /* real time host monotonic timer */
Re: [Qemu-devel] [PATCH 0/5] Add some tracepoints for clarification of the cause of troubles
Il 26/03/2013 08:13, Kazuya Saito ha scritto: I'm not sure 4-5 are that useful, but the first 3 patches are definitely good stuff. Thanks. I'll modify the patch you pointed out about CPU number and re-post it. I'd like to add tracepoints to the virtual device creation/deletion part. I had an issue that when a Windows guest OS booted up, it didn't have a virtual NIC device which it should have had. It took us time to figure out which the guest OS or the QEMU had the issue. If I have had the tracepoints in the virtual device creation/deletion should have eased the situation much better. Wouldn't you get the same information from the command line? Paolo
Re: [Qemu-devel] [PATCH v3] New QMP command query-cpu-max and HMP command cpu_max
Il 26/03/2013 08:14, Paolo Bonzini ha scritto: These commands return the maximum number of CPUs supported by the currently running emulator instance, as defined in its QEMUMachine struct. For HMP, I think the output could be added to info cpus. Just saw Luiz's solution, that's also good of course. Paolo
Re: [Qemu-devel] [PATCH v15 2/2] patch dsdt to use passed-in pvpanic ioport
On Tue, Mar 26, 2013 at 08:03:09AM +0100, Paolo Bonzini wrote: Il 26/03/2013 02:59, Hu Tao ha scritto: Why doesn't it work with q35? ACPI_EXTRACT_NAME_WORD_CONST dsdt_isa_pest generates two dsdt_isa_pest, one in out/acpi-dsdt.hex the other in out/q35-acpi-dsdt.hex. We should use the one in q35-acpi-dsdt.hex to patch DSDT for q35. But including q35-acpi-dsdt.hex, along with acpi-dsdt.hex, will result in redefinition of dsdt_isa_pest. I didn't see a simple way to solve this. Compile it in a separate file and include it in the SSDT (build_ssdt in src/acpi.c). Doesn't work. iasl gives an error: Data Table Compiler is not available yet Even though it compiles, I think the generated offset (*dsdt_isa_pest) won't be correct because it depends on acpi-dsdt.dsl/q35-acpi-dsdt.dsl. -- Regards, Hu Tao
Re: [Qemu-devel] Target-agnostic virtio?
On Tue, Mar 26, 2013 at 1:52 AM, Rob Landley r...@landley.net wrote: Can the virtio things (serial, network, block, virtfs) be used on arbitrary targets yet? I.E. Can I use a virtio network device on arm, mips, powerpc, sparc... Yes. Moreover, for sparc64 the virtio network is currently the only way to have a network under Linux guest (and a virtio block is the only to have a disk under Linux guest). -- Regards, Artyom Tarasenko Linux/sparc and solaris/sparc under qemu blog: http://tyom.blogspot.com/search/label/qemu
Re: [Qemu-devel] [PATCH v15 2/2] patch dsdt to use passed-in pvpanic ioport
Il 26/03/2013 08:24, Hu Tao ha scritto: ACPI_EXTRACT_NAME_WORD_CONST dsdt_isa_pest generates two dsdt_isa_pest, one in out/acpi-dsdt.hex the other in out/q35-acpi-dsdt.hex. We should use the one in q35-acpi-dsdt.hex to patch DSDT for q35. But including q35-acpi-dsdt.hex, along with acpi-dsdt.hex, will result in redefinition of dsdt_isa_pest. I didn't see a simple way to solve this. Compile it in a separate file and include it in the SSDT (build_ssdt in src/acpi.c). Doesn't work. iasl gives an error: Data Table Compiler is not available yet Even though it compiles, I think the generated offset (*dsdt_isa_pest) won't be correct because it depends on acpi-dsdt.dsl/q35-acpi-dsdt.dsl. See how it is done for ssdt-misc.aml (in fact, you can simply extend ssdt-misc.aml). Paolo
Re: [Qemu-devel] Want to be part of Memory Hotplug
在 2013-02-07四的 18:54 +0100,Vasilis Liaskovitis写道: Hi Senthil, On Mon, Feb 04, 2013 at 04:17:30PM +0530, kumaran wrote: Hi, I am Senthil, doing post graduation in IIT Bombay,India. I am looking for some problems related to KVM as part of my research work. I read about memory hotplug and other open issues in KVM. Can i be part of your work regarding memory hotplug. My Experience in KVM: - I have implemented Record and Replay feature in KVM - I have good hands on experience with KVM and QEMU's code base - Thorough knowledge about QEMU's architecture and PCI emulation - I have implemented Record and replay for Intel Ee100Pro network interface and for IDE disks (including DMA) If I get chance, I can spend around 5 dedicated months on this work. Please let me know your interest. thanks for your interest in the memory hotplug effort. You are welcome to contribute. Memory hotplug is still not in mainline qemu. It is a qemu-wide project rather than a kvm-specific one. Some possible directions are: - reviewing / improvement suggestions on v4 here: http://lists.nongnu.org/archive/html/qemu-devel/2012-12/msg02693.html - define the qom interface for Dimms. The current patches use a memory bus abstraction (DimmBus) where Dimms can plugin. That's definitely one choice. Some people have suggested using links from the i440fx/mch (in general the memory controller device of the emulated system) to the Dimm devices. That's similar to how CPUs are re-modelled in qom-cpu patchsets I think. The final dimm interface has not been agreed upon yet. - Add acpi native memory hotplug support for q35/ich9. The current code creates paravirtual Dimmbus + Dimms, without emulating real hotplug-capable memory controller hardware. - Make sure ejection is safe i.e. all users of a hotplugged MemoryRegion (not only guest/CPUs but also qemu block layer) have stopped using the memory, before actually freeing it. when can be considered 'have stopped using the memory' for 'MemoryRegion'? what I can see is only the devices used this 'MemoryRegion' decided to destroy memory region. make sure to include the qemu list (cc'ed) in order to let everyone know what you are working on and to get feedback. thanks, - Vasilis
Re: [Qemu-devel] [PATCHv4 0/9] buffer_is_zero / migration optimizations
Am 25.03.2013 um 15:34 schrieb Paolo Bonzini pbonz...@redhat.com: Hmm, right. What about just processing the first few longs twice, i.e. the above followed by for (i = 0; i len / sizeof(sizeof(VECTYPE); i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR)? I tested this version as v3: size_t buffer_find_nonzero_offset_v3(const void *buf, size_t len) { VECTYPE *p = (VECTYPE *)buf; unsigned long *tmp = (unsigned long *)buf; VECTYPE zero = ZERO_SPLAT; size_t i; assert(can_use_buffer_find_nonzero_offset(buf, len)); if (!len) { return 0; } if (tmp[0]) { return 0; } if (tmp[1]) { return 1 * sizeof(unsigned long); } if (tmp[2]) { return 2 * sizeof(unsigned long); } if (tmp[3]) { return 3 * sizeof(unsigned long); } for (i = 0; i len / sizeof(VECTYPE); i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) { VECTYPE tmp0 = p[i + 0] | p[i + 1]; VECTYPE tmp1 = p[i + 2] | p[i + 3]; VECTYPE tmp2 = p[i + 4] | p[i + 5]; VECTYPE tmp3 = p[i + 6] | p[i + 7]; VECTYPE tmp01 = tmp0 | tmp1; VECTYPE tmp23 = tmp2 | tmp3; if (!ALL_EQ(tmp01 | tmp23, zero)) { break; } } return i * sizeof(VECTYPE); } For reference this is v2: size_t buffer_find_nonzero_offset_v2(const void *buf, size_t len) { VECTYPE *p = (VECTYPE *)buf; VECTYPE zero = ZERO_SPLAT; size_t i; assert(can_use_buffer_find_nonzero_offset(buf, len)); if (!len) { return 0; } for (i = 0; i BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) { if (!ALL_EQ(p[i], zero)) { return i * sizeof(VECTYPE); } } for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i len / sizeof(VECTYPE); i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) { VECTYPE tmp0 = p[i + 0] | p[i + 1]; VECTYPE tmp1 = p[i + 2] | p[i + 3]; VECTYPE tmp2 = p[i + 4] | p[i + 5]; VECTYPE tmp3 = p[i + 6] | p[i + 7]; VECTYPE tmp01 = tmp0 | tmp1; VECTYPE tmp23 = tmp2 | tmp3; if (!ALL_EQ(tmp01 | tmp23, zero)) { break; } } return i * sizeof(VECTYPE); } I ran 3*2 tests. Each with 1GB memory and 256 iterations of checking each 4k page for zero. 1) all pages zero a) SSE2 is_zero_page: res=67108864 (ticks 3289 user 1 system) is_zero_page_v2: res=67108864 (ticks 3326 user 0 system) is_zero_page_v3: res=67108864 (ticks 3305 user 3 system) is_dup_page: res=67108864 (ticks 3648 user 1 system) b) unsigned long arithmetic is_zero_page: res=67108864 (ticks 3474 user 3 system) is_zero_page_2: res=67108864 (ticks 3516 user 1 system) is_zero_page_3: res=67108864 (ticks 3525 user 3 system) is_dup_page: res=67108864 (ticks 3826 user 4 system) 2) all pages non-zero, but first 64-bit of each page zero a) SSE2 is_zero_page: res=0 (ticks 251 user 0 system) is_zero_page_v2: res=0 (ticks 87 user 0 system) is_zero_page_v3: res=0 (ticks 91 user 0 system) is_dup_page: res=0 (ticks 82 user 0 system) b) unsigned long arithmetic is_zero_page: res=0 (ticks 209 user 0 system) is_zero_page_v2: res=0 (ticks 89 user 0 system) is_zero_page_v3: res=0 (ticks 88 user 0 system) is_dup_page: res=0 (ticks 88 user 0 system) 3) all pages non-zero, but first 256-bit of each page zero a) is_zero_pages: res=0 (ticks 260 user 0 system) is_zero_pages_2: res=0 (ticks 199 user 0 system) is_zero_pages_3: res=0 (ticks 342 user 0 system) is_dup_pages: res=0 (ticks 223 user 0 system) b) unsigned long arithmetic is_zero_pages: res=0 (ticks 230 user 0 system) is_zero_pages_2: res=0 (ticks 194 user 0 system) is_zero_pages_3: res=0 (ticks 280 user 0 system) is_dup_pages: res=0 (ticks 191 user 0 system) --- is_zero_page is the version from patch set v4. is_zero_page_2 is checking the first 8 * sizeof(VECTYPE) chunks one by one and than continuing 8 chunks at once without double-checks is_zero_page_3 is the above version. is_dup_page the old implementation. All compiled with gcc -O3 If noone objects I would use is_zero_page_2 and continue with v5 of the patch set. As I am ooo for the next 8 days from tomorrow. i prefer v3 as it has better performance if the non-zeroness is within the 8*sizeof(VECTYPE) bytes and not in the first 256-bit. Paolo, with the version that has lower setup costs in mind shall I use the vectorized or the unrolled version of patch 4 (find_next_bit optimization)? Peter
Re: [Qemu-devel] [PATCH 16/18] console: stop using DisplayState in gfx hardware emulation
On 2013-03-25 21:30, Gerd Hoffmann wrote: On 03/25/13 14:56, Igor Mitsyanko wrote: On 03/25/2013 02:37 PM, Gerd Hoffmann wrote: Hi, [5425.580115] displaysurface_create_from surface=0x7ff315d3df40, 800x600, bpp 16, bswap 0 [5425.580257] displaysurface_free surface=0x7ff3158c33b0 This is vga=0x314 Looks like we have some funky interaction between vga and vmware. I'll go dig. Meanwhile you can try vga=0x315 (800x600x24) or vga=normal (textmode), that has a high chance to workaround this. cheers, Gerd Couldn't it be because wred, wgreen and wblue were removed? It seems like it was a workaround for some pre-existing problem, is it ok that you removed them but left depth and bypp intact? No, it is not, and yes, this is where the inconsistency comes from. We read wred+wgreen+wblue directly from the surface whereas depth is cached in the vmware vga state struct. Patch attached. Not fully tested yet. Unfortunately, this doesn't change the picture (except for the expected vmsvga_value_read: Bad register 1c). The 0x315 workaround does indeed work. Jan signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [RFC PATCH 04/10] qemu-ga: Add Windows VSS provider to quiesce applications on fsfreeze
On Tue, 2013-03-26 at 08:09 +0100, Paolo Bonzini wrote: Il 25/03/2013 21:50, Tomoki Sekiyama ha scritto: Hi, Paolo Bonzini pbonz...@redhat.com wrote: Il 14/02/2013 07:10, Tomoki Sekiyama ha scritto: diff --git a/qga/vss-win32-provider/qga-provider.idl b/qga/vss-win32-provider/qga-provider.idl new file mode 100644 index 000..17abca0 --- /dev/null +++ b/qga/vss-win32-provider/qga-provider.idl @@ -0,0 +1,20 @@ +import oaidl.idl; +import ocidl.idl; + +[ +uuid(103B8142-6CE5-48A7-BDE1-794D3192FCF1), +version(1.0), +helpstring(QGAVSSProvider Type Library) +] +library QGAVSSHWProviderLib +{ +importlib(stdole2.tlb); +[ +uuid(6E6A3492-8D4D-440C-9619-5E5D0CC31CA8), +helpstring(QGAVSSProvider Class) +] +coclass QGAVSSHWProvider +{ +[default] interface IUnknown; +}; +}; Ok, I checked widl and it chokes on the importlib line. If that can be removed, it's fine to use widl. The invocation is widl -m32/-m64 -o qga-provider.tlb -t qga-provider.idl where code to choose between -m32 and -m64 is already in the configure script (search for `case $cpu`). Paolo Unfortunately, if I remove importlib(stdole2.tlb), generated .tlb seems rejected to register into Windows COM+ Catalog. Wine has stdole2.tlb in its fakedlls directory, but widl does not accept this by error: Wrong or unsupported typelib magic 405a4d Even if I copied native stdole2.tlb, widl fails with the same error. Do you have any idea about this error? Seems like your tlb has nonstandard identifying characters. Check first several bytes of the tlb file. Usually it should be something like '4D 53 46 54', or '4D 5A 90' No, I suggest you ask on the Wine mailing lists. In the meanwhile we can include a precompiled .tlb file in the QEMU repository and use midl. Paolo
[Qemu-devel] [PATCH] hw/i386/pc: format load_linux function
Signed-off-by: liguang lig.f...@cn.fujitsu.com --- hw/i386/pc.c | 109 ++ 1 files changed, 56 insertions(+), 53 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ed7d9ba..b1e06fa 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -646,8 +646,8 @@ static long get_file_size(FILE *f) static void load_linux(void *fw_cfg, const char *kernel_filename, - const char *initrd_filename, - const char *kernel_cmdline, + const char *initrd_filename, + const char *kernel_cmdline, hwaddr max_ram_size) { uint16_t protocol; @@ -664,60 +664,62 @@ static void load_linux(void *fw_cfg, /* load the kernel header */ f = fopen(kernel_filename, rb); if (!f || !(kernel_size = get_file_size(f)) || - fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) != - MIN(ARRAY_SIZE(header), kernel_size)) { - fprintf(stderr, qemu: could not load kernel '%s': %s\n, - kernel_filename, strerror(errno)); - exit(1); +fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) != +MIN(ARRAY_SIZE(header), kernel_size)) { +fprintf(stderr, qemu: could not load kernel '%s': %s\n, +kernel_filename, strerror(errno)); +exit(1); } /* kernel protocol version */ #if 0 fprintf(stderr, header magic: %#x\n, ldl_p(header+0x202)); #endif -if (ldl_p(header+0x202) == 0x53726448) - protocol = lduw_p(header+0x206); -else { - /* This looks like a multiboot kernel. If it is, let's stop - treating it like a Linux kernel. */ +if (ldl_p(header+0x202) == 0x53726448) { +protocol = lduw_p(header+0x206); +} else { +/* This looks like a multiboot kernel. If it is, let's stop + treating it like a Linux kernel. */ if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename, - kernel_cmdline, kernel_size, header)) + kernel_cmdline, kernel_size, header)) { return; - protocol = 0; +} +protocol = 0; } if (protocol 0x200 || !(header[0x211] 0x01)) { - /* Low kernel */ - real_addr= 0x9; - cmdline_addr = 0x9a000 - cmdline_size; - prot_addr= 0x1; +/* Low kernel */ +real_addr= 0x9; +cmdline_addr = 0x9a000 - cmdline_size; +prot_addr= 0x1; } else if (protocol 0x202) { - /* High but ancient kernel */ - real_addr= 0x9; - cmdline_addr = 0x9a000 - cmdline_size; - prot_addr= 0x10; +/* High but ancient kernel */ +real_addr= 0x9; +cmdline_addr = 0x9a000 - cmdline_size; +prot_addr= 0x10; } else { - /* High and recent kernel */ - real_addr= 0x1; - cmdline_addr = 0x2; - prot_addr= 0x10; +/* High and recent kernel */ +real_addr= 0x1; +cmdline_addr = 0x2; +prot_addr= 0x10; } #if 0 fprintf(stderr, - qemu: real_addr = 0x TARGET_FMT_plx \n - qemu: cmdline_addr = 0x TARGET_FMT_plx \n - qemu: prot_addr = 0x TARGET_FMT_plx \n, - real_addr, - cmdline_addr, - prot_addr); +qemu: real_addr = 0x TARGET_FMT_plx \n +qemu: cmdline_addr = 0x TARGET_FMT_plx \n +qemu: prot_addr = 0x TARGET_FMT_plx \n, +real_addr, +cmdline_addr, +prot_addr); #endif /* highest address for loading the initrd */ -if (protocol = 0x203) - initrd_max = ldl_p(header+0x22c); -else - initrd_max = 0x37ff; +if (protocol = 0x203) { +initrd_max = ldl_p(header+0x22c); +} else { +initrd_max = 0x37ff; +} if (initrd_max = max_ram_size-ACPI_DATA_SIZE) initrd_max = max_ram_size-ACPI_DATA_SIZE-1; @@ -727,10 +729,10 @@ static void load_linux(void *fw_cfg, fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); if (protocol = 0x202) { - stl_p(header+0x228, cmdline_addr); +stl_p(header+0x228, cmdline_addr); } else { - stw_p(header+0x20, 0xA33F); - stw_p(header+0x22, cmdline_addr-real_addr); +stw_p(header+0x20, 0xA33F); +stw_p(header+0x22, cmdline_addr-real_addr); } /* handle vga= parameter */ @@ -755,23 +757,23 @@ static void load_linux(void *fw_cfg, /* High nybble = B reserved for QEMU; low nybble is revision number. If this code is substantially changed, you may want to consider incrementing the revision. */ -if (protocol = 0x200) - header[0x210] = 0xB0; - +if (protocol = 0x200) { +header[0x210] = 0xB0; +} /* heap */
Re: [Qemu-devel] [PATCH] hw/i386/pc: fix possible segment fault for port92_write
在 2013-03-22五的 12:20 +0100,Andreas Färber写道: Am 22.03.2013 10:12, schrieb liguang: e.g. $qemu-system-x86_64 -device port92 will report segment fault, for port92_write try a un-allocated assignment for a20_out. so check before this assignment. Signed-off-by: liguang lig.f...@cn.fujitsu.com --- hw/i386/pc.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ed7d9ba..a0e8ee0 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -440,7 +440,8 @@ static void port92_write(void *opaque, hwaddr addr, uint64_t val, DPRINTF(port92: write 0x%02x\n, val); s-outport = val; -qemu_set_irq(*s-a20_out, (val 1) 1); +if (s-a20_out) +qemu_set_irq(*s-a20_out, (val 1) 1); Missing braces. Yes, Thanks! But I think it would be better to proceed with my QOM'ification [1] and return an Error on realize here since these IRQs don't change while realized and qdev init doesn't allow to return a textual error. Andreas [1] https://github.com/afaerber/qemu-cpu/commits/realize-isa if (val 1) { qemu_system_reset_request(); }
Re: [Qemu-devel] [PATCH] glib: add a compatibility interface for g_timeout_add_seconds
On Mon, Mar 25, 2013 at 08:21:13PM -, Anthony Liguori wrote: Applied. Thanks. Thanks for applying. RHEL5 and other old buildslaves should turn green again now :). Stefan
Re: [Qemu-devel] [PATCH] hw/i386/pc: fix possible segment fault for port92_write
在 2013-03-22五的 12:07 +0100,Paolo Bonzini写道: Il 22/03/2013 10:12, liguang ha scritto: e.g. $qemu-system-x86_64 -device port92 will report segment fault, for port92_write try a un-allocated assignment for a20_out. so check before this assignment. Signed-off-by: liguang lig.f...@cn.fujitsu.com --- hw/i386/pc.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ed7d9ba..a0e8ee0 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -440,7 +440,8 @@ static void port92_write(void *opaque, hwaddr addr, uint64_t val, DPRINTF(port92: write 0x%02x\n, val); s-outport = val; -qemu_set_irq(*s-a20_out, (val 1) 1); +if (s-a20_out) +qemu_set_irq(*s-a20_out, (val 1) 1); if (val 1) { qemu_system_reset_request(); } Unfortunately, this is a very common problem. The correct fix is to change port92 to use the GPIO mechanism instead. Sorry, Paolo, I'm not so familiar with 'GPIO mechanism', can you specify more? Thanks!
[Qemu-devel] [PATCH v15.1] Add pvpanic device driver
pvpanic device is used to notify host(qemu) when guest panic happens. Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- Paolo, Can I add your Signed-off-by? Since the original code is given by you. Thank you, Paolo :) src/acpi.c| 3 +++ src/ssdt-misc.dsl | 46 ++ 2 files changed, 49 insertions(+) diff --git a/src/acpi.c b/src/acpi.c index bc4d8ea..fe504f0 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -534,6 +534,9 @@ build_ssdt(void) ssdt_ptr[acpi_pci64_valid[0]] = 0; } +int pvpanic_port = romfile_loadint(etc/pvpanic-port, 0x0); +*(u16 *)(ssdt_ptr + *ssdt_isa_pest) = pvpanic_port; + ssdt_ptr += sizeof(ssdp_misc_aml); // build Scope(_SB_) header diff --git a/src/ssdt-misc.dsl b/src/ssdt-misc.dsl index 679422b..acc850e 100644 --- a/src/ssdt-misc.dsl +++ b/src/ssdt-misc.dsl @@ -55,4 +55,50 @@ DefinitionBlock (ssdt-misc.aml, SSDT, 0x01, BXPC, BXSSDTSUSP, 0x1) Zero /* reserved */ }) } + +External(\_SB.PCI0, DeviceObj) +External(\_SB.PCI0.ISA, DeviceObj) + +Scope(\_SB.PCI0.ISA) { +Device(PEVT) { +Name(_HID, QEMU0001) +/* PEST will be patched to be Zero if no such device */ +ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest +Name(PEST, 0x) +OperationRegion(PEOR, SystemIO, PEST, 0x01) +Field(PEOR, ByteAcc, NoLock, Preserve) { +PEPT, 8, +} + +Method(_STA, 0, NotSerialized) { +Store(PEST, Local0) +If (LEqual(Local0, Zero)) { +Return (0x00) +} Else { +Return (0x0F) +} +} + +Method(RDPT, 0, NotSerialized) { +Store(PEPT, Local0) +Return (Local0) +} + +Method(WRPT, 1, NotSerialized) { +Store(Arg0, PEPT) +} + +Name(_CRS, ResourceTemplate() { +IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO) +}) + +CreateWordField(_CRS, IO._MIN, IOMN) +CreateWordField(_CRS, IO._MAX, IOMX) + +Method(_INI, 0, NotSerialized) { +Store(PEST, IOMN) +Store(PEST, IOMX) +} +} +} } -- 1.8.1.4
Re: [Qemu-devel] [PATCH v15.1] Add pvpanic device driver
Il 26/03/2013 09:52, Hu Tao ha scritto: pvpanic device is used to notify host(qemu) when guest panic happens. Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- Paolo, Can I add your Signed-off-by? Since the original code is given by you. Sure, as you prefer. Paolo src/acpi.c| 3 +++ src/ssdt-misc.dsl | 46 ++ 2 files changed, 49 insertions(+) diff --git a/src/acpi.c b/src/acpi.c index bc4d8ea..fe504f0 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -534,6 +534,9 @@ build_ssdt(void) ssdt_ptr[acpi_pci64_valid[0]] = 0; } +int pvpanic_port = romfile_loadint(etc/pvpanic-port, 0x0); +*(u16 *)(ssdt_ptr + *ssdt_isa_pest) = pvpanic_port; + ssdt_ptr += sizeof(ssdp_misc_aml); // build Scope(_SB_) header diff --git a/src/ssdt-misc.dsl b/src/ssdt-misc.dsl index 679422b..acc850e 100644 --- a/src/ssdt-misc.dsl +++ b/src/ssdt-misc.dsl @@ -55,4 +55,50 @@ DefinitionBlock (ssdt-misc.aml, SSDT, 0x01, BXPC, BXSSDTSUSP, 0x1) Zero /* reserved */ }) } + +External(\_SB.PCI0, DeviceObj) +External(\_SB.PCI0.ISA, DeviceObj) + +Scope(\_SB.PCI0.ISA) { +Device(PEVT) { +Name(_HID, QEMU0001) +/* PEST will be patched to be Zero if no such device */ +ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest +Name(PEST, 0x) +OperationRegion(PEOR, SystemIO, PEST, 0x01) +Field(PEOR, ByteAcc, NoLock, Preserve) { +PEPT, 8, +} + +Method(_STA, 0, NotSerialized) { +Store(PEST, Local0) +If (LEqual(Local0, Zero)) { +Return (0x00) +} Else { +Return (0x0F) +} +} + +Method(RDPT, 0, NotSerialized) { +Store(PEPT, Local0) +Return (Local0) +} + +Method(WRPT, 1, NotSerialized) { +Store(Arg0, PEPT) +} + +Name(_CRS, ResourceTemplate() { +IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO) +}) + +CreateWordField(_CRS, IO._MIN, IOMN) +CreateWordField(_CRS, IO._MAX, IOMX) + +Method(_INI, 0, NotSerialized) { +Store(PEST, IOMN) +Store(PEST, IOMX) +} +} +} }
[Qemu-devel] [PATCH v15.1 resend] Add pvpanic device driver
pvpanic device is used to notify host(qemu) when guest panic happens. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- src/acpi.c| 3 +++ src/ssdt-misc.dsl | 46 ++ 2 files changed, 49 insertions(+) diff --git a/src/acpi.c b/src/acpi.c index bc4d8ea..fe504f0 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -534,6 +534,9 @@ build_ssdt(void) ssdt_ptr[acpi_pci64_valid[0]] = 0; } +int pvpanic_port = romfile_loadint(etc/pvpanic-port, 0x0); +*(u16 *)(ssdt_ptr + *ssdt_isa_pest) = pvpanic_port; + ssdt_ptr += sizeof(ssdp_misc_aml); // build Scope(_SB_) header diff --git a/src/ssdt-misc.dsl b/src/ssdt-misc.dsl index 679422b..acc850e 100644 --- a/src/ssdt-misc.dsl +++ b/src/ssdt-misc.dsl @@ -55,4 +55,50 @@ DefinitionBlock (ssdt-misc.aml, SSDT, 0x01, BXPC, BXSSDTSUSP, 0x1) Zero /* reserved */ }) } + +External(\_SB.PCI0, DeviceObj) +External(\_SB.PCI0.ISA, DeviceObj) + +Scope(\_SB.PCI0.ISA) { +Device(PEVT) { +Name(_HID, QEMU0001) +/* PEST will be patched to be Zero if no such device */ +ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest +Name(PEST, 0x) +OperationRegion(PEOR, SystemIO, PEST, 0x01) +Field(PEOR, ByteAcc, NoLock, Preserve) { +PEPT, 8, +} + +Method(_STA, 0, NotSerialized) { +Store(PEST, Local0) +If (LEqual(Local0, Zero)) { +Return (0x00) +} Else { +Return (0x0F) +} +} + +Method(RDPT, 0, NotSerialized) { +Store(PEPT, Local0) +Return (Local0) +} + +Method(WRPT, 1, NotSerialized) { +Store(Arg0, PEPT) +} + +Name(_CRS, ResourceTemplate() { +IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO) +}) + +CreateWordField(_CRS, IO._MIN, IOMN) +CreateWordField(_CRS, IO._MAX, IOMX) + +Method(_INI, 0, NotSerialized) { +Store(PEST, IOMN) +Store(PEST, IOMX) +} +} +} } -- 1.8.1.4
Re: [Qemu-devel] [PATCH] VMXNET3: initialize rx_ridx to eliminate compile warning
On Tue, Mar 26, 2013 at 10:24:06AM +0800, Wenchao Xia wrote: Gcc report hw/vmxnet3.c:972: error: ‘rx_ridx’ may be used uninitialized in this function, so fix it. Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- hw/vmxnet3.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/vmxnet3.c b/hw/vmxnet3.c index 925be80..bdd256e 100644 --- a/hw/vmxnet3.c +++ b/hw/vmxnet3.c @@ -969,7 +969,7 @@ vmxnet3_indicate_packet(VMXNET3State *s) struct Vmxnet3_RxDesc rxd; bool is_head = true; uint32_t rxd_idx; -uint32_t rx_ridx; +uint32_t rx_ridx = 0; Reviewed-by: Stefan Hajnoczi stefa...@redhat.com This seems to be a gcc weakness in some versions. No warnings here with gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8). I manually checked the code and there is no path which can use uninitialized rx_ridx: static bool vmxnet3_indicate_packet(VMXNET3State *s) { struct Vmxnet3_RxDesc rxd; bool is_head = true; uint32_t rxd_idx; uint32_t rx_ridx; [...] while (bytes_left 0) { [...] if (!vmxnet3_get_next_rx_descr(s, is_head, rxd, rxd_idx, rx_ridx)) { break; } rx_ridx is assigned by vmxnet3_get_next_rx_descr() unless it returns false. From now on rx_ridx is initialized. [...] rxcd.rqID = RXQ_IDX + rx_ridx * s-rxq_num; Used here, fine since we initialized it above. [...] VMW_RIPRN(RX Completion descriptor: rxRing: %lu rxIdx %lu len %lu sop %d csum_correct %lu, (unsigned long) rx_ridx, Used here, fine since we initialized it above. [...] } Not used outside the while loop.
Re: [Qemu-devel] [PATCH] VMXNET3: initialize rx_ridx to eliminate compile warning
On Tue, Mar 26, 2013 at 10:24:06AM +0800, Wenchao Xia wrote: Gcc report hw/vmxnet3.c:972: error: ‘rx_ridx’ may be used uninitialized in this function, so fix it. Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- hw/vmxnet3.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Anthony: Please apply this fix directly. I think there's no need to go through the net tree. Stefan
Re: [Qemu-devel] [PATCHv4 0/9] buffer_is_zero / migration optimizations
Il 26/03/2013 09:14, Peter Lieven ha scritto: If noone objects I would use is_zero_page_2 and continue with v5 of the patch set. As I am ooo for the next 8 days from tomorrow. i prefer v3 as it has better performance if the non-zeroness is within the 8*sizeof(VECTYPE) bytes and not in the first 256-bit. Either v2 or v3 is fine. v3 has slightly simpler code and v2 optimizes for a rare case, but v2 is indeed a bit faster and your benchmarking effort should be rewarded. :) Paolo, with the version that has lower setup costs in mind shall I use the vectorized or the unrolled version of patch 4 (find_next_bit optimization)? I think for that we should, at least for now, use the version we discussed a few weeks ago (with no SIMD and just unrolling). Paolo
Re: [Qemu-devel] [PATCH v15.1 4/6] pvpanic: add document of pvpanic
Il 26/03/2013 04:03, Hu Tao ha scritto: Signed-off-by: Hu Tao hu...@cn.fujitsu.com --- docs/specs/pvpanic.txt | 35 +++ 1 file changed, 35 insertions(+) create mode 100644 docs/specs/pvpanic.txt diff --git a/docs/specs/pvpanic.txt b/docs/specs/pvpanic.txt new file mode 100644 index 000..1f14063 --- /dev/null +++ b/docs/specs/pvpanic.txt @@ -0,0 +1,35 @@ +PVPANIC DEVICE +== + +pvpanic device is a simulated ISA device, through which a guest panic +event is sent to qemu, and a QMP event is generated. This allows +management apps (e.g. libvirt) to be notified and respond to the event. + +The management app has the option of waiting for GUEST_PANICKED events, +and/or polling for guest-panicked RunState, to learn when the pvpanic +device has fired a panic event. + +ISA Interface +- + +pvpanic uses port 0x505 to receive a panic event from the guest. On +written, bit 0 is set to indicate guest panic has happened. On read, bit +0 is set to indicate guest panic notification is supported. + +ACPI Interface +-- + +pvpanic device is defined with ACPI ID QEMU0001. Custom methods: + +RDPT: To determine whether guest panic notification is supported. +Rrguments: None +Return: Returns a byte, bit 0 set to indicate guest panic +notification is supported. + +WRPT: To send a guest panic event +Arguments: Arg0 is a byte, with bit 0 set to indicate guest panic has +happened. +Return: None + +The ACPI device will automatically refer to the right port in case it +is modified. Looks good. Paolo
Re: [Qemu-devel] KVM call agenda for 2013-03-26
On Mon, Mar 25, 2013 at 08:13:34PM -0500, Rob Landley wrote: On 03/25/2013 08:17:44 AM, Juan Quintela wrote: Hi Please send in any agenda topics you are interested in. Later, Juan. If Google summer of code is still open: http://qemu-project.org/Google_Summer_of_Code_2013 Project ideas can still be added to the wiki. They must have a mentor who is able to commit around 5 hours per week this summer. I'm not sure about the status of the todo list items you mentioned, hopefully others can help. Stefan
Re: [Qemu-devel] [PATCH 2/2] vl.c: throw an error if iscsi is not supported
On Mon, Mar 25, 2013 at 02:34:01PM +, Peter Maydell wrote: On 25 March 2013 14:10, Peter Lieven p...@kamp.de wrote: Am 25.03.2013 um 15:00 schrieb Stefan Hajnoczi stefa...@gmail.com: On Thu, Mar 21, 2013 at 01:07:11PM +0100, Peter Lieven wrote: this patch adds a check for qemu_find_opts(iscsi) returning NULL instead of blindly passing the result to qemu_opts_parse(). Signed-off-by: Peter Lieven p...@kamp.de --- vl.c |9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) Why is this change necessary? a) just to make sure we check the result of qemu_find_opts for NULL in case a bug stops registering the opts again It's OK to crash for can't happen cases IMHO. b) to have an error output if libiscsi is not compiled in and someone passes an iscsi flag (analogue to the error if you supply -spice XXX) I don't have a strong opinion here but it would be good to be consistent. At the moment (as well as iscsi) SLIRP, TPM and mem_prealloc options all just vanish if qemu wasn't configured with them supported. [Various other things like SDL and Windows specific options do remain to produce an error.] So maybe we should move all these options to always exist but may produce an error. Agreed. Either this patch should be dropped because it's not strictly necessary. Or we should be consistent and clean up all of vl.c:main(). There's not much point of just changing -iscsi. Stefan
Re: [Qemu-devel] [PATCH] block: Add support for Secure Shell (ssh) block device.
On Mon, Mar 25, 2013 at 03:11:37PM +, Richard W.M. Jones wrote: On Mon, Mar 25, 2013 at 03:36:22PM +0100, Kevin Wolf wrote: You don't have a bdrv_co_flush_to_disk, what does this mean? Is every write immediately flushed to the disk, is the driver unsafe by design, or is this just a missing implementation detail? Initially there is no .bdrv_co_flush_to_disk because this patch is just a proof of concept. However it does seem likely that a true flush-to-disk operation is not possible with sftp. Assuming this is supposed to guarantee that the bits have been committed to disk, I don't see anything in the sftp protocol that supports that guarantee. It seems to be left up to the implementation to do whatever it wants. Here's the protocol v3 as implemented by OpenSSH: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02 and here's the latest version v6 (not implemented by anyone AFAIK): http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 if you think you can see anything that I've missed ... Also I grepped over the source of OpenSSH and there is no call to sync(2), fsync(2) or fdatasync(2). I looked at OpenSSH sftp-server.c to see if open, close, or write do anything special. They don't. There's also no 'sync' command in the SFTP protocol. So unless the underlying filesystem is mounted -o sync, there is no guarantee that data is safely on disk. Stefan
Re: [Qemu-devel] [Bug 1158912] Re: QEMU Version 1.4.0 - SLIRP hangs VM
On Mon, Mar 25, 2013 at 08:57:46PM -, Kenneth Salerno wrote: Result of git bisect: commit 837d1f978224f7e7b020c71ffb10b291952cc596 Merge: a6fc23e 2b35e93 Author: Blue Swirl blauwir...@gmail.com Date: Sat Jan 12 12:46:57 2013 + Merge branch 's390-reorg' of git://repo.or.cz/qemu/rth * 's390-reorg' of git://repo.or.cz/qemu/rth: (149 commits) target-s390: Claim maintainership target-s390: Use noreturn for exception and load_psw target-s390: Use TCG_CALL_NO_WG for misc helpers target-s390: Use TCG_CALL_NO_WG for integer helpers target-s390: Use TCG_CALL_NO_WG for floating-point helpers target-s390: Use TCG_CALL_NO_WG for memory helpers target-s390: Perform COMPARE AND SWAP inline target-s390: Optimize get_address target-s390: Optimize ADDC/SUBB target-s390: Optimize ADDU/SUBU CC testing target-s390: Tidy comparisons target-s390: Optmize emitting discards target-s390: Optimize XC target-s390: Fix cpu_clone_regs target-s390: Implement LOAD/SET FP AND SIGNAL target-s390: Implement SET ROUNDING MODE target-s390: Use uint64_to_float128 target-s390: Implement LCDFR target-s390: Check insn operand specifications target-s390: Implement CPSDR ... There are 1,484 files affected by this commit - Is there a way I can narrow this down even further within this commit? Looks like git-bisect(1) got stuck on a merge - maybe it followed the wrong parent commit. Please manually check whether a6fc23e hangs: $ cd qemu $ git checkout a6fc23e $ ...build and test hang... If a6fc23e is indeed broken then you can start a new git bisect between v1.3.0 (good) and a6fc23e (bad). If a6fc23e is not broken then that really suggestes the 's390-reorg' merge broke SLIRP, which is unlikely. Hope this helps. Regarding the QEMU backtrace, it shows SLIRP is waiting in a blocking accept() call: Thread 1 (Thread 416.0x228): #0 0x7c90e514 in ntdll!KiFastSystemCallRet () from /cygdrive/c/WINDOWS/system32/ntdll.dll #1 0x7c90df5a in ntdll!ZwWaitForSingleObject () from /cygdrive/c/WINDOWS/system32/ntdll.dll #2 0x71a5402b in ?? () from /cygdrive/c/WINDOWS/system32/mswsock.dll #3 0x71a6b858 in StartWsdpService () from /cygdrive/c/WINDOWS/system32/mswsock.dll #4 0x71ac0e46 in WSAAccept () from /cygdrive/c/WINDOWS/system32/WS2_32.dll #5 0x71ac1057 in accept () from /cygdrive/c/WINDOWS/system32/WS2_32.dll #6 0x0057caff in tcp_connect (inso=0x1c07c68) at slirp/tcp_subr.c:423 #7 0x005763d0 in slirp_select_poll (readfds=0xa19a40 rfds, writefds=0xa19b60 wfds, xfds=0xa19c80 xfds, select_error=0) at slirp/slirp.c:485 #8 0x0053688b in main_loop_wait (nonblocking=0) at main-loop.c:419 #9 0x005a8333 in main_loop () at vl.c:2001 #10 0x005af134 in qemu_main (argc=34, argv=0x1c08048, envp=0x0) at vl.c:4326 #11 0x005a4d84 in SDL_main (argc=34, argv=0x1c08048) at vl.c:102 #12 0x0073a951 in console_main () #13 0x0022 in ?? () #14 0x01c08048 in ?? () Since the main loop holds the global mutex the guest is unable to make progress and appears to hang. Stefan
Re: [Qemu-devel] coroutine: hung when using gthread backend
On Tue, Mar 26, 2013 at 08:03:50AM +0100, Paolo Bonzini wrote: Il 26/03/2013 03:50, Wenchao Xia ha scritto: When I using tcg with coroutine backend = gthread, x86_64-softmmu/qemu-system-x86_64 will hung. Any one working on it? coroutine backend gthread hardly works for qemu, only qemu-io and qemu-img. Do you know why it doesn't work? Stefan
Re: [Qemu-devel] coroutine: hung when using gthread backend
On 26 March 2013 09:54, Stefan Hajnoczi stefa...@gmail.com wrote: On Tue, Mar 26, 2013 at 08:03:50AM +0100, Paolo Bonzini wrote: coroutine backend gthread hardly works for qemu, only qemu-io and qemu-img. Do you know why it doesn't work? Because nobody tests it? -- PMM
[Qemu-devel] [PATCHv5 04/10] buffer_is_zero: use vector optimizations if possible
performance gain on SSE2 is approx. 20-25%. altivec is not tested. performance for unsigned long arithmetic is unchanged. Signed-off-by: Peter Lieven p...@kamp.de Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Orit Wasserman owass...@redhat.com --- util/cutils.c |5 + 1 file changed, 5 insertions(+) diff --git a/util/cutils.c b/util/cutils.c index 0314a18..daf032a 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -215,6 +215,11 @@ bool buffer_is_zero(const void *buf, size_t len) long d0, d1, d2, d3; const long * const data = buf; +/* use vector optimized zero check if possible */ +if (can_use_buffer_find_nonzero_offset(buf, len)) { +return buffer_find_nonzero_offset(buf, len) == len; +} + assert(len % (4 * sizeof(long)) == 0); len /= sizeof(long); -- 1.7.9.5
[Qemu-devel] [PATCHv5 05/10] bitops: unroll while loop in find_next_bit()
this patch adopts the loop unrolling idea of bitmap_is_zero() to speed up the skipping of large areas with zeros in find_next_bit(). this routine is extensively used to find dirty pages in live migration. testing only the find_next_bit performance on a zeroed bitfield the loop onrolling decreased executing time by approx. 50% on x86_64. Signed-off-by: Peter Lieven p...@kamp.de --- util/bitops.c | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/util/bitops.c b/util/bitops.c index e72237a..227c38b 100644 --- a/util/bitops.c +++ b/util/bitops.c @@ -42,7 +42,23 @@ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, size -= BITS_PER_LONG; result += BITS_PER_LONG; } -while (size ~(BITS_PER_LONG-1)) { +while (size = 4*BITS_PER_LONG) { +unsigned long d1, d2, d3; +tmp = *p; +d1 = *(p+1); +d2 = *(p+2); +d3 = *(p+3); +if (tmp) { +goto found_middle; +} +if (d1 | d2 | d3) { +break; +} +p += 4; +result += 4*BITS_PER_LONG; +size -= 4*BITS_PER_LONG; +} +while (size = BITS_PER_LONG) { if ((tmp = *(p++))) { goto found_middle; } -- 1.7.9.5
[Qemu-devel] [PATCHv5 08/10] migration: do not sent zero pages in bulk stage
during bulk stage of ram migration if a page is a zero page do not send it at all. the memory at the destination reads as zero anyway. even if there is an madvise with QEMU_MADV_DONTNEED at the target upon receipt of a zero page I have observed that the target starts swapping if the memory is overcommitted. it seems that the pages are dropped asynchronously. this patch also updates QMP to return the number of skipped pages in MigrationStats. Signed-off-by: Peter Lieven p...@kamp.de Reviewed-by: Eric Blake ebl...@redhat.com --- arch_init.c | 24 hmp.c |2 ++ include/migration/migration.h |2 ++ migration.c |3 ++- qapi-schema.json |8 +--- qmp-commands.hx |3 ++- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/arch_init.c b/arch_init.c index 1291bd2..3a0d02e 100644 --- a/arch_init.c +++ b/arch_init.c @@ -183,6 +183,7 @@ int64_t xbzrle_cache_resize(int64_t new_size) /* accounting for migration statistics */ typedef struct AccountingInfo { uint64_t dup_pages; +uint64_t skipped_pages; uint64_t norm_pages; uint64_t iterations; uint64_t xbzrle_bytes; @@ -208,6 +209,16 @@ uint64_t dup_mig_pages_transferred(void) return acct_info.dup_pages; } +uint64_t skipped_mig_bytes_transferred(void) +{ +return acct_info.skipped_pages * TARGET_PAGE_SIZE; +} + +uint64_t skipped_mig_pages_transferred(void) +{ +return acct_info.skipped_pages; +} + uint64_t norm_mig_bytes_transferred(void) { return acct_info.norm_pages * TARGET_PAGE_SIZE; @@ -440,10 +451,15 @@ static int ram_save_block(QEMUFile *f, bool last_stage) bytes_sent = -1; if (is_zero_page(p)) { acct_info.dup_pages++; -bytes_sent = save_block_hdr(f, block, offset, cont, -RAM_SAVE_FLAG_COMPRESS); -qemu_put_byte(f, 0); -bytes_sent++; +if (!ram_bulk_stage) { +bytes_sent = save_block_hdr(f, block, offset, cont, +RAM_SAVE_FLAG_COMPRESS); +qemu_put_byte(f, 0); +bytes_sent++; +} else { +acct_info.skipped_pages++; +bytes_sent = 0; +} } else if (migrate_use_xbzrle()) { current_addr = block-offset + offset; bytes_sent = save_xbzrle_page(f, p, current_addr, block, diff --git a/hmp.c b/hmp.c index b0a861c..e3e833e 100644 --- a/hmp.c +++ b/hmp.c @@ -173,6 +173,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) info-ram-total 10); monitor_printf(mon, duplicate: % PRIu64 pages\n, info-ram-duplicate); +monitor_printf(mon, skipped: % PRIu64 pages\n, + info-ram-skipped); monitor_printf(mon, normal: % PRIu64 pages\n, info-ram-normal); monitor_printf(mon, normal bytes: % PRIu64 kbytes\n, diff --git a/include/migration/migration.h b/include/migration/migration.h index bb617fd..e2acec6 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -96,6 +96,8 @@ extern SaveVMHandlers savevm_ram_handlers; uint64_t dup_mig_bytes_transferred(void); uint64_t dup_mig_pages_transferred(void); +uint64_t skipped_mig_bytes_transferred(void); +uint64_t skipped_mig_pages_transferred(void); uint64_t norm_mig_bytes_transferred(void); uint64_t norm_mig_pages_transferred(void); uint64_t xbzrle_mig_bytes_transferred(void); diff --git a/migration.c b/migration.c index 185d112..7fb2147 100644 --- a/migration.c +++ b/migration.c @@ -197,11 +197,11 @@ MigrationInfo *qmp_query_migrate(Error **errp) info-ram-remaining = ram_bytes_remaining(); info-ram-total = ram_bytes_total(); info-ram-duplicate = dup_mig_pages_transferred(); +info-ram-skipped = skipped_mig_pages_transferred(); info-ram-normal = norm_mig_pages_transferred(); info-ram-normal_bytes = norm_mig_bytes_transferred(); info-ram-dirty_pages_rate = s-dirty_pages_rate; - if (blk_mig_active()) { info-has_disk = true; info-disk = g_malloc0(sizeof(*info-disk)); @@ -227,6 +227,7 @@ MigrationInfo *qmp_query_migrate(Error **errp) info-ram-remaining = 0; info-ram-total = ram_bytes_total(); info-ram-duplicate = dup_mig_pages_transferred(); +info-ram-skipped = skipped_mig_pages_transferred(); info-ram-normal = norm_mig_pages_transferred(); info-ram-normal_bytes = norm_mig_bytes_transferred(); break; diff --git a/qapi-schema.json b/qapi-schema.json index 088f4e1..d6a8812 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -496,7 +496,9 @@ # # @total: total amount
[Qemu-devel] [PATCHv5 01/10] move vector definitions to qemu-common.h
vector optimizations will now be used at various places not just in is_dup_page() in arch_init.c Signed-off-by: Peter Lieven p...@kamp.de --- arch_init.c | 20 include/qemu-common.h | 21 + 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/arch_init.c b/arch_init.c index e8ade9e..35974c2 100644 --- a/arch_init.c +++ b/arch_init.c @@ -116,26 +116,6 @@ const uint32_t arch_type = QEMU_ARCH; #define RAM_SAVE_FLAG_CONTINUE 0x20 #define RAM_SAVE_FLAG_XBZRLE 0x40 -#ifdef __ALTIVEC__ -#include altivec.h -#define VECTYPEvector unsigned char -#define SPLAT(p) vec_splat(vec_ld(0, p), 0) -#define ALL_EQ(v1, v2) vec_all_eq(v1, v2) -/* altivec.h may redefine the bool macro as vector type. - * Reset it to POSIX semantics. */ -#undef bool -#define bool _Bool -#elif defined __SSE2__ -#include emmintrin.h -#define VECTYPE__m128i -#define SPLAT(p) _mm_set1_epi8(*(p)) -#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0x) -#else -#define VECTYPEunsigned long -#define SPLAT(p) (*(p) * (~0UL / 255)) -#define ALL_EQ(v1, v2) ((v1) == (v2)) -#endif - static struct defconfig_file { const char *filename; diff --git a/include/qemu-common.h b/include/qemu-common.h index 2371132..d7ad3a7 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -448,4 +448,25 @@ int uleb128_decode_small(const uint8_t *in, uint32_t *n); void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); +/* vector definitions */ +#ifdef __ALTIVEC__ +#include altivec.h +#define VECTYPEvector unsigned char +#define SPLAT(p) vec_splat(vec_ld(0, p), 0) +#define ALL_EQ(v1, v2) vec_all_eq(v1, v2) +/* altivec.h may redefine the bool macro as vector type. + * Reset it to POSIX semantics. */ +#undef bool +#define bool _Bool +#elif defined __SSE2__ +#include emmintrin.h +#define VECTYPE__m128i +#define SPLAT(p) _mm_set1_epi8(*(p)) +#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0x) +#else +#define VECTYPEunsigned long +#define SPLAT(p) (*(p) * (~0UL / 255)) +#define ALL_EQ(v1, v2) ((v1) == (v2)) +#endif + #endif -- 1.7.9.5
[Qemu-devel] [PATCHv5 07/10] migration: add an indicator for bulk state of ram migration
the first round of ram transfer is special since all pages are dirty and thus all memory pages are transferred to the target. this patch adds a boolean variable to track this stage. Signed-off-by: Peter Lieven p...@kamp.de Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Orit Wasserman owass...@redhat.com --- arch_init.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/arch_init.c b/arch_init.c index dd5deff..1291bd2 100644 --- a/arch_init.c +++ b/arch_init.c @@ -319,6 +319,7 @@ static ram_addr_t last_offset; static unsigned long *migration_bitmap; static uint64_t migration_dirty_pages; static uint32_t last_version; +static bool ram_bulk_stage; static inline ram_addr_t migration_bitmap_find_and_reset_dirty(MemoryRegion *mr, @@ -426,6 +427,7 @@ static int ram_save_block(QEMUFile *f, bool last_stage) if (!block) { block = QTAILQ_FIRST(ram_list.blocks); complete_round = true; +ram_bulk_stage = false; } } else { uint8_t *p; @@ -529,6 +531,7 @@ static void reset_ram_globals(void) last_sent_block = NULL; last_offset = 0; last_version = ram_list.version; +ram_bulk_stage = true; } #define MAX_WAIT 50 /* ms, half buffered_file limit */ -- 1.7.9.5
[Qemu-devel] [PATCHv5 03/10] cutils: add a function to find non-zero content in a buffer
this adds buffer_find_nonzero_offset() which is a SSE2/Altivec optimized function that searches for non-zero content in a buffer. the function starts full unrolling only after the first few chunks have been checked one by one. analyzing real memory page data has revealed that non-zero pages are non-zero within the first 256-512 bits in most cases. as this function is also heavily used to check for zero memory pages this tweak has been made to avoid the high setup costs of the fully unrolled check for non-zero pages. due to the optimizations used in the function there are restrictions on buffer address and search length. the function can_use_buffer_find_nonzero_content() can be used to check if the function can be used safely. Signed-off-by: Peter Lieven p...@kamp.de --- include/qemu-common.h | 13 util/cutils.c | 55 + 2 files changed, 68 insertions(+) diff --git a/include/qemu-common.h b/include/qemu-common.h index 9022646..7c7c244 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -472,4 +472,17 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #define ALL_EQ(v1, v2) ((v1) == (v2)) #endif +#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8 +static inline bool +can_use_buffer_find_nonzero_offset(const void *buf, size_t len) +{ +if (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR + * sizeof(VECTYPE)) == 0 + ((uintptr_t) buf) % sizeof(VECTYPE) == 0) { +return true; +} +return false; +} +size_t buffer_find_nonzero_offset(const void *buf, size_t len); + #endif diff --git a/util/cutils.c b/util/cutils.c index 1439da4..0314a18 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -143,6 +143,61 @@ int qemu_fdatasync(int fd) } /* + * Searches for an area with non-zero content in a buffer + * + * Attention! The len must be a multiple of + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE) + * and addr must be a multiple of sizeof(VECTYPE) due to + * restriction of optimizations in this function. + * + * can_use_buffer_find_nonzero_offset() can be used to check + * these requirements. + * + * The return value is the offset of the non-zero area rounded + * down to a multiple of sizeof(VECTYPE) for the first + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR chunks and down to + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE) + * afterwards. + * + * If the buffer is all zero the return value is equal to len. + */ + +size_t buffer_find_nonzero_offset(const void *buf, size_t len) +{ +VECTYPE *p = (VECTYPE *)buf; +VECTYPE zero = ZERO_SPLAT; +size_t i; + +assert(can_use_buffer_find_nonzero_offset(buf, len)); + +if (!len) { +return 0; +} + +for (i = 0; i BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) { +if (!ALL_EQ(p[i], zero)) { +return i * sizeof(VECTYPE); +} +} + +for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; + i len / sizeof(VECTYPE); + i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) { +VECTYPE tmp0 = p[i + 0] | p[i + 1]; +VECTYPE tmp1 = p[i + 2] | p[i + 3]; +VECTYPE tmp2 = p[i + 4] | p[i + 5]; +VECTYPE tmp3 = p[i + 6] | p[i + 7]; +VECTYPE tmp01 = tmp0 | tmp1; +VECTYPE tmp23 = tmp2 | tmp3; +if (!ALL_EQ(tmp01 | tmp23, zero)) { +break; +} +} + +return i * sizeof(VECTYPE); +} + +/* * Checks if a buffer is all zeroes * * Attention! The len must be a multiple of 4 * sizeof(long) due to -- 1.7.9.5
[Qemu-devel] [PATCHv5 09/10] migration: do not search dirty pages in bulk stage
avoid searching for dirty pages just increment the page offset. all pages are dirty anyway. Signed-off-by: Peter Lieven p...@kamp.de Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Orit Wasserman owass...@redhat.com --- arch_init.c |8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch_init.c b/arch_init.c index 3a0d02e..a522735 100644 --- a/arch_init.c +++ b/arch_init.c @@ -340,7 +340,13 @@ ram_addr_t migration_bitmap_find_and_reset_dirty(MemoryRegion *mr, unsigned long nr = base + (start TARGET_PAGE_BITS); unsigned long size = base + (int128_get64(mr-size) TARGET_PAGE_BITS); -unsigned long next = find_next_bit(migration_bitmap, size, nr); +unsigned long next; + +if (ram_bulk_stage nr base) { +next = nr + 1; +} else { +next = find_next_bit(migration_bitmap, size, nr); +} if (next size) { clear_bit(next, migration_bitmap); -- 1.7.9.5
[Qemu-devel] [PATCHv5 06/10] migration: search for zero instead of dup pages
virtually all dup pages are zero pages. remove the special is_dup_page() function and use the optimized buffer_find_nonzero_offset() function instead. here buffer_find_nonzero_offset() is used directly to avoid the unnecssary additional checks in buffer_is_zero(). raw performace gain checking 1 GByte zeroed memory over is_dup_page() is approx. 10-12% with SSE2 and 8-10% with unsigned long arithmedtic. Signed-off-by: Peter Lieven p...@kamp.de Reviewed-by: Orit Wasserman owass...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com --- arch_init.c | 21 ++--- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/arch_init.c b/arch_init.c index 35974c2..dd5deff 100644 --- a/arch_init.c +++ b/arch_init.c @@ -146,19 +146,10 @@ int qemu_read_default_config_files(bool userconfig) return 0; } -static int is_dup_page(uint8_t *page) +static inline bool is_zero_page(uint8_t *p) { -VECTYPE *p = (VECTYPE *)page; -VECTYPE val = SPLAT(page); -int i; - -for (i = 0; i TARGET_PAGE_SIZE / sizeof(VECTYPE); i++) { -if (!ALL_EQ(val, p[i])) { -return 0; -} -} - -return 1; +return buffer_find_nonzero_offset(p, TARGET_PAGE_SIZE) == +TARGET_PAGE_SIZE; } /* struct contains XBZRLE cache and a static page @@ -445,12 +436,12 @@ static int ram_save_block(QEMUFile *f, bool last_stage) /* In doubt sent page as normal */ bytes_sent = -1; -if (is_dup_page(p)) { +if (is_zero_page(p)) { acct_info.dup_pages++; bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS); -qemu_put_byte(f, *p); -bytes_sent += 1; +qemu_put_byte(f, 0); +bytes_sent++; } else if (migrate_use_xbzrle()) { current_addr = block-offset + offset; bytes_sent = save_xbzrle_page(f, p, current_addr, block, -- 1.7.9.5
Re: [Qemu-devel] coroutine: hung when using gthread backend
Il 26/03/2013 10:54, Stefan Hajnoczi ha scritto: On Tue, Mar 26, 2013 at 08:03:50AM +0100, Paolo Bonzini wrote: Il 26/03/2013 03:50, Wenchao Xia ha scritto: When I using tcg with coroutine backend = gthread, x86_64-softmmu/qemu-system-x86_64 will hung. Any one working on it? coroutine backend gthread hardly works for qemu, only qemu-io and qemu-img. Do you know why it doesn't work? Because it screws up the signals. Coroutines can start in a thread and later move to another. If you use the gthread backend, coroutines keep the signal mask of the thread where they were created. It is basically the same bug that was fixed in commit 6ab7e54 (Replace all setjmp()/longjmp() with sigsetjmp()/siglongjmp(), 2013-02-20). Paolo
[Qemu-devel] [PATCH 01/11] qemu-char: Rename opened to be_open
Rename the opened variable to be_open to reflect that it contains the opened state of the backend. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/dev-serial.c | 2 +- hw/usb/redirect.c | 2 +- include/char/char.h | 2 +- qemu-char.c | 6 +++--- spice-qemu-char.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index 47ac8c9..7c314dc 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -495,7 +495,7 @@ static int usb_serial_initfn(USBDevice *dev) usb_serial_event, s); usb_serial_handle_reset(dev); -if (s-cs-opened !dev-attached) { +if (s-cs-be_open !dev-attached) { usb_device_attach(dev); } return 0; diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index c519b9b..9734e42 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -258,7 +258,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count) { USBRedirDevice *dev = priv; -if (!dev-cs-opened) { +if (!dev-cs-be_open) { return 0; } diff --git a/include/char/char.h b/include/char/char.h index 0326b2a..d801f92 100644 --- a/include/char/char.h +++ b/include/char/char.h @@ -74,7 +74,7 @@ struct CharDriverState { int idle_tag; char *label; char *filename; -int opened; +int be_open; int avail_connections; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; diff --git a/qemu-char.c b/qemu-char.c index 4e011df..32a05af 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -108,10 +108,10 @@ void qemu_chr_be_event(CharDriverState *s, int event) /* Keep track if the char device is open */ switch (event) { case CHR_EVENT_OPENED: -s-opened = 1; +s-be_open = 1; break; case CHR_EVENT_CLOSED: -s-opened = 0; +s-be_open = 0; break; } @@ -207,7 +207,7 @@ void qemu_chr_add_handlers(CharDriverState *s, /* We're connecting to an already opened device, so let's make sure we also get the open event */ -if (s-opened) { +if (s-be_open) { qemu_chr_generic_open(s); } } diff --git a/spice-qemu-char.c b/spice-qemu-char.c index 8a9236d..c39095b 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -100,8 +100,8 @@ static void vmc_state(SpiceCharDeviceInstance *sin, int connected) } #endif -if ((scd-chr-opened connected) || -(!scd-chr-opened !connected)) { +if ((scd-chr-be_open connected) || +(!scd-chr-be_open !connected)) { return; } -- 1.8.1.4
[Qemu-devel] [PATCHv5 10/10] migration: use XBZRLE only after bulk stage
at the beginning of migration all pages are marked dirty and in the first round a bulk migration of all pages is performed. currently all these pages are copied to the page cache regardless of whether they are frequently updated or not. this doesn't make sense since most of these pages are never transferred again. this patch changes the XBZRLE transfer to only be used after the bulk stage has been completed. that means a page is added to the page cache the second time it is transferred and XBZRLE can benefit from the third time of transfer. since the page cache is likely smaller than the number of pages it's also likely that in the second round the page is missing in the cache due to collisions in the bulk phase. on the other hand a lot of unnecessary mallocs, memdups and frees are saved. the following results have been taken earlier while executing the test program from docs/xbzrle.txt. (+) with the patch and (-) without. (thanks to Eric Blake for reformatting and comments) + total time: 22185 milliseconds - total time: 22410 milliseconds Shaved 0.3 seconds, better than 1%! + downtime: 29 milliseconds - downtime: 21 milliseconds Not sure why downtime seemed worse, but probably not the end of the world. + transferred ram: 706034 kbytes - transferred ram: 721318 kbytes Fewer bytes sent - good. + remaining ram: 0 kbytes - remaining ram: 0 kbytes + total ram: 1057216 kbytes - total ram: 1057216 kbytes + duplicate: 108556 pages - duplicate: 105553 pages + normal: 175146 pages - normal: 179589 pages + normal bytes: 700584 kbytes - normal bytes: 718356 kbytes Fewer normal bytes... + cache size: 67108864 bytes - cache size: 67108864 bytes + xbzrle transferred: 3127 kbytes - xbzrle transferred: 630 kbytes ...and more compressed pages sent - good. + xbzrle pages: 117811 pages - xbzrle pages: 21527 pages + xbzrle cache miss: 18750 - xbzrle cache miss: 179589 And very good improvement on the cache miss rate. + xbzrle overflow : 0 - xbzrle overflow : 0 Signed-off-by: Peter Lieven p...@kamp.de Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Orit Wasserman owass...@redhat.com --- arch_init.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch_init.c b/arch_init.c index a522735..e1af898 100644 --- a/arch_init.c +++ b/arch_init.c @@ -466,7 +466,7 @@ static int ram_save_block(QEMUFile *f, bool last_stage) acct_info.skipped_pages++; bytes_sent = 0; } -} else if (migrate_use_xbzrle()) { +} else if (!ram_bulk_stage migrate_use_xbzrle()) { current_addr = block-offset + offset; bytes_sent = save_xbzrle_page(f, p, current_addr, block, offset, cont, last_stage); -- 1.7.9.5
[Qemu-devel] [PATCHv5 00/10] buffer_is_zero / migration optimizations
this is v5 of my patch series with various optimizations in zero buffer checking and migration tweaks. thanks especially to Eric Blake, Orit Wassermann and Paolo Bonzini for reviewing. v5: - move zero splat vector to a different patch - fix indentation of can_user_buffer_find_nonzero_offset() - do not unroll the first loop in buffer_find_nonzero_offset() to optimize it for zero page checking - use an older unrolled version of find_next_bit() without SIMD instruction as there is no evidence that the vectorized version is better if not even worse and the code is easier to understand. - added a word in the commit message of patch 8 about the skipped pages field in QMP MigrationStats. - fixed the order of key-value pairs of MigrationStats in qapi-schema.json - updated info about the performance benefit of is_zero_page() to the latest benchmark results in the commit message. v4: - do not inline buffer_find_nonzero_offset() - inline can_usebuffer_find_nonzero_offset() correctly - readd asserts in buffer_find_nonzero_offset() as profiling shows they do not hurt. - change last occurences of scalar 8 by BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR - avoid deferencing p already in patch 5 where we know that the page (p) is zero - explicitly set bytes_sent = 0 if we skip a zero page. bytes_sent was 0 before, but it was not obvious. - add accounting information for skipped zero pages - fix errors reported by checkpatch.pl v3: - remove asserts, inline functions and add a check function if buffer_find_nonzero_offset() can be used. - use above check function in buffer_is_zero() and find_next_bit(). - use buffer_is_nonzero_offset() directly to find zero pages. we know that all requirements are met for memory pages. - fix C89 violation in buffer_is_zero(). - avoid derefencing p in ram_save_block() if we already know the page is zero. - fix initialization of last_offset in reset_ram_globals(). - avoid skipping pages with offset == 0 in bulk stage in migration_bitmap_find_and_reset_dirty(). - compared to v1 check for zero pages also after bulk ram migration as there are guests (e.g. Windows) which zero out large amount of memory while running. v2: - fix description, add trivial zero check and add asserts to buffer_find_nonzero_offset. - add a constant for the unroll factor of buffer_find_nonzero_offset - replace is_dup_page() by buffer_is_zero() - added test results to xbzrle patch - optimize descriptions Peter Lieven (10): move vector definitions to qemu-common.h add a zero splat vector to qemu-common.h cutils: add a function to find non-zero content in a buffer buffer_is_zero: use vector optimizations if possible bitops: unroll while loop in find_next_bit() migration: search for zero instead of dup pages migration: add an indicator for bulk state of ram migration migration: do not sent zero pages in bulk stage migration: do not search dirty pages in bulk stage migration: use XBZRLE only after bulk stage arch_init.c | 74 +++-- hmp.c |2 ++ include/migration/migration.h |2 ++ include/qemu-common.h | 37 + migration.c |3 +- qapi-schema.json |8 +++-- qmp-commands.hx |3 +- util/bitops.c | 18 +- util/cutils.c | 60 + 9 files changed, 162 insertions(+), 45 deletions(-) -- 1.7.9.5
[Qemu-devel] [PATCHv5 02/10] add a zero splat vector to qemu-common.h
Signed-off-by: Peter Lieven p...@kamp.de --- include/qemu-common.h |3 +++ 1 file changed, 3 insertions(+) diff --git a/include/qemu-common.h b/include/qemu-common.h index d7ad3a7..9022646 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -453,6 +453,7 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #include altivec.h #define VECTYPEvector unsigned char #define SPLAT(p) vec_splat(vec_ld(0, p), 0) +#define ZERO_SPLAT vec_splat(vec_ld(0, 0), 0) #define ALL_EQ(v1, v2) vec_all_eq(v1, v2) /* altivec.h may redefine the bool macro as vector type. * Reset it to POSIX semantics. */ @@ -462,10 +463,12 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #include emmintrin.h #define VECTYPE__m128i #define SPLAT(p) _mm_set1_epi8(*(p)) +#define ZERO_SPLAT _mm_setzero_si128() #define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0x) #else #define VECTYPEunsigned long #define SPLAT(p) (*(p) * (~0UL / 255)) +#define ZERO_SPLAT 0x0UL #define ALL_EQ(v1, v2) ((v1) == (v2)) #endif -- 1.7.9.5
[Qemu-devel] [PATCH 05/11] qemu-char: Cleanup: consolidate fe_open/fe_close into fe_set_open
Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/virtio-console.c | 4 ++-- include/char/char.h | 17 - qemu-char.c | 24 ++-- 3 files changed, 12 insertions(+), 33 deletions(-) diff --git a/hw/virtio-console.c b/hw/virtio-console.c index 2f7c3df..7c89990 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -74,7 +74,7 @@ static void guest_open(VirtIOSerialPort *port) if (!vcon-chr) { return; } -qemu_chr_fe_open(vcon-chr); +qemu_chr_fe_set_open(vcon-chr, 1); } /* Callback function that's called when the guest closes the port */ @@ -85,7 +85,7 @@ static void guest_close(VirtIOSerialPort *port) if (!vcon-chr) { return; } -qemu_chr_fe_close(vcon-chr); +qemu_chr_fe_set_open(vcon-chr, 0); } /* Readiness of the guest to accept data on a port */ diff --git a/include/char/char.h b/include/char/char.h index 27ebbc3..3c8dd28 100644 --- a/include/char/char.h +++ b/include/char/char.h @@ -129,21 +129,12 @@ void qemu_chr_delete(CharDriverState *chr); void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo); /** - * @qemu_chr_fe_open: + * @qemu_chr_fe_set_open: * - * Open a character backend. This function call is an indication that the - * front end is ready to begin doing I/O. + * Set character frontend open status. This is an indication that the + * front end is ready (or not) to begin doing I/O. */ -void qemu_chr_fe_open(struct CharDriverState *chr); - -/** - * @qemu_chr_fe_close: - * - * Close a character backend. This function call indicates that the front end - * no longer is able to process I/O. To process I/O again, the front end will - * call @qemu_chr_fe_open. - */ -void qemu_chr_fe_close(struct CharDriverState *chr); +void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open); /** * @qemu_chr_fe_printf: diff --git a/qemu-char.c b/qemu-char.c index f580297..3651af1 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -211,11 +211,7 @@ void qemu_chr_add_handlers(CharDriverState *s, s-chr_update_read_handler(s); if (!s-explicit_fe_open) { -if (fe_open) { -qemu_chr_fe_open(s); -} else { -qemu_chr_fe_close(s); -} +qemu_chr_fe_set_open(s, fe_open); } /* We're connecting to an already opened device, so let's make sure we @@ -3396,24 +3392,16 @@ void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo) } } -void qemu_chr_fe_open(struct CharDriverState *chr) +void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open) { -if (chr-fe_open) { +if (chr-fe_open == fe_open) { return; } -chr-fe_open = 1; -if (chr-chr_guest_open) { +chr-fe_open = fe_open; +if (fe_open chr-chr_guest_open) { chr-chr_guest_open(chr); } -} - -void qemu_chr_fe_close(struct CharDriverState *chr) -{ -if (!chr-fe_open) { -return; -} -chr-fe_open = 0; -if (chr-chr_guest_close) { +if (!fe_open chr-chr_guest_close) { chr-chr_guest_close(chr); } } -- 1.8.1.4
[Qemu-devel] [PATCH 03/11] qemu-char: Add fe_open tracking
Add tracking of the fe_open state to struct CharDriverState. Signed-off-by: Hans de Goede hdego...@redhat.com --- include/char/char.h | 1 + qemu-char.c | 8 2 files changed, 9 insertions(+) diff --git a/include/char/char.h b/include/char/char.h index dd8f39a..3174575 100644 --- a/include/char/char.h +++ b/include/char/char.h @@ -75,6 +75,7 @@ struct CharDriverState { char *label; char *filename; int be_open; +int fe_open; int avail_connections; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; diff --git a/qemu-char.c b/qemu-char.c index 55795d7..2f35504 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3385,6 +3385,10 @@ void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo) void qemu_chr_fe_open(struct CharDriverState *chr) { +if (chr-fe_open) { +return; +} +chr-fe_open = 1; if (chr-chr_guest_open) { chr-chr_guest_open(chr); } @@ -3392,6 +3396,10 @@ void qemu_chr_fe_open(struct CharDriverState *chr) void qemu_chr_fe_close(struct CharDriverState *chr) { +if (!chr-fe_open) { +return; +} +chr-fe_open = 0; if (chr-chr_guest_close) { chr-chr_guest_close(chr); } -- 1.8.1.4
[Qemu-devel] [PATCH 04/11] qemu-char: Automatically do fe_open / fe_close on qemu_chr_add_handlers
Most frontends can't really determine if the guest actually has the frontend side open. So lets automatically generate fe_open / fe_close as soon as a frontend becomes ready (as signalled by calling qemu_chr_add_handlers) / becomes non ready (as signalled by setting all handlers to NULL). And allow frontends which can actually determine if the guest is listening to opt-out of this. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/redirect.c | 2 -- hw/virtio-console.c | 1 + include/char/char.h | 1 + qemu-char.c | 13 + 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 9734e42..d02a7b9 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -1282,7 +1282,6 @@ static int usbredir_initfn(USBDevice *udev) dev-compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH; /* Let the backend know we are ready */ -qemu_chr_fe_open(dev-cs); qemu_chr_add_handlers(dev-cs, usbredir_chardev_can_read, usbredir_chardev_read, usbredir_chardev_event, dev); @@ -1306,7 +1305,6 @@ static void usbredir_handle_destroy(USBDevice *udev) { USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -qemu_chr_fe_close(dev-cs); qemu_chr_delete(dev-cs); /* Note must be done after qemu_chr_close, as that causes a close event */ qemu_bh_delete(dev-chardev_close_bh); diff --git a/hw/virtio-console.c b/hw/virtio-console.c index e2d1c58..2f7c3df 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -131,6 +131,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port) } if (vcon-chr) { +vcon-chr-explicit_fe_open = 1; qemu_chr_add_handlers(vcon-chr, chr_can_read, chr_read, chr_event, vcon); } diff --git a/include/char/char.h b/include/char/char.h index 3174575..27ebbc3 100644 --- a/include/char/char.h +++ b/include/char/char.h @@ -76,6 +76,7 @@ struct CharDriverState { char *filename; int be_open; int fe_open; +int explicit_fe_open; int avail_connections; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; diff --git a/qemu-char.c b/qemu-char.c index 2f35504..f580297 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -194,9 +194,14 @@ void qemu_chr_add_handlers(CharDriverState *s, IOEventHandler *fd_event, void *opaque) { +int fe_open; + if (!opaque !fd_can_read !fd_read !fd_event) { /* chr driver being released. */ ++s-avail_connections; +fe_open = 0; +} else { +fe_open = 1; } s-chr_can_read = fd_can_read; s-chr_read = fd_read; @@ -205,6 +210,14 @@ void qemu_chr_add_handlers(CharDriverState *s, if (s-chr_update_read_handler) s-chr_update_read_handler(s); +if (!s-explicit_fe_open) { +if (fe_open) { +qemu_chr_fe_open(s); +} else { +qemu_chr_fe_close(s); +} +} + /* We're connecting to an already opened device, so let's make sure we also get the open event */ if (s-be_open) { -- 1.8.1.4
[Qemu-devel] [PATCH 0/11] chardev frontend open handling cleanup v2
This patch-series is the result of the [PATCH 1/2] char: add qemu_chr_be_is_fe_connected discussion thread. This patch series makes the frontend open concept both more explicit and generic, and significantly cleans up the surrounding code. Changes in v2: - Based on top of latest master - Add protection against double closing / opening to: [PATCH 03/11] qemu-char: Add fe_open tracking - Add 3 new patches, including a fix for the migration issue which started the whole discussion: [PATCH 07/11] qemu-char: Move incrementing of avail_connections to [PATCH 08/11] qemu-char: add_handlers: Don't re-send the be_open [PATCH 10/11] virtio-serial: propagate guest_connected to the port on Regards, Hans
[Qemu-devel] [PATCH 11/11] spice-qemu-char: Drop hackish vmc_register on spice_chr_write
Now that the core takes care of fe_open tracking we no longer need this hack. Signed-off-by: Hans de Goede hdego...@redhat.com --- spice-qemu-char.c | 1 - 1 file changed, 1 deletion(-) diff --git a/spice-qemu-char.c b/spice-qemu-char.c index d249829..535f955 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -149,7 +149,6 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { SpiceCharDriver *s = chr-opaque; -vmc_register_interface(s); assert(s-datalen == 0); if (s-bufsize len) { s-bufsize = len; -- 1.8.1.4
[Qemu-devel] [PATCH 07/11] qemu-char: Move incrementing of avail_connections to qdev-properties-system
The decrement of avail_connections is done in qdev-properties-system move the increment there too for proper balancing of the calls. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/qdev-properties-system.c | 6 -- qemu-char.c | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c index 8795144..12a87d5 100644 --- a/hw/qdev-properties-system.c +++ b/hw/qdev-properties-system.c @@ -136,9 +136,11 @@ static void release_chr(Object *obj, const char *name, void *opaque) DeviceState *dev = DEVICE(obj); Property *prop = opaque; CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); +CharDriverState *chr = *ptr; -if (*ptr) { -qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); +if (chr) { +qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL); +++chr-avail_connections; } } diff --git a/qemu-char.c b/qemu-char.c index 8a66627..368e7f5 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -197,8 +197,6 @@ void qemu_chr_add_handlers(CharDriverState *s, int fe_open; if (!opaque !fd_can_read !fd_read !fd_event) { -/* chr driver being released. */ -++s-avail_connections; fe_open = 0; } else { fe_open = 1; -- 1.8.1.4
[Qemu-devel] [PATCH 02/11] qemu-char: Rename qemu_chr_generic_open to qemu_chr_be_generic_open
To better reflect that it is for handling a backend being opened. Signed-off-by: Hans de Goede hdego...@redhat.com --- backends/baum.c | 2 +- include/char/char.h | 2 +- qemu-char.c | 24 ui/console.c| 2 +- ui/gtk.c| 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/backends/baum.c b/backends/baum.c index d7d658c..ea9ffe8 100644 --- a/backends/baum.c +++ b/backends/baum.c @@ -611,7 +611,7 @@ CharDriverState *chr_baum_init(void) qemu_set_fd_handler(baum-brlapi_fd, baum_chr_read, NULL, baum); -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); return chr; diff --git a/include/char/char.h b/include/char/char.h index d801f92..dd8f39a 100644 --- a/include/char/char.h +++ b/include/char/char.h @@ -235,7 +235,7 @@ void qemu_chr_add_handlers(CharDriverState *s, IOEventHandler *fd_event, void *opaque); -void qemu_chr_generic_open(CharDriverState *s); +void qemu_chr_be_generic_open(CharDriverState *s); void qemu_chr_accept_input(CharDriverState *s); int qemu_chr_add_client(CharDriverState *s, int fd); void qemu_chr_info_print(Monitor *mon, const QObject *ret_data); diff --git a/qemu-char.c b/qemu-char.c index 32a05af..55795d7 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -120,7 +120,7 @@ void qemu_chr_be_event(CharDriverState *s, int event) s-chr_event(s-handler_opaque, event); } -static gboolean qemu_chr_generic_open_bh(gpointer opaque) +static gboolean qemu_chr_be_generic_open_bh(gpointer opaque) { CharDriverState *s = opaque; qemu_chr_be_event(s, CHR_EVENT_OPENED); @@ -128,10 +128,10 @@ static gboolean qemu_chr_generic_open_bh(gpointer opaque) return FALSE; } -void qemu_chr_generic_open(CharDriverState *s) +void qemu_chr_be_generic_open(CharDriverState *s) { if (s-idle_tag == 0) { -s-idle_tag = g_idle_add(qemu_chr_generic_open_bh, s); +s-idle_tag = g_idle_add(qemu_chr_be_generic_open_bh, s); } } @@ -208,7 +208,7 @@ void qemu_chr_add_handlers(CharDriverState *s, /* We're connecting to an already opened device, so let's make sure we also get the open event */ if (s-be_open) { -qemu_chr_generic_open(s); +qemu_chr_be_generic_open(s); } } @@ -482,7 +482,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) chr-chr_guest_close = NULL; /* Muxes are always open on creation */ -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); return chr; } @@ -836,7 +836,7 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) chr-chr_update_read_handler = fd_chr_update_read_handler; chr-chr_close = fd_chr_close; -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); return chr; } @@ -1133,7 +1133,7 @@ static void pty_chr_state(CharDriverState *chr, int connected) pty_chr_rearm_timer(chr, 1000); } else { if (!s-connected) -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); s-connected = 1; } } @@ -1549,7 +1549,7 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd) chr-chr_close = pp_close; chr-opaque = drv; -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); return chr; } @@ -1834,7 +1834,7 @@ static CharDriverState *qemu_chr_open_win_path(const char *filename) g_free(chr); return NULL; } -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); return chr; } @@ -1934,7 +1934,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) g_free(chr); return NULL; } -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); return chr; } @@ -1948,7 +1948,7 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out) s-hcom = fd_out; chr-opaque = s; chr-chr_write = win_chr_write; -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); return chr; } @@ -2513,7 +2513,7 @@ static void tcp_chr_connect(void *opaque) if (s-chan) { s-tag = io_add_watch_poll(s-chan, tcp_chr_read_poll, tcp_chr_read, chr); } -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); } #define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c; diff --git a/ui/console.c b/ui/console.c index eb7a2bc..e84ba8b 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1600,7 +1600,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds) s-t_attrib = s-t_attrib_default; } -qemu_chr_generic_open(chr); +qemu_chr_be_generic_open(chr); if (chr-init) chr-init(chr); } diff --git a/ui/gtk.c b/ui/gtk.c index 1edfaca..a5a8156 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1163,7 +1163,7 @@ static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, GSL
[Qemu-devel] [PATCH 06/11] qemu-char: Consolidate guest_close/guest_open into a set_fe_open callback
Signed-off-by: Hans de Goede hdego...@redhat.com --- include/char/char.h | 3 +-- qemu-char.c | 10 +++--- spice-qemu-char.c | 17 +++-- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/include/char/char.h b/include/char/char.h index 3c8dd28..1457e80 100644 --- a/include/char/char.h +++ b/include/char/char.h @@ -68,8 +68,7 @@ struct CharDriverState { void (*chr_close)(struct CharDriverState *chr); void (*chr_accept_input)(struct CharDriverState *chr); void (*chr_set_echo)(struct CharDriverState *chr, bool echo); -void (*chr_guest_open)(struct CharDriverState *chr); -void (*chr_guest_close)(struct CharDriverState *chr); +void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open); void *opaque; int idle_tag; char *label; diff --git a/qemu-char.c b/qemu-char.c index 3651af1..8a66627 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -487,8 +487,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) chr-chr_update_read_handler = mux_chr_update_read_handler; chr-chr_accept_input = mux_chr_accept_input; /* Frontend guest-open / -close notification is not support with muxes */ -chr-chr_guest_open = NULL; -chr-chr_guest_close = NULL; +chr-chr_set_fe_open = NULL; /* Muxes are always open on creation */ qemu_chr_be_generic_open(chr); @@ -3398,11 +3397,8 @@ void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open) return; } chr-fe_open = fe_open; -if (fe_open chr-chr_guest_open) { -chr-chr_guest_open(chr); -} -if (!fe_open chr-chr_guest_close) { -chr-chr_guest_close(chr); +if (chr-chr_set_fe_open) { +chr-chr_set_fe_open(chr, fe_open); } } diff --git a/spice-qemu-char.c b/spice-qemu-char.c index c39095b..d249829 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -176,16 +176,14 @@ static void spice_chr_close(struct CharDriverState *chr) g_free(s); } -static void spice_chr_guest_open(struct CharDriverState *chr) +static void spice_chr_set_fe_open(struct CharDriverState *chr, int fe_open) { SpiceCharDriver *s = chr-opaque; -vmc_register_interface(s); -} - -static void spice_chr_guest_close(struct CharDriverState *chr) -{ -SpiceCharDriver *s = chr-opaque; -vmc_unregister_interface(s); +if (fe_open) { +vmc_register_interface(s); +} else { +vmc_unregister_interface(s); +} } static void print_allowed_subtypes(void) @@ -218,8 +216,7 @@ static CharDriverState *chr_open(const char *subtype) chr-opaque = s; chr-chr_write = spice_chr_write; chr-chr_close = spice_chr_close; -chr-chr_guest_open = spice_chr_guest_open; -chr-chr_guest_close = spice_chr_guest_close; +chr-chr_set_fe_open = spice_chr_set_fe_open; QLIST_INSERT_HEAD(spice_chars, s, next); -- 1.8.1.4
[Qemu-devel] [PATCH 08/11] qemu-char: add_handlers: Don't re-send the be_open event on unregister
Resending the be_open event only is useful when a frontend is registering, not when it is unregistering. Signed-off-by: Hans de Goede hdego...@redhat.com --- qemu-char.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-char.c b/qemu-char.c index 368e7f5..edf3779 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -214,7 +214,7 @@ void qemu_chr_add_handlers(CharDriverState *s, /* We're connecting to an already opened device, so let's make sure we also get the open event */ -if (s-be_open) { +if (fe_open s-be_open) { qemu_chr_be_generic_open(s); } } -- 1.8.1.4
[Qemu-devel] [PATCH 10/11] virtio-serial: propagate guest_connected to the port on post_load
From: Alon Levy al...@redhat.com When migrating a host with with a spice agent running the mouse becomes non operational after the migration due to the agent state being inconsistent between the guest and the client. After migration the spicevmc backend on the destination has never been notified of the (non 0) guest_connected state. Virtio-serial holds this state information and migrates it, this patch properly propagates this information to virtio-console and through that to interested chardev backends. rhbz #725965 Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/virtio-serial-bus.c | 5 + 1 file changed, 5 insertions(+) diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index eb7af21..a9cb114 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -579,6 +579,7 @@ static void virtio_serial_post_load_timer_cb(void *opaque) VirtIOSerial *s = opaque; VirtIOSerialPort *port; uint8_t host_connected; +VirtIOSerialPortClass *vsc; if (!s-post_load) { return; @@ -594,6 +595,10 @@ static void virtio_serial_post_load_timer_cb(void *opaque) send_control_event(s, port-id, VIRTIO_CONSOLE_PORT_OPEN, port-host_connected); } +vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); +if (vsc-set_guest_connected) { +vsc-set_guest_connected(port, port-guest_connected); +} } g_free(s-post_load-connected); qemu_free_timer(s-post_load-timer); -- 1.8.1.4
[Qemu-devel] [PATCH 09/11] virtio-serial: Consolidate guest_open/guest_close into set_guest_connected
Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/virtio-console.c| 23 +-- hw/virtio-serial-bus.c | 15 +-- hw/virtio-serial.h | 6 ++ 3 files changed, 12 insertions(+), 32 deletions(-) diff --git a/hw/virtio-console.c b/hw/virtio-console.c index 7c89990..284180f 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -66,26 +66,15 @@ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) return ret; } -/* Callback function that's called when the guest opens the port */ -static void guest_open(VirtIOSerialPort *port) +/* Callback function that's called when the guest opens/closes the port */ +static void set_guest_connected(VirtIOSerialPort *port, int guest_connected) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); if (!vcon-chr) { return; } -qemu_chr_fe_set_open(vcon-chr, 1); -} - -/* Callback function that's called when the guest closes the port */ -static void guest_close(VirtIOSerialPort *port) -{ -VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); - -if (!vcon-chr) { -return; -} -qemu_chr_fe_set_open(vcon-chr, 0); +qemu_chr_fe_set_open(vcon-chr, guest_connected); } /* Readiness of the guest to accept data on a port */ @@ -152,8 +141,7 @@ static void virtconsole_class_init(ObjectClass *klass, void *data) k-is_console = true; k-init = virtconsole_initfn; k-have_data = flush_buf; -k-guest_open = guest_open; -k-guest_close = guest_close; +k-set_guest_connected = set_guest_connected; dc-props = virtconsole_properties; } @@ -176,8 +164,7 @@ static void virtserialport_class_init(ObjectClass *klass, void *data) k-init = virtconsole_initfn; k-have_data = flush_buf; -k-guest_open = guest_open; -k-guest_close = guest_close; +k-set_guest_connected = set_guest_connected; dc-props = virtserialport_properties; } diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index ab7168e..eb7af21 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -372,14 +372,9 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) case VIRTIO_CONSOLE_PORT_OPEN: port-guest_connected = cpkt.value; -if (cpkt.value vsc-guest_open) { +if (vsc-set_guest_connected) { /* Send the guest opened notification if an app is interested */ -vsc-guest_open(port); -} - -if (!cpkt.value vsc-guest_close) { -/* Send the guest closed notification if an app is interested */ -vsc-guest_close(port); +vsc-set_guest_connected(port, cpkt.value); } break; } @@ -484,9 +479,9 @@ static void guest_reset(VirtIOSerial *vser) vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); if (port-guest_connected) { port-guest_connected = false; - -if (vsc-guest_close) -vsc-guest_close(port); +if (vsc-set_guest_connected) { +vsc-set_guest_connected(port, false); +} } } } diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h index 484dcfe..516400f 100644 --- a/hw/virtio-serial.h +++ b/hw/virtio-serial.h @@ -92,10 +92,8 @@ typedef struct VirtIOSerialPortClass { int (*exit)(VirtIOSerialPort *port); /* Callbacks for guest events */ -/* Guest opened device. */ -void (*guest_open)(VirtIOSerialPort *port); -/* Guest closed device. */ -void (*guest_close)(VirtIOSerialPort *port); +/* Guest opened/closed device. */ +void (*set_guest_connected)(VirtIOSerialPort *port, int guest_connected); /* Guest is now ready to accept data (virtqueues set up). */ void (*guest_ready)(VirtIOSerialPort *port); -- 1.8.1.4
Re: [Qemu-devel] [PATCHv5 02/10] add a zero splat vector to qemu-common.h
Il 26/03/2013 10:58, Peter Lieven ha scritto: Signed-off-by: Peter Lieven p...@kamp.de --- include/qemu-common.h |3 +++ 1 file changed, 3 insertions(+) diff --git a/include/qemu-common.h b/include/qemu-common.h index d7ad3a7..9022646 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -453,6 +453,7 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #include altivec.h #define VECTYPEvector unsigned char #define SPLAT(p) vec_splat(vec_ld(0, p), 0) +#define ZERO_SPLAT vec_splat(vec_ld(0, 0), 0) #define ALL_EQ(v1, v2) vec_all_eq(v1, v2) /* altivec.h may redefine the bool macro as vector type. * Reset it to POSIX semantics. */ @@ -462,10 +463,12 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #include emmintrin.h #define VECTYPE__m128i #define SPLAT(p) _mm_set1_epi8(*(p)) +#define ZERO_SPLAT _mm_setzero_si128() #define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0x) #else #define VECTYPEunsigned long #define SPLAT(p) (*(p) * (~0UL / 255)) +#define ZERO_SPLAT 0x0UL #define ALL_EQ(v1, v2) ((v1) == (v2)) #endif C trivia of the day: this can be written simply as (VECTYPE) {0} Yes, it works even with unsigned long. :) It is a C99 compound literal. Paolo
Re: [Qemu-devel] [PATCH v2] block: Add support for Secure Shell (ssh) block device.
On Mon, Mar 25, 2013 at 11:49:41PM +, Richard W.M. Jones wrote: From: Richard W.M. Jones rjo...@redhat.com qemu-system-x86_64 -drive file=ssh://hostname/some/image QEMU will ssh into 'hostname' and open '/some/image' which is made available as a standard block device. You can specify a username (ssh://user@host/...) and/or a port number (ssh://host:port/...). Current limitations: - Authentication must be done without passwords or passphrases, using ssh-agent. Other authentication methods are not supported. (*) - Does not check host key. (*) - New remote files cannot be created. (*) - Uses a single connection, instead of concurrent AIO with multiple SSH connections. - Blocks during connection and authentication. This isn't ideal but .bdrv_open() is a blocking function anyway. If you open a raw image on an NFS export the open(2) call can block too. Blocking in .bdrv_open() is fine during startup. It's bad when hotplugging drives since the running VM will experience downtime. +/* Start SFTP. */ +s-sftp = libssh2_sftp_init(s-session); +if (!s-sftp) { +session_error_report(s, failed to initialize sftp handle); +ret = -EINVAL; +goto err; +} + +s-sftp_handle = libssh2_sftp_open(s-sftp, path, + LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE, Probably worth handling -drive ...,readonly=on. !(flags BDRV_O_RDWR) +static coroutine_fn void set_fd_handler(BDRVSSHState *s) +{ +int r; +void (*rd_handler)(void*); +void (*wr_handler)(void*); There's a typedef for this: IOHandler. +Coroutine *co = qemu_coroutine_self(); + +rd_handler = wr_handler = NULL; + +r = libssh2_session_block_directions(s-session); + +if (r LIBSSH2_SESSION_BLOCK_INBOUND) { +rd_handler = restart_coroutine; +} +if (r LIBSSH2_SESSION_BLOCK_OUTBOUND) { +wr_handler = restart_coroutine; +} + +DPRINTF(s-sock=%d rd_handler=%p wr_handler=%p, s-sock, +rd_handler, wr_handler); + +qemu_aio_set_fd_handler(s-sock, rd_handler, wr_handler, return_true, co); +} + +/* A non-blocking call returned EAGAIN, so yield, ensuring the + * handlers are set up so that we'll be rescheduled when there is an + * interesting event on the socket. + */ +static coroutine_fn void co_yield(BDRVSSHState *s) +{ +set_fd_handler(s); +qemu_coroutine_yield(); Should we clear the fd handler here? That way the caller doesn't have to worry about fd handler state.
Re: [Qemu-devel] [PATCHv5 02/10] add a zero splat vector to qemu-common.h
Am 26.03.2013 um 11:14 schrieb Paolo Bonzini pbonz...@redhat.com: Il 26/03/2013 10:58, Peter Lieven ha scritto: Signed-off-by: Peter Lieven p...@kamp.de --- include/qemu-common.h |3 +++ 1 file changed, 3 insertions(+) diff --git a/include/qemu-common.h b/include/qemu-common.h index d7ad3a7..9022646 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -453,6 +453,7 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #include altivec.h #define VECTYPEvector unsigned char #define SPLAT(p) vec_splat(vec_ld(0, p), 0) +#define ZERO_SPLAT vec_splat(vec_ld(0, 0), 0) #define ALL_EQ(v1, v2) vec_all_eq(v1, v2) /* altivec.h may redefine the bool macro as vector type. * Reset it to POSIX semantics. */ @@ -462,10 +463,12 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #include emmintrin.h #define VECTYPE__m128i #define SPLAT(p) _mm_set1_epi8(*(p)) +#define ZERO_SPLAT _mm_setzero_si128() #define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0x) #else #define VECTYPEunsigned long #define SPLAT(p) (*(p) * (~0UL / 255)) +#define ZERO_SPLAT 0x0UL #define ALL_EQ(v1, v2) ((v1) == (v2)) #endif C trivia of the day: this can be written simply as (VECTYPE) {0} you are the first who mentions this ;-) respin? Peter
Re: [Qemu-devel] [PATCHv5 02/10] add a zero splat vector to qemu-common.h
Il 26/03/2013 11:17, Peter Lieven ha scritto: C trivia of the day: this can be written simply as (VECTYPE) {0} you are the first who mentions this ;-) respin? Yes, please. Paolo
Re: [Qemu-devel] [PATCHv5 02/10] add a zero splat vector to qemu-common.h
Am 26.03.2013 um 11:17 schrieb Paolo Bonzini pbonz...@redhat.com: Il 26/03/2013 11:17, Peter Lieven ha scritto: C trivia of the day: this can be written simply as (VECTYPE) {0} you are the first who mentions this ;-) respin? Yes, please. Ok, I wait if someone finds something else. Peter Paolo
[Qemu-devel] [PATCH v2 11/11] hw/versatile_pci: Drop unnecessary vpb_pci_config_addr()
Drop the vpb_pci_config_addr() function -- it is unnecessary since the size of the memory regions means the hwaddr is always within the 24 bit size. (This function was probably a leftover from when read/write functions were called with absolute addresses rather than relative ones.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/versatile_pci.c |9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 1575dd7..20092fe 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -192,11 +192,6 @@ static const MemoryRegionOps pci_vpb_reg_ops = { }, }; -static inline uint32_t vpb_pci_config_addr(hwaddr addr) -{ -return addr 0xff; -} - static void pci_vpb_config_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -222,7 +217,7 @@ static void pci_vpb_config_write(void *opaque, hwaddr addr, } } } -pci_data_write(s-pci_bus, vpb_pci_config_addr(addr), val, size); +pci_data_write(s-pci_bus, addr, val, size); } static uint64_t pci_vpb_config_read(void *opaque, hwaddr addr, @@ -230,7 +225,7 @@ static uint64_t pci_vpb_config_read(void *opaque, hwaddr addr, { PCIVPBState *s = (PCIVPBState *)opaque; uint32_t val; -val = pci_data_read(s-pci_bus, vpb_pci_config_addr(addr), size); +val = pci_data_read(s-pci_bus, addr, size); return val; } -- 1.7.9.5
[Qemu-devel] [PATCH v2 10/11] versatile_pci: Expose PCI memory space to system
The VersatilePB's PCI controller exposes the PCI memory space to the system via three regions controlled by the mapping control registers. Implement this so that guests can actually use MMIO-BAR PCI cards. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/arm/realview.c|3 +++ hw/arm/versatilepb.c |3 +++ hw/versatile_pci.c | 72 +- 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/hw/arm/realview.c b/hw/arm/realview.c index 23c968b..db41525 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -221,6 +221,9 @@ static void realview_init(QEMUMachineInitArgs *args, sysbus_mmio_map(busdev, 1, 0x6000); /* PCI self-config */ sysbus_mmio_map(busdev, 2, 0x6100); /* PCI config */ sysbus_mmio_map(busdev, 3, 0x6200); /* PCI I/O */ +sysbus_mmio_map(busdev, 4, 0x6300); /* PCI memory window 1 */ +sysbus_mmio_map(busdev, 5, 0x6400); /* PCI memory window 2 */ +sysbus_mmio_map(busdev, 6, 0x6800); /* PCI memory window 3 */ sysbus_connect_irq(busdev, 0, pic[48]); sysbus_connect_irq(busdev, 1, pic[49]); sysbus_connect_irq(busdev, 2, pic[50]); diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index 9c9bfde..413f0e9 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -228,6 +228,9 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id) sysbus_mmio_map(busdev, 1, 0x4100); /* PCI self-config */ sysbus_mmio_map(busdev, 2, 0x4200); /* PCI config */ sysbus_mmio_map(busdev, 3, 0x4300); /* PCI I/O */ +sysbus_mmio_map(busdev, 4, 0x4400); /* PCI memory window 1 */ +sysbus_mmio_map(busdev, 5, 0x5000); /* PCI memory window 2 */ +sysbus_mmio_map(busdev, 6, 0x6000); /* PCI memory window 3 */ sysbus_connect_irq(busdev, 0, sic[27]); sysbus_connect_irq(busdev, 1, sic[28]); sysbus_connect_irq(busdev, 2, sic[29]); diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index a598b64..1575dd7 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -20,13 +20,20 @@ typedef struct { MemoryRegion controlregs; MemoryRegion mem_config; MemoryRegion mem_config2; +/* Containers representing the PCI address spaces */ MemoryRegion pci_io_space; +MemoryRegion pci_mem_space; +/* Alias regions into PCI address spaces which we expose as sysbus regions. + * The offsets into pci_mem_space are controlled by the imap registers. + */ MemoryRegion pci_io_window; +MemoryRegion pci_mem_window[3]; PCIBus pci_bus; PCIDevice pci_dev; /* Constant for life of device: */ int realview; +uint32_t mem_win_size[3]; /* Variable state: */ uint32_t imap[3]; @@ -36,10 +43,49 @@ typedef struct { bool broken_irq_mapping; } PCIVPBState; +static void pci_vpb_update_window(PCIVPBState *s, int i) +{ +/* Adjust the offset of the alias region we use for + * the memory window i to account for a change in the + * value of the corresponding IMAP register. + * Note that the semantics of the IMAP register differ + * for realview and versatile variants of the controller. + */ +hwaddr offset; +if (s-realview) { +/* Top bits of register (masked according to window size) provide + * top bits of PCI address. + */ +offset = s-imap[i] ~(s-mem_win_size[i] - 1); +} else { +/* Bottom 4 bits of register provide top 4 bits of PCI address */ +offset = s-imap[i] 28; +} +memory_region_set_alias_offset(s-pci_mem_window[i], offset); +} + +static void pci_vpb_update_all_windows(PCIVPBState *s) +{ +/* Update all alias windows based on the current register state */ +int i; + +for (i = 0; i 3; i++) { +pci_vpb_update_window(s, i); +} +} + +static int pci_vpb_post_load(void *opaque, int version_id) +{ +PCIVPBState *s = opaque; +pci_vpb_update_all_windows(s); +return 0; +} + static const VMStateDescription pci_vpb_vmstate = { .name = versatile-pci, .version_id = 1, .minimum_version_id = 1, +.post_load = pci_vpb_post_load, .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(imap, PCIVPBState, 3), VMSTATE_UINT32_ARRAY(smap, PCIVPBState, 3), @@ -81,6 +127,7 @@ static void pci_vpb_reg_write(void *opaque, hwaddr addr, { int win = (addr - PCI_IMAP0) 2; s-imap[win] = val; +pci_vpb_update_window(s, win); break; } case PCI_SELFID: @@ -257,6 +304,8 @@ static void pci_vpb_reset(DeviceState *d) s-smap[2] = 0; s-selfid = 0; s-flags = 0; + +pci_vpb_update_all_windows(s); } static void pci_vpb_init(Object *obj) @@ -265,9 +314,10 @@ static void pci_vpb_init(Object *obj) PCIVPBState *s = PCI_VPB(obj); memory_region_init(s-pci_io_space, pci_io, 1ULL 32); +
Re: [Qemu-devel] [PATCHv5 03/10] cutils: add a function to find non-zero content in a buffer
Peter Lieven p...@kamp.de wrote: this adds buffer_find_nonzero_offset() which is a SSE2/Altivec optimized function that searches for non-zero content in a buffer. the function starts full unrolling only after the first few chunks have been checked one by one. analyzing real memory page data has revealed that non-zero pages are non-zero within the first 256-512 bits in most cases. as this function is also heavily used to check for zero memory pages this tweak has been made to avoid the high setup costs of the fully unrolled check for non-zero pages. due to the optimizations used in the function there are restrictions on buffer address and search length. the function can_use_buffer_find_nonzero_content() can be used to check if the function can be used safely. Signed-off-by: Peter Lieven p...@kamp.de --- include/qemu-common.h | 13 util/cutils.c | 55 + 2 files changed, 68 insertions(+) diff --git a/include/qemu-common.h b/include/qemu-common.h index 9022646..7c7c244 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -472,4 +472,17 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #define ALL_EQ(v1, v2) ((v1) == (v2)) #endif +#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8 +static inline bool +can_use_buffer_find_nonzero_offset(const void *buf, size_t len) +{ +if (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR + * sizeof(VECTYPE)) == 0 + ((uintptr_t) buf) % sizeof(VECTYPE) == 0) { +return true; +} +return false; +} +size_t buffer_find_nonzero_offset(const void *buf, size_t len); + #endif diff --git a/util/cutils.c b/util/cutils.c index 1439da4..0314a18 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -143,6 +143,61 @@ int qemu_fdatasync(int fd) } /* + * Searches for an area with non-zero content in a buffer + * + * Attention! The len must be a multiple of + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE) + * and addr must be a multiple of sizeof(VECTYPE) due to + * restriction of optimizations in this function. + * + * can_use_buffer_find_nonzero_offset() can be used to check + * these requirements. + * + * The return value is the offset of the non-zero area rounded + * down to a multiple of sizeof(VECTYPE) for the first + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR chunks and down to + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE) + * afterwards. + * + * If the buffer is all zero the return value is equal to len. + */ + +size_t buffer_find_nonzero_offset(const void *buf, size_t len) +{ +VECTYPE *p = (VECTYPE *)buf; +VECTYPE zero = ZERO_SPLAT; If you have to resplit it anyways, what about changing this to: -VECTYPE *p = (VECTYPE *)buf; -VECTYPE zero = ZERO_SPLAT; +const VECTYPE *p = buf; +const VECTYPE zero = ZERO_SPLAT; size_t i; From the I hate casts film? Thanks, Juan.
[Qemu-devel] [PATCH v3] block: Add support for Secure Shell (ssh) block device.
From: Richard W.M. Jones rjo...@redhat.com qemu-system-x86_64 -drive file=ssh://hostname/some/image QEMU will ssh into 'hostname' and open '/some/image' which is made available as a standard block device. You can specify a username (ssh://user@host/...) and/or a port number (ssh://host:port/...). Current limitations: - Authentication must be done without passwords or passphrases, using ssh-agent. Other authentication methods are not supported. (*) - New remote files cannot be created. (*) - Uses a single connection, instead of concurrent AIO with multiple SSH connections. (*) = potentially easy fix This is implemented using libssh2 on the client side. The server just requires a regular ssh daemon with sftp-server support. Most ssh daemons on Unix/Linux systems will work out of the box. Thanks: Stefan Hajnoczi, Kevin Wolf. --- block/Makefile.objs | 1 + block/ssh.c | 750 configure | 47 qemu-doc.texi | 40 +++ qemu-options.hx | 12 + 5 files changed, 850 insertions(+) create mode 100644 block/ssh.c diff --git a/block/Makefile.objs b/block/Makefile.objs index c067f38..6c4b5bc 100644 --- a/block/Makefile.objs +++ b/block/Makefile.objs @@ -13,6 +13,7 @@ block-obj-$(CONFIG_LIBISCSI) += iscsi.o block-obj-$(CONFIG_CURL) += curl.o block-obj-$(CONFIG_RBD) += rbd.o block-obj-$(CONFIG_GLUSTERFS) += gluster.o +block-obj-$(CONFIG_LIBSSH2) += ssh.o endif common-obj-y += stream.o diff --git a/block/ssh.c b/block/ssh.c new file mode 100644 index 000..f7b8d32 --- /dev/null +++ b/block/ssh.c @@ -0,0 +1,750 @@ +/* + * Secure Shell (ssh) backend for QEMU. + * + * Copyright (C) 2013 Red Hat Inc., Richard W.M. Jones rjo...@redhat.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include stdio.h +#include stdlib.h +#include stdarg.h + +#ifndef _WIN32 +#include pwd.h +#endif + +#include libssh2.h +#include libssh2_sftp.h + +#include block/block_int.h +#include qemu/sockets.h +#include qemu/uri.h +#include qapi/qmp/qint.h + +#define DEBUG_SSH 1 + +#if DEBUG_SSH +#define DPRINTF(fmt,...)\ +do {\ +fprintf(stderr, ssh: %-15s fmt \n, __func__, ##__VA_ARGS__); \ +} while (0) +#else +#define DPRINTF(fmt,...) /* nothing */ +#endif + +typedef struct BDRVSSHState { +CoMutex lock; /* coroutine lock */ + +/* ssh connection */ +int sock; /* socket */ +LIBSSH2_SESSION *session; /* ssh session */ +LIBSSH2_SFTP *sftp; /* sftp session */ +LIBSSH2_SFTP_HANDLE *sftp_handle; /* sftp remote file handle */ + +/* file attributes (at open) */ +LIBSSH2_SFTP_ATTRIBUTES attrs; +} BDRVSSHState; + +/* Wrappers around error_report which make sure to dump as much + * information from libssh2 as possible. + */ +static void +session_error_report(BDRVSSHState *s, const char *fs, ...) +{ +va_list args; + +va_start(args, fs); + +if ((s)-session) { +char *ssh_err; +int ssh_err_len = sizeof ssh_err; +int ssh_err_code; + +libssh2_session_last_error((s)-session, + ssh_err, ssh_err_len, 0); +/* This is not an errno. See libssh2.h. */ +ssh_err_code = libssh2_session_last_errno((s)-session); + +error_vprintf(fs, args); +error_printf(: %s (libssh2 error code: %d), ssh_err, ssh_err_code); +} +else { +error_vprintf(fs, args); +} + +va_end(args); +error_printf(\n); +} + +static void +sftp_error_report(BDRVSSHState *s, const char *fs, ...) +{ +va_list args; + +va_start(args, fs); + +if ((s)-sftp) { +char *ssh_err; +int ssh_err_len = sizeof ssh_err; +int ssh_err_code; +unsigned long sftp_err_code; + +
Re: [Qemu-devel] [PATCH v2] block: Add support for Secure Shell (ssh) block device.
Thanks -- I've included all feedback up to this point in version 3, which I'll post in a moment. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming blog: http://rwmj.wordpress.com Fedora now supports 80 OCaml packages (the OPEN alternative to F#)
Re: [Qemu-devel] [PATCHv5 03/10] cutils: add a function to find non-zero content in a buffer
Peter Lieven p...@kamp.de wrote: this adds buffer_find_nonzero_offset() which is a SSE2/Altivec optimized function that searches for non-zero content in a buffer. the function starts full unrolling only after the first few chunks have been checked one by one. analyzing real memory page data has revealed that non-zero pages are non-zero within the first 256-512 bits in most cases. as this function is also heavily used to check for zero memory pages this tweak has been made to avoid the high setup costs of the fully unrolled check for non-zero pages. due to the optimizations used in the function there are restrictions on buffer address and search length. the function can_use_buffer_find_nonzero_content() can be used to check if the function can be used safely. Signed-off-by: Peter Lieven p...@kamp.de --- include/qemu-common.h | 13 util/cutils.c | 55 + 2 files changed, 68 insertions(+) diff --git a/include/qemu-common.h b/include/qemu-common.h index 9022646..7c7c244 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -472,4 +472,17 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #define ALL_EQ(v1, v2) ((v1) == (v2)) #endif +#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8 +static inline bool +can_use_buffer_find_nonzero_offset(const void *buf, size_t len) +{ +if (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR + * sizeof(VECTYPE)) == 0 + ((uintptr_t) buf) % sizeof(VECTYPE) == 0) { +return true; +} +return false; +} This can be spelled as: return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE)) == 0 ((uintptr_t) buf) % sizeof(VECTYPE) == 0);; But I don't care too much.
Re: [Qemu-devel] [PATCHv5 03/10] cutils: add a function to find non-zero content in a buffer
Am 26.03.2013 um 11:38 schrieb Juan Quintela quint...@redhat.com: Peter Lieven p...@kamp.de wrote: this adds buffer_find_nonzero_offset() which is a SSE2/Altivec optimized function that searches for non-zero content in a buffer. the function starts full unrolling only after the first few chunks have been checked one by one. analyzing real memory page data has revealed that non-zero pages are non-zero within the first 256-512 bits in most cases. as this function is also heavily used to check for zero memory pages this tweak has been made to avoid the high setup costs of the fully unrolled check for non-zero pages. due to the optimizations used in the function there are restrictions on buffer address and search length. the function can_use_buffer_find_nonzero_content() can be used to check if the function can be used safely. Signed-off-by: Peter Lieven p...@kamp.de --- include/qemu-common.h | 13 util/cutils.c | 55 + 2 files changed, 68 insertions(+) diff --git a/include/qemu-common.h b/include/qemu-common.h index 9022646..7c7c244 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -472,4 +472,17 @@ void hexdump(const char *buf, FILE *fp, const char *prefix, size_t size); #define ALL_EQ(v1, v2) ((v1) == (v2)) #endif +#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8 +static inline bool +can_use_buffer_find_nonzero_offset(const void *buf, size_t len) +{ +if (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR + * sizeof(VECTYPE)) == 0 + ((uintptr_t) buf) % sizeof(VECTYPE) == 0) { +return true; +} +return false; +} +size_t buffer_find_nonzero_offset(const void *buf, size_t len); + #endif diff --git a/util/cutils.c b/util/cutils.c index 1439da4..0314a18 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -143,6 +143,61 @@ int qemu_fdatasync(int fd) } /* + * Searches for an area with non-zero content in a buffer + * + * Attention! The len must be a multiple of + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE) + * and addr must be a multiple of sizeof(VECTYPE) due to + * restriction of optimizations in this function. + * + * can_use_buffer_find_nonzero_offset() can be used to check + * these requirements. + * + * The return value is the offset of the non-zero area rounded + * down to a multiple of sizeof(VECTYPE) for the first + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR chunks and down to + * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE) + * afterwards. + * + * If the buffer is all zero the return value is equal to len. + */ + +size_t buffer_find_nonzero_offset(const void *buf, size_t len) +{ +VECTYPE *p = (VECTYPE *)buf; +VECTYPE zero = ZERO_SPLAT; If you have to resplit it anyways, what about changing this to: -VECTYPE *p = (VECTYPE *)buf; -VECTYPE zero = ZERO_SPLAT; +const VECTYPE *p = buf; +const VECTYPE zero = ZERO_SPLAT; i would change it to const VECTYPE zero = (VECTYPE) {0}; and drop patch 2 again. Peter size_t i; From the I hate casts film? Thanks, Juan.
[Qemu-devel] [PATCH v2 09/11] arm/realview: Fix mapping of PCI regions
Fix the mapping of the PCI regions for the realview board, which were all incorrect. (This was never noticed because the Linux kernel doesn't actually include a PCI driver for the realview boards.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/arm/realview.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hw/arm/realview.c b/hw/arm/realview.c index ba61d18..23c968b 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -218,9 +218,9 @@ static void realview_init(QEMUMachineInitArgs *args, busdev = SYS_BUS_DEVICE(dev); qdev_init_nofail(dev); sysbus_mmio_map(busdev, 0, 0x10019000); /* PCI controller registers */ -sysbus_mmio_map(busdev, 1, 0x6100); /* PCI self-config */ -sysbus_mmio_map(busdev, 2, 0x6200); /* PCI config */ -sysbus_mmio_map(busdev, 3, 0x6300); /* PCI I/O */ +sysbus_mmio_map(busdev, 1, 0x6000); /* PCI self-config */ +sysbus_mmio_map(busdev, 2, 0x6100); /* PCI config */ +sysbus_mmio_map(busdev, 3, 0x6200); /* PCI I/O */ sysbus_connect_irq(busdev, 0, pic[48]); sysbus_connect_irq(busdev, 1, pic[49]); sysbus_connect_irq(busdev, 2, pic[50]); @@ -304,12 +304,12 @@ static void realview_init(QEMUMachineInitArgs *args, /* 0x5800 PISMO. */ /* 0x5c00 PISMO. */ /* 0x6000 PCI. */ -/* 0x6100 PCI Self Config. */ -/* 0x6200 PCI Config. */ -/* 0x6300 PCI IO. */ -/* 0x6400 PCI mem 0. */ -/* 0x6800 PCI mem 1. */ -/* 0x6c00 PCI mem 2. */ +/* 0x6000 PCI Self Config. */ +/* 0x6100 PCI Config. */ +/* 0x6200 PCI IO. */ +/* 0x6300 PCI mem 0. */ +/* 0x6400 PCI mem 1. */ +/* 0x6800 PCI mem 2. */ /* ??? Hack to map an additional page of ram for the secondary CPU startup code. I guess this works on real hardware because the -- 1.7.9.5
[Qemu-devel] [PATCH v2 06/11] versatile_pci: Put the host bridge PCI device at slot 29
On real hardware the host bridge appears as a PCI device in slot 29, so make QEMU put its host bridge in that slot too. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/versatile_pci.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 777e9b1..576e619 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -87,6 +87,8 @@ static void pci_vpb_init(Object *obj) object_initialize(s-pci_dev, TYPE_VERSATILE_PCI_HOST); qdev_set_parent_bus(DEVICE(s-pci_dev), BUS(s-pci_bus)); +object_property_set_int(OBJECT(s-pci_dev), PCI_DEVFN(29, 0), addr, +NULL); } static void pci_vpb_realize(DeviceState *dev, Error **errp) -- 1.7.9.5
[Qemu-devel] [PATCH v2 05/11] versatile_pci: Use separate PCI I/O space rather than system I/O space
Rather than overloading the system I/O space (which doesn't even make any sense on ARM) for PCI I/O, create an memory region in the PCI controller and use that to represent the I/O space. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/versatile_pci.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index dfd3001..777e9b1 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -19,7 +19,8 @@ typedef struct { qemu_irq irq[4]; MemoryRegion mem_config; MemoryRegion mem_config2; -MemoryRegion isa; +MemoryRegion pci_io_space; +MemoryRegion pci_io_window; PCIBus pci_bus; PCIDevice pci_dev; @@ -77,8 +78,10 @@ static void pci_vpb_init(Object *obj) PCIHostState *h = PCI_HOST_BRIDGE(obj); PCIVPBState *s = PCI_VPB(obj); +memory_region_init(s-pci_io_space, pci_io, 1ULL 32); + pci_bus_new_inplace(s-pci_bus, DEVICE(obj), pci, -get_system_memory(), get_system_io(), +get_system_memory(), s-pci_io_space, PCI_DEVFN(11, 0)); h-bus = s-pci_bus; @@ -111,8 +114,14 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp) memory_region_init_io(s-mem_config2, pci_vpb_config_ops, s-pci_bus, pci-vpb-config, 0x100); sysbus_init_mmio(sbd, s-mem_config2); -isa_mmio_setup(s-isa, 0x010); -sysbus_init_mmio(sbd, s-isa); + +/* The window into I/O space is always into a fixed base address; + * its size is the same for both realview and versatile. + */ +memory_region_init_alias(s-pci_io_window, pci-vbp-io-window, + s-pci_io_space, 0, 0x10); + +sysbus_init_mmio(sbd, s-pci_io_space); /* TODO Remove once realize propagates to child devices. */ object_property_set_bool(OBJECT(s-pci_dev), true, realized, errp); -- 1.7.9.5
[Qemu-devel] [PATCH v2 01/11] versatile_pci: Fix hardcoded tabs
There is just one line in this source file with a hardcoded tab indent, so just fix it. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/versatile_pci.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 0b97a40..16ce5d1 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -104,7 +104,7 @@ static int pci_realview_init(SysBusDevice *dev) static int versatile_pci_host_init(PCIDevice *d) { pci_set_word(d-config + PCI_STATUS, -PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); + PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); pci_set_byte(d-config + PCI_LATENCY_TIMER, 0x10); return 0; } -- 1.7.9.5
[Qemu-devel] [PATCH v2 02/11] versatile_pci: Expose PCI I/O region on Versatile PB
Comments in the QEMU source code claim that the version of the PCI controller on the VersatilePB board doesn't support the PCI I/O region, but this is incorrect; expose that region, map it in the correct location, and drop the misleading comments. This change removes the only currently implemented difference between the realview-pci and versatile-pci models; however there are other differences in not-yet-implemented functionality, so we retain the distinction between the two device types. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/arm/versatilepb.c |3 +-- hw/versatile_pci.c |8 +++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index baaa265..0d08d15 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -226,14 +226,13 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id) qdev_init_nofail(dev); sysbus_mmio_map(busdev, 0, 0x4100); /* PCI self-config */ sysbus_mmio_map(busdev, 1, 0x4200); /* PCI config */ +sysbus_mmio_map(busdev, 2, 0x4300); /* PCI I/O */ sysbus_connect_irq(busdev, 0, sic[27]); sysbus_connect_irq(busdev, 1, sic[28]); sysbus_connect_irq(busdev, 2, sic[29]); sysbus_connect_irq(busdev, 3, sic[30]); pci_bus = (PCIBus *)qdev_get_child_bus(dev, pci); -/* The Versatile PCI bridge does not provide access to PCI IO space, - so many of the qemu PCI devices are not useable. */ for(n = 0; n nb_nics; n++) { nd = nd_table[n]; diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 16ce5d1..1312f46 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -77,7 +77,7 @@ static int pci_vpb_init(SysBusDevice *dev) /* Our memory regions are: * 0 : PCI self config window * 1 : PCI config window - * 2 : PCI IO window (realview_pci only) + * 2 : PCI IO window */ memory_region_init_io(s-mem_config, pci_vpb_config_ops, bus, pci-vpb-selfconfig, 0x100); @@ -85,10 +85,8 @@ static int pci_vpb_init(SysBusDevice *dev) memory_region_init_io(s-mem_config2, pci_vpb_config_ops, bus, pci-vpb-config, 0x100); sysbus_init_mmio(dev, s-mem_config2); -if (s-realview) { -isa_mmio_setup(s-isa, 0x010); -sysbus_init_mmio(dev, s-isa); -} +isa_mmio_setup(s-isa, 0x010); +sysbus_init_mmio(dev, s-isa); pci_create_simple(bus, -1, versatile_pci_host); return 0; -- 1.7.9.5
[Qemu-devel] [PATCH v2 07/11] versatile_pci: Implement the correct PCI IRQ mapping
Implement the correct IRQ mapping for the Versatile PCI controller; it differs between realview and versatile boards, but the previous QEMU implementation was correct only for the first PCI card on a versatile board, since we weren't swizzling IRQs based on the slot number. Since this change would otherwise break any uses of PCI on Linux kernels which have an equivalent bug (since they have effectively only been tested against QEMU, not real hardware), we implement a mechanism for automatically detecting those broken kernels and switching back to the old mapping. This works by looking at the values the kernel writes to the PCI_INTERRUPT_LINE register in the config space, which is effectively the interrupt number the kernel expects the device to be using. If this doesn't match reality we use the broken mapping. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/versatile_pci.c | 85 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 576e619..1b56796 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -26,6 +26,9 @@ typedef struct { /* Constant for life of device: */ int realview; + +/* Variable state: */ +bool broken_irq_mapping; } PCIVPBState; #define TYPE_VERSATILE_PCI versatile_pci @@ -44,14 +47,37 @@ static inline uint32_t vpb_pci_config_addr(hwaddr addr) static void pci_vpb_config_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { -pci_data_write(opaque, vpb_pci_config_addr(addr), val, size); +/* Old and buggy versions of QEMU used the wrong mapping from + * PCI IRQs to system interrupt lines. Unfortunately the Linux + * kernel also had the corresponding bug in setting up interrupts + * (so older kernels work on QEMU and not on real hardware). + * We automatically detect these broken kernels and flip back + * to the broken irq mapping by spotting guest writes to the + * PCI_INTERRUPT_LINE register to see where the guest thinks + * interrupts are going to be routed. + * We allow arbitrary flipping between broken and non broken + * to permit corner cases like kexec between two kernels. + */ +PCIVPBState *s = (PCIVPBState *)opaque; +if (!s-realview (addr 0xff) == PCI_INTERRUPT_LINE) { +uint8_t devfn = addr 8; +if ((PCI_SLOT(devfn) % PCI_NUM_PINS) != 2) { +if (val == 27) { +s-broken_irq_mapping = true; +} else { +s-broken_irq_mapping = false; +} +} +} +pci_data_write(s-pci_bus, vpb_pci_config_addr(addr), val, size); } static uint64_t pci_vpb_config_read(void *opaque, hwaddr addr, unsigned size) { +PCIVPBState *s = (PCIVPBState *)opaque; uint32_t val; -val = pci_data_read(opaque, vpb_pci_config_addr(addr), size); +val = pci_data_read(s-pci_bus, vpb_pci_config_addr(addr), size); return val; } @@ -63,7 +89,47 @@ static const MemoryRegionOps pci_vpb_config_ops = { static int pci_vpb_map_irq(PCIDevice *d, int irq_num) { -return irq_num; +PCIVPBState *s = container_of(d-bus, PCIVPBState, pci_bus); + +if (s-broken_irq_mapping) { +/* Legacy broken IRQ mapping for compatibility with old and + * buggy Linux guests + */ +return irq_num; +} + +/* Slot to IRQ mapping for RealView Platform Baseboard 926 backplane + * nameslotIntAIntBIntCIntD + * A 31 IRQ28 IRQ29 IRQ30 IRQ27 + * B 30 IRQ27 IRQ28 IRQ29 IRQ30 + * C 29 IRQ30 IRQ27 IRQ28 IRQ29 + * Slot C is for the host bridge; A and B the peripherals. + * Our output irqs 0..3 correspond to the baseboard's 27..30. + * + * This mapping function takes account of an oddity in the PB926 + * board wiring, where the FPGA's P_nINTA input is connected to + * the INTB connection on the board PCI edge connector, P_nINTB + * is connected to INTC, and so on, so everything is one number + * further round from where you might expect. + */ +return pci_swizzle_map_irq_fn(d, irq_num + 2); +} + +static int pci_vpb_rv_map_irq(PCIDevice *d, int irq_num) +{ +/* Slot to IRQ mapping for RealView EB and PB1176 backplane + * nameslotIntAIntBIntCIntD + * A 31 IRQ50 IRQ51 IRQ48 IRQ49 + * B 30 IRQ49 IRQ50 IRQ51 IRQ48 + * C 29 IRQ48 IRQ49 IRQ50 IRQ51 + * Slot C is for the host bridge; A and B the peripherals. + * Our output irqs 0..3 correspond to the baseboard's 48..51. + * + * The PB1176 and EB boards don't have the PB926 wiring oddity + * described above; P_nINTA connects to INTA, P_nINTB to INTB + * and so on, which is why this mapping
[Qemu-devel] [PATCH v2 03/11] versatile_pci: Update to realize and instance init functions
Update the Versatile PCI controller to use a realize function rather than SysBusDevice::init. To reflect the fact that the 'realview_pci' class is taking most of its implementation from 'versatile_pci' (and to make the QOM casts work) we make 'realview_pci' a subclass of 'versatile_pci'. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/versatile_pci.c | 50 +- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 1312f46..541f6b5 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -21,6 +21,14 @@ typedef struct { MemoryRegion isa; } PCIVPBState; +#define TYPE_VERSATILE_PCI versatile_pci +#define PCI_VPB(obj) \ +OBJECT_CHECK(PCIVPBState, (obj), TYPE_VERSATILE_PCI) + +#define TYPE_VERSATILE_PCI_HOST versatile_pci_host +#define PCI_VPB_HOST(obj) \ +OBJECT_CHECK(PCIDevice, (obj), TYPE_VERSATILE_PCIHOST) + static inline uint32_t vpb_pci_config_addr(hwaddr addr) { return addr 0xff; @@ -58,16 +66,17 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[irq_num], level); } -static int pci_vpb_init(SysBusDevice *dev) +static void pci_vpb_realize(DeviceState *dev, Error **errp) { -PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); +PCIVPBState *s = PCI_VPB(dev); +SysBusDevice *sbd = SYS_BUS_DEVICE(dev); PCIBus *bus; int i; for (i = 0; i 4; i++) { -sysbus_init_irq(dev, s-irq[i]); +sysbus_init_irq(sbd, s-irq[i]); } -bus = pci_register_bus(dev-qdev, pci, +bus = pci_register_bus(dev, pci, pci_vpb_set_irq, pci_vpb_map_irq, s-irq, get_system_memory(), get_system_io(), PCI_DEVFN(11, 0), 4); @@ -81,22 +90,14 @@ static int pci_vpb_init(SysBusDevice *dev) */ memory_region_init_io(s-mem_config, pci_vpb_config_ops, bus, pci-vpb-selfconfig, 0x100); -sysbus_init_mmio(dev, s-mem_config); +sysbus_init_mmio(sbd, s-mem_config); memory_region_init_io(s-mem_config2, pci_vpb_config_ops, bus, pci-vpb-config, 0x100); -sysbus_init_mmio(dev, s-mem_config2); +sysbus_init_mmio(sbd, s-mem_config2); isa_mmio_setup(s-isa, 0x010); -sysbus_init_mmio(dev, s-isa); +sysbus_init_mmio(sbd, s-isa); pci_create_simple(bus, -1, versatile_pci_host); -return 0; -} - -static int pci_realview_init(SysBusDevice *dev) -{ -PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); -s-realview = 1; -return pci_vpb_init(dev); } static int versatile_pci_host_init(PCIDevice *d) @@ -118,7 +119,7 @@ static void versatile_pci_host_class_init(ObjectClass *klass, void *data) } static const TypeInfo versatile_pci_host_info = { -.name = versatile_pci_host, +.name = TYPE_VERSATILE_PCI_HOST, .parent= TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init= versatile_pci_host_class_init, @@ -126,30 +127,29 @@ static const TypeInfo versatile_pci_host_info = { static void pci_vpb_class_init(ObjectClass *klass, void *data) { -SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); +DeviceClass *dc = DEVICE_CLASS(klass); -sdc-init = pci_vpb_init; +dc-realize = pci_vpb_realize; } static const TypeInfo pci_vpb_info = { -.name = versatile_pci, +.name = TYPE_VERSATILE_PCI, .parent= TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(PCIVPBState), .class_init= pci_vpb_class_init, }; -static void pci_realview_class_init(ObjectClass *klass, void *data) +static void pci_realview_init(Object *obj) { -SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); +PCIVPBState *s = PCI_VPB(obj); -sdc-init = pci_realview_init; +s-realview = 1; } static const TypeInfo pci_realview_info = { .name = realview_pci, -.parent= TYPE_SYS_BUS_DEVICE, -.instance_size = sizeof(PCIVPBState), -.class_init= pci_realview_class_init, +.parent= TYPE_VERSATILE_PCI, +.instance_init = pci_realview_init, }; static void versatile_pci_register_types(void) -- 1.7.9.5
[Qemu-devel] [PATCH v2 04/11] versatile_pci: Change to subclassing TYPE_PCI_HOST_BRIDGE
Change versatile_pci to subclass TYPE_PCI_HOST_BRIDGE and generally handle PCI in a more QOM-like fashion. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/versatile_pci.c | 41 ++--- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 541f6b5..dfd3001 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -9,16 +9,22 @@ #include hw/sysbus.h #include hw/pci/pci.h +#include hw/pci/pci_bus.h #include hw/pci/pci_host.h #include exec/address-spaces.h typedef struct { -SysBusDevice busdev; +PCIHostState parent_obj; + qemu_irq irq[4]; -int realview; MemoryRegion mem_config; MemoryRegion mem_config2; MemoryRegion isa; +PCIBus pci_bus; +PCIDevice pci_dev; + +/* Constant for life of device: */ +int realview; } PCIVPBState; #define TYPE_VERSATILE_PCI versatile_pci @@ -66,20 +72,31 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[irq_num], level); } +static void pci_vpb_init(Object *obj) +{ +PCIHostState *h = PCI_HOST_BRIDGE(obj); +PCIVPBState *s = PCI_VPB(obj); + +pci_bus_new_inplace(s-pci_bus, DEVICE(obj), pci, +get_system_memory(), get_system_io(), +PCI_DEVFN(11, 0)); +h-bus = s-pci_bus; + +object_initialize(s-pci_dev, TYPE_VERSATILE_PCI_HOST); +qdev_set_parent_bus(DEVICE(s-pci_dev), BUS(s-pci_bus)); +} + static void pci_vpb_realize(DeviceState *dev, Error **errp) { PCIVPBState *s = PCI_VPB(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); -PCIBus *bus; int i; for (i = 0; i 4; i++) { sysbus_init_irq(sbd, s-irq[i]); } -bus = pci_register_bus(dev, pci, - pci_vpb_set_irq, pci_vpb_map_irq, s-irq, - get_system_memory(), get_system_io(), - PCI_DEVFN(11, 0), 4); + +pci_bus_irqs(s-pci_bus, pci_vpb_set_irq, pci_vpb_map_irq, s-irq, 4); /* ??? Register memory space. */ @@ -88,16 +105,17 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp) * 1 : PCI config window * 2 : PCI IO window */ -memory_region_init_io(s-mem_config, pci_vpb_config_ops, bus, +memory_region_init_io(s-mem_config, pci_vpb_config_ops, s-pci_bus, pci-vpb-selfconfig, 0x100); sysbus_init_mmio(sbd, s-mem_config); -memory_region_init_io(s-mem_config2, pci_vpb_config_ops, bus, +memory_region_init_io(s-mem_config2, pci_vpb_config_ops, s-pci_bus, pci-vpb-config, 0x100); sysbus_init_mmio(sbd, s-mem_config2); isa_mmio_setup(s-isa, 0x010); sysbus_init_mmio(sbd, s-isa); -pci_create_simple(bus, -1, versatile_pci_host); +/* TODO Remove once realize propagates to child devices. */ +object_property_set_bool(OBJECT(s-pci_dev), true, realized, errp); } static int versatile_pci_host_init(PCIDevice *d) @@ -134,8 +152,9 @@ static void pci_vpb_class_init(ObjectClass *klass, void *data) static const TypeInfo pci_vpb_info = { .name = TYPE_VERSATILE_PCI, -.parent= TYPE_SYS_BUS_DEVICE, +.parent= TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(PCIVPBState), +.instance_init = pci_vpb_init, .class_init= pci_vpb_class_init, }; -- 1.7.9.5
[Qemu-devel] [PATCH v2 00/11] Fix versatile_pci (now without breaking linux)
This patch series fixes a number of serious bugs in our emulation of the PCI controller found on VersatilePB and the early Realview boards: * our interrupt mapping was totally wrong * we weren't implementing the PCI memory windows * the I/O window wasn't mapped on VersatilePB * realview mapped things at the wrong addresses * we didn't implement the controller's registers at all It also updates to some reasonable approximation to QOM best practice, including subclassing pci_host rather than doing everything by hand. I haven't implemented support for the SMAP registers (which control how the controller converts accesses made by bus-mastering PCI devices into system addresses). For the moment we rely on the fact that Linux always maps things 1:1. (It wouldn't be too hard to add SMAP support but it requires changing QEMU's pci code to allow a controller to pass in a MemoryRegion* for DMA to use instead of the system address space, so I prefer to leave that for another series.) Patchset tested on both versatilepb and realview, using a set of Linux kernel patches written by Arnd Bergmann: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-October/029040.html which were in turn tested against real PB926 and PB1176 hardware. This version of the patchset avoids breaking legacy Linux guests by automatically detecting those broken kernels and switching back to the old mapping. This works by looking at the values the kernel writes to the PCI_INTERRUPT_LINE register in the config space, which is effectively the interrupt number the kernel expects the device to be using. If this doesn't match reality we use the broken mapping. (Thanks to Michael S. Tsirkin for this suggestion.) I haven't included any mechanism for forcing this autodetection off. Changes v1-v2: * autodetect broken guests rather than using user-set property * use pci_swizzle_map_fn * new patch: drop unnecessary vpb_pci_config_addr() function Peter Maydell (11): versatile_pci: Fix hardcoded tabs versatile_pci: Expose PCI I/O region on Versatile PB versatile_pci: Update to realize and instance init functions versatile_pci: Change to subclassing TYPE_PCI_HOST_BRIDGE versatile_pci: Use separate PCI I/O space rather than system I/O space versatile_pci: Put the host bridge PCI device at slot 29 versatile_pci: Implement the correct PCI IRQ mapping versatile_pci: Implement the PCI controller's control registers arm/realview: Fix mapping of PCI regions versatile_pci: Expose PCI memory space to system hw/versatile_pci: Drop unnecessary vpb_pci_config_addr() hw/arm/realview.c| 22 +-- hw/arm/versatilepb.c | 11 +- hw/versatile_pci.c | 386 +++--- 3 files changed, 358 insertions(+), 61 deletions(-) -- 1.7.9.5
Re: [Qemu-devel] [PATCHv5 00/10] buffer_is_zero / migration optimizations
Peter Lieven p...@kamp.de wrote: this is v5 of my patch series with various optimizations in zero buffer checking and migration tweaks. thanks especially to Eric Blake, Orit Wassermann and Paolo Bonzini for reviewing. v5: - move zero splat vector to a different patch - fix indentation of can_user_buffer_find_nonzero_offset() - do not unroll the first loop in buffer_find_nonzero_offset() to optimize it for zero page checking - use an older unrolled version of find_next_bit() without SIMD instruction as there is no evidence that the vectorized version is better if not even worse and the code is easier to understand. - added a word in the commit message of patch 8 about the skipped pages field in QMP MigrationStats. - fixed the order of key-value pairs of MigrationStats in qapi-schema.json - updated info about the performance benefit of is_zero_page() to the latest benchmark results in the commit message. v4: - do not inline buffer_find_nonzero_offset() - inline can_usebuffer_find_nonzero_offset() correctly - readd asserts in buffer_find_nonzero_offset() as profiling shows they do not hurt. - change last occurences of scalar 8 by BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR - avoid deferencing p already in patch 5 where we know that the page (p) is zero - explicitly set bytes_sent = 0 if we skip a zero page. bytes_sent was 0 before, but it was not obvious. - add accounting information for skipped zero pages - fix errors reported by checkpatch.pl v3: - remove asserts, inline functions and add a check function if buffer_find_nonzero_offset() can be used. - use above check function in buffer_is_zero() and find_next_bit(). - use buffer_is_nonzero_offset() directly to find zero pages. we know that all requirements are met for memory pages. - fix C89 violation in buffer_is_zero(). - avoid derefencing p in ram_save_block() if we already know the page is zero. - fix initialization of last_offset in reset_ram_globals(). - avoid skipping pages with offset == 0 in bulk stage in migration_bitmap_find_and_reset_dirty(). - compared to v1 check for zero pages also after bulk ram migration as there are guests (e.g. Windows) which zero out large amount of memory while running. v2: - fix description, add trivial zero check and add asserts to buffer_find_nonzero_offset. - add a constant for the unroll factor of buffer_find_nonzero_offset - replace is_dup_page() by buffer_is_zero() - added test results to xbzrle patch - optimize descriptions Peter Lieven (10): move vector definitions to qemu-common.h add a zero splat vector to qemu-common.h cutils: add a function to find non-zero content in a buffer buffer_is_zero: use vector optimizations if possible bitops: unroll while loop in find_next_bit() migration: search for zero instead of dup pages migration: add an indicator for bulk state of ram migration migration: do not sent zero pages in bulk stage migration: do not search dirty pages in bulk stage migration: use XBZRLE only after bulk stage Really nice series. I did some minor review changes, but they are more nits that anynthing else. Thanks, Juan. Reviewed-by: Juan Quintela quint...@redhat.com
[Qemu-devel] [PATCH v2 08/11] versatile_pci: Implement the PCI controller's control registers
The versatile_pci PCI controller has a set of control registers which handle the mapping between PCI and system address spaces. Implement these registers (though for now they have no effect since we don't implement mapping PCI space into system memory at all). The most natural order for our sysbus regions has the control registers at the start, so move all the others down one. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- hw/arm/realview.c|7 +-- hw/arm/versatilepb.c |7 +-- hw/versatile_pci.c | 134 -- 3 files changed, 137 insertions(+), 11 deletions(-) diff --git a/hw/arm/realview.c b/hw/arm/realview.c index 5fb490c..ba61d18 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -217,9 +217,10 @@ static void realview_init(QEMUMachineInitArgs *args, dev = qdev_create(NULL, realview_pci); busdev = SYS_BUS_DEVICE(dev); qdev_init_nofail(dev); -sysbus_mmio_map(busdev, 0, 0x6100); /* PCI self-config */ -sysbus_mmio_map(busdev, 1, 0x6200); /* PCI config */ -sysbus_mmio_map(busdev, 2, 0x6300); /* PCI I/O */ +sysbus_mmio_map(busdev, 0, 0x10019000); /* PCI controller registers */ +sysbus_mmio_map(busdev, 1, 0x6100); /* PCI self-config */ +sysbus_mmio_map(busdev, 2, 0x6200); /* PCI config */ +sysbus_mmio_map(busdev, 3, 0x6300); /* PCI I/O */ sysbus_connect_irq(busdev, 0, pic[48]); sysbus_connect_irq(busdev, 1, pic[49]); sysbus_connect_irq(busdev, 2, pic[50]); diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index 0d08d15..9c9bfde 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -224,9 +224,10 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id) dev = qdev_create(NULL, versatile_pci); busdev = SYS_BUS_DEVICE(dev); qdev_init_nofail(dev); -sysbus_mmio_map(busdev, 0, 0x4100); /* PCI self-config */ -sysbus_mmio_map(busdev, 1, 0x4200); /* PCI config */ -sysbus_mmio_map(busdev, 2, 0x4300); /* PCI I/O */ +sysbus_mmio_map(busdev, 0, 0x10001000); /* PCI controller regs */ +sysbus_mmio_map(busdev, 1, 0x4100); /* PCI self-config */ +sysbus_mmio_map(busdev, 2, 0x4200); /* PCI config */ +sysbus_mmio_map(busdev, 3, 0x4300); /* PCI I/O */ sysbus_connect_irq(busdev, 0, sic[27]); sysbus_connect_irq(busdev, 1, sic[28]); sysbus_connect_irq(busdev, 2, sic[29]); diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 1b56796..a598b64 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -17,6 +17,7 @@ typedef struct { PCIHostState parent_obj; qemu_irq irq[4]; +MemoryRegion controlregs; MemoryRegion mem_config; MemoryRegion mem_config2; MemoryRegion pci_io_space; @@ -28,9 +29,27 @@ typedef struct { int realview; /* Variable state: */ +uint32_t imap[3]; +uint32_t smap[3]; +uint32_t selfid; +uint32_t flags; bool broken_irq_mapping; } PCIVPBState; +static const VMStateDescription pci_vpb_vmstate = { +.name = versatile-pci, +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_UINT32_ARRAY(imap, PCIVPBState, 3), +VMSTATE_UINT32_ARRAY(smap, PCIVPBState, 3), +VMSTATE_UINT32(selfid, PCIVPBState), +VMSTATE_UINT32(flags, PCIVPBState), +VMSTATE_BOOL(broken_irq_mapping, PCIVPBState), +VMSTATE_END_OF_LIST() +} +}; + #define TYPE_VERSATILE_PCI versatile_pci #define PCI_VPB(obj) \ OBJECT_CHECK(PCIVPBState, (obj), TYPE_VERSATILE_PCI) @@ -39,6 +58,93 @@ typedef struct { #define PCI_VPB_HOST(obj) \ OBJECT_CHECK(PCIDevice, (obj), TYPE_VERSATILE_PCIHOST) +typedef enum { +PCI_IMAP0 = 0x0, +PCI_IMAP1 = 0x4, +PCI_IMAP2 = 0x8, +PCI_SELFID = 0xc, +PCI_FLAGS = 0x10, +PCI_SMAP0 = 0x14, +PCI_SMAP1 = 0x18, +PCI_SMAP2 = 0x1c, +} PCIVPBControlRegs; + +static void pci_vpb_reg_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ +PCIVPBState *s = opaque; + +switch (addr) { +case PCI_IMAP0: +case PCI_IMAP1: +case PCI_IMAP2: +{ +int win = (addr - PCI_IMAP0) 2; +s-imap[win] = val; +break; +} +case PCI_SELFID: +s-selfid = val; +break; +case PCI_FLAGS: +s-flags = val; +break; +case PCI_SMAP0: +case PCI_SMAP1: +case PCI_SMAP2: +{ +int win = (addr - PCI_SMAP0) 2; +s-smap[win] = val; +break; +} +default: +qemu_log_mask(LOG_GUEST_ERROR, + pci_vpb_reg_write: Bad offset %x\n, (int)addr); +break; +} +} + +static uint64_t pci_vpb_reg_read(void *opaque, hwaddr addr, + unsigned size) +{ +PCIVPBState *s = opaque; + +switch (addr) { +case PCI_IMAP0: +case PCI_IMAP1:
Re: [Qemu-devel] [PATCH v3] New QMP command query-cpu-max and HMP command cpu_max
On 03/25/2013 07:37 PM, Luiz Capitulino wrote: On Mon, 25 Mar 2013 17:31:33 +0100 Michal Novotny minov...@redhat.com wrote: These commands return the maximum number of CPUs supported by the currently running emulator instance, as defined in its QEMUMachine struct. I've applied this patch to the QMP tree, but with one change (see below). Signed-off-by: Michal Novotny minov...@redhat.com --- hmp-commands.hx | 14 ++ hmp.c| 8 hmp.h| 1 + qapi-schema.json | 11 +++ qmp-commands.hx | 22 ++ vl.c | 5 + 6 files changed, 61 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index df44906..c976459 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -690,6 +690,20 @@ Set the default CPU. ETEXI { +.name = cpu_max, +.args_type = , +.params = , +.help = Get maximum number of VCPUs supported by machine, +.mhandler.cmd = hmp_query_cpu_max, +}, + +STEXI +@item cpu_max +@findex cpu_max +Returns the number of CPUs supported by the machine being emulated. +ETEXI What you really want is an info command, like 'info cpu_max'. As I didn't spot this in my first review (looks like I'm still sleeping, although it's afternoon) I've made that change myself and applied the patch to the qmp tree. Now, if you disagree I can drop it and we discuss the matter :) I'm fine with that :-) Michal -- Michal Novotny minov...@redhat.com, RHCE, Red Hat Virtualization | libvirt-php bindings | php-virt-control.org
Re: [Qemu-devel] [PATCH v2 07/11] versatile_pci: Implement the correct PCI IRQ mapping
On Tuesday 26 March 2013, Peter Maydell wrote: Implement the correct IRQ mapping for the Versatile PCI controller; it differs between realview and versatile boards, but the previous QEMU implementation was correct only for the first PCI card on a versatile board, since we weren't swizzling IRQs based on the slot number. Since this change would otherwise break any uses of PCI on Linux kernels which have an equivalent bug (since they have effectively only been tested against QEMU, not real hardware), we implement a mechanism for automatically detecting those broken kernels and switching back to the old mapping. This works by looking at the values the kernel writes to the PCI_INTERRUPT_LINE register in the config space, which is effectively the interrupt number the kernel expects the device to be using. If this doesn't match reality we use the broken mapping. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Yes, very good. We will probably introduce sparse irq support on versatile in the near future, and then the value we write into the PCI_INTERRUPT_LINE field will become arbitrary from qemu's point of view, but I will make sure that we fix the interrupt mapping in the kernel at the same time so we always fall into the s-broken_irq_mapping = false; case. We also need to find a way to make the new kernel work with an old qemu, and I think we can do that by using the versatile-dt board type with a PCI device node that sets all four lines to 27, while using the actual interrupt lines for the default versatile device tree. Arnd
Re: [Qemu-devel] [PATCHv5 00/10] buffer_is_zero / migration optimizations
Am 26.03.2013 um 11:46 schrieb Juan Quintela quint...@redhat.com: Peter Lieven p...@kamp.de wrote: this is v5 of my patch series with various optimizations in zero buffer checking and migration tweaks. thanks especially to Eric Blake, Orit Wassermann and Paolo Bonzini for reviewing. v5: - move zero splat vector to a different patch - fix indentation of can_user_buffer_find_nonzero_offset() - do not unroll the first loop in buffer_find_nonzero_offset() to optimize it for zero page checking - use an older unrolled version of find_next_bit() without SIMD instruction as there is no evidence that the vectorized version is better if not even worse and the code is easier to understand. - added a word in the commit message of patch 8 about the skipped pages field in QMP MigrationStats. - fixed the order of key-value pairs of MigrationStats in qapi-schema.json - updated info about the performance benefit of is_zero_page() to the latest benchmark results in the commit message. v4: - do not inline buffer_find_nonzero_offset() - inline can_usebuffer_find_nonzero_offset() correctly - readd asserts in buffer_find_nonzero_offset() as profiling shows they do not hurt. - change last occurences of scalar 8 by BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR - avoid deferencing p already in patch 5 where we know that the page (p) is zero - explicitly set bytes_sent = 0 if we skip a zero page. bytes_sent was 0 before, but it was not obvious. - add accounting information for skipped zero pages - fix errors reported by checkpatch.pl v3: - remove asserts, inline functions and add a check function if buffer_find_nonzero_offset() can be used. - use above check function in buffer_is_zero() and find_next_bit(). - use buffer_is_nonzero_offset() directly to find zero pages. we know that all requirements are met for memory pages. - fix C89 violation in buffer_is_zero(). - avoid derefencing p in ram_save_block() if we already know the page is zero. - fix initialization of last_offset in reset_ram_globals(). - avoid skipping pages with offset == 0 in bulk stage in migration_bitmap_find_and_reset_dirty(). - compared to v1 check for zero pages also after bulk ram migration as there are guests (e.g. Windows) which zero out large amount of memory while running. v2: - fix description, add trivial zero check and add asserts to buffer_find_nonzero_offset. - add a constant for the unroll factor of buffer_find_nonzero_offset - replace is_dup_page() by buffer_is_zero() - added test results to xbzrle patch - optimize descriptions Peter Lieven (10): move vector definitions to qemu-common.h add a zero splat vector to qemu-common.h cutils: add a function to find non-zero content in a buffer buffer_is_zero: use vector optimizations if possible bitops: unroll while loop in find_next_bit() migration: search for zero instead of dup pages migration: add an indicator for bulk state of ram migration migration: do not sent zero pages in bulk stage migration: do not search dirty pages in bulk stage migration: use XBZRLE only after bulk stage Really nice series. Thank you. I did some minor review changes, but they are more nits that anynthing else. Ok, where is your repository? Peter Thanks, Juan. Reviewed-by: Juan Quintela quint...@redhat.com
Re: [Qemu-devel] [PATCH v2 07/11] versatile_pci: Implement the correct PCI IRQ mapping
On 26 March 2013 10:54, Arnd Bergmann a...@arndb.de wrote: Yes, very good. We will probably introduce sparse irq support on versatile in the near future, and then the value we write into the PCI_INTERRUPT_LINE field will become arbitrary from qemu's point of view, but I will make sure that we fix the interrupt mapping in the kernel at the same time so we always fall into the s-broken_irq_mapping = false; case. Yeah, as long as you avoid the number 27 you're ok :-) We also need to find a way to make the new kernel work with an old qemu, and I think we can do that by using the versatile-dt board type with a PCI device node that sets all four lines to 27, while using the actual interrupt lines for the default versatile device tree. Personally I'd be happy for you to just say needs a new QEMU. The broken QEMU is missing so much (including working memory windows) that I think it would be a pain to get the kernel to cope with it. -- PMM
Re: [Qemu-devel] [PATCH v2 07/11] versatile_pci: Implement the correct PCI IRQ mapping
On Tuesday 26 March 2013, Peter Maydell wrote: On 26 March 2013 10:54, Arnd Bergmann a...@arndb.de wrote: Yes, very good. We will probably introduce sparse irq support on versatile in the near future, and then the value we write into the PCI_INTERRUPT_LINE field will become arbitrary from qemu's point of view, but I will make sure that we fix the interrupt mapping in the kernel at the same time so we always fall into the s-broken_irq_mapping = false; case. Yeah, as long as you avoid the number 27 you're ok :-) Good point. I guess we'll have to keep using a legacy domain for versatile then. We also need to find a way to make the new kernel work with an old qemu, and I think we can do that by using the versatile-dt board type with a PCI device node that sets all four lines to 27, while using the actual interrupt lines for the default versatile device tree. Personally I'd be happy for you to just say needs a new QEMU. The broken QEMU is missing so much (including working memory windows) that I think it would be a pain to get the kernel to cope with it. But it was working earlier, so I'd definitely try not to break if at all possible. A lot of people use the verstatile qemu model to run kernels and I would not want to deal with the complaints I'd get if we break those. Using a separate dts file seems easy enough. Arnd
Re: [Qemu-devel] [PATCH v5 00/10] virtio-scsi refactoring.
On 21 March 2013 14:15, fred.kon...@greensocs.com wrote: From: KONRAD Frederic fred.kon...@greensocs.com This is the next part of virtio-refactoring. Basically it creates virtio-scsi device which extends virtio-device. Then a virtio-scsi can be connected on a virtio-bus. virtio-scsi-pci, virtio-scsi-s390x, virtio-scsi-ccw are created too, they extend respectively virtio-pci, virtio-s390-device, virtio-ccw-device and have a virtio-scsi. Series: Reviewed-by: Peter Maydell peter.mayd...@linaro.org -- PMM
[Qemu-devel] selecting a sparc framebuffer from command line
It looks like we will have more framebuffers beside TCX in the near future. One way to use them would be to make new machines combining a base machine name with a framebuffer name, like ss5tcx and ss5cg3, but I guess this would produce too many machines if we have more than 2 framebuffers. Should the -vga option be (mis)used for selecting a framebuffer? They are not called VGA in the wild, but maybe the name VGA is obvious enough for a modern user? After all there is already a -hda option in the SPARCStation-5 emulation command line, although in the non-emulating world no one calls scsi disk hda. Or should an architecture-specific option, like -framebuffer be added? -- Regards, Artyom Tarasenko Linux/sparc and solaris/sparc under qemu blog: http://tyom.blogspot.com/search/label/qemu
Re: [Qemu-devel] [PATCH v2 07/11] versatile_pci: Implement the correct PCI IRQ mapping
On 26 March 2013 11:08, Arnd Bergmann a...@arndb.de wrote: On Tuesday 26 March 2013, Peter Maydell wrote: On 26 March 2013 10:54, Arnd Bergmann a...@arndb.de wrote: Yes, very good. We will probably introduce sparse irq support on versatile in the near future, and then the value we write into the PCI_INTERRUPT_LINE field will become arbitrary from qemu's point of view, but I will make sure that we fix the interrupt mapping in the kernel at the same time so we always fall into the s-broken_irq_mapping = false; case. Yeah, as long as you avoid the number 27 you're ok :-) Good point. I guess we'll have to keep using a legacy domain for versatile then. I'm happy to provide some other way for QEMU to detect a new working kernel if you want to implement one in the kernel, if that's cleaner. We also need to find a way to make the new kernel work with an old qemu, and I think we can do that by using the versatile-dt board type with a PCI device node that sets all four lines to 27, while using the actual interrupt lines for the default versatile device tree. Personally I'd be happy for you to just say needs a new QEMU. The broken QEMU is missing so much (including working memory windows) that I think it would be a pain to get the kernel to cope with it. But it was working earlier, so I'd definitely try not to break if at all possible. A lot of people use the verstatile qemu model to run kernels and I would not want to deal with the complaints I'd get if we break those. Using a separate dts file seems easy enough. Yeah, but it only worked earlier because the kernel PCI controller support was so broken and limited, I think. If you run a new kernel with the old QEMU it won't work even if you avoid the irq-mapping issues. Also I really don't want to get people into the habit of using a QEMU-specific dts file. The result will be that nobody will ever move on from that dts file to the one that gets used with real hardware. Plus, you guys make kernel changes that break running on QEMU all the time, so I don't see that as a big deal really. (Most recently, vexpress needed a pile of support for the config registers that define the voltage regulators and clocks.) -- PMM
[Qemu-devel] [Bug 1159605] Re: run command hangs using -M none
Andreas, sorry. My Bad. But could you please confirm that 3rd and 4th cmd run correctly/ lead to stall? Do you not get a help msg (unlike an infinite hang mentioned by Jiamswang ) that I mentioned in the comment? I tried running the given commands on my machine and the 1st and 2nd commands run just fine. Its the 3rd and 4th commands that do not work. Also, the , is handled by an appropriate help msg. I used libvirt 0.9.8 Host - Ubuntu 12.04 Kernel 3.6. Guest Gentoo. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1159605 Title: run command hangs using -M none Status in QEMU: Invalid Bug description: when i run following command, it just hangs there qemu-system-x86_64 -enable-kvm -S -no-user-config -nodefaults -nographic -machine none,kernel_irqchip=on -monitor unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile /var/lib/libvirt/qemu/capabilities.pidfile OR qemu-system-x86_64 -enable-kvm -S -no-user-config -nodefaults -nographic -M none -monitor unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile /var/lib/libvirt/qemu/capabilities.pidfile but blow command just fine qemu-system-x86_64 -enable-kvm -S -no-user-config -nodefaults -nographic -M none,kernel_irqchip=on -monitor unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile /var/lib/libvirt/qemu/capabilities.pidfile OR qemu-system-x86_64 -enable-kvm -S -no-user-config -nodefaults -nographic -M none, -monitor unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile /var/lib/libvirt/qemu/capabilities.pidfile I installed qemu-git version on gentoo with kernel 3.8.4 is this a bug??? To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1159605/+subscriptions
[Qemu-devel] [PATCH] sh7750: Fix crash when accessing PVR/PRR/CVR
Commit b350ab75 causes segfaults on accesses to PVR/PRR/CVR because it tries to call SUPERH_CPU_GET_CLASS() on a pointer that isn't a QOM object. Fix this by getting the actual QOM CPU object first. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- Tested with the r2d image/instructions from https://oss.renesas.com/modules/document/?Getting%20Started%20with%20SH4%20and%20QEMU hw/sh4/sh7750.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c index e4d37ad..3580c87 100644 --- a/hw/sh4/sh7750.c +++ b/hw/sh4/sh7750.c @@ -289,13 +289,13 @@ static uint32_t sh7750_mem_readl(void *opaque, hwaddr addr) case SH7750_CCR_A7: return s-ccr; case 0x1f30: /* Processor version */ -scc = SUPERH_CPU_GET_CLASS(s-cpu); +scc = SUPERH_CPU_GET_CLASS(ENV_GET_CPU(s-cpu)); return scc-pvr; case 0x1f40: /* Cache version */ -scc = SUPERH_CPU_GET_CLASS(s-cpu); +scc = SUPERH_CPU_GET_CLASS(ENV_GET_CPU(s-cpu)); return scc-cvr; case 0x1f44: /* Processor revision */ -scc = SUPERH_CPU_GET_CLASS(s-cpu); +scc = SUPERH_CPU_GET_CLASS(ENV_GET_CPU(s-cpu)); return scc-prr; default: error_access(long read, addr); -- 1.7.9.5
[Qemu-devel] [PATCH] hw/tcx: Remove unused 'addr' field and the property that sets it
Remove the 'addr' field from TCXState (since it is completely unused), also the qdev property which sets it. This seems to be a relic from many years past; devices don't need to know where they are mapped. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- Random minor cleanup, but I'm hoping we might be able to get rid of the 'taddr' properties altogether; there aren't very many of them... hw/sparc/sun4m.c |1 - hw/tcx.c |2 -- 2 files changed, 3 deletions(-) diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 2f214da..9ebda02 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -575,7 +575,6 @@ static void tcx_init(hwaddr addr, int vram_size, int width, SysBusDevice *s; dev = qdev_create(NULL, SUNW,tcx); -qdev_prop_set_taddr(dev, addr, addr); qdev_prop_set_uint32(dev, vram_size, vram_size); qdev_prop_set_uint16(dev, width, width); qdev_prop_set_uint16(dev, height, height); diff --git a/hw/tcx.c b/hw/tcx.c index f1edffd..c44068e 100644 --- a/hw/tcx.c +++ b/hw/tcx.c @@ -37,7 +37,6 @@ typedef struct TCXState { SysBusDevice busdev; -hwaddr addr; QemuConsole *con; uint8_t *vram; uint32_t *vram24, *cplane; @@ -707,7 +706,6 @@ write_err: } static Property tcx_properties[] = { -DEFINE_PROP_TADDR(addr, TCXState, addr, -1), DEFINE_PROP_HEX32(vram_size, TCXState, vram_size, -1), DEFINE_PROP_UINT16(width,TCXState, width, -1), DEFINE_PROP_UINT16(height, TCXState, height,-1), -- 1.7.9.5
[Qemu-devel] [PULL 0/4] QMP queue
The changes (since dcadaa9b40d6019ac18d6fd7763d43048ef79218) are available in the following repository: git://repo.or.cz/qemu/qmp-unstable.git queue/qmp Corey Bryant (2): QMP: Remove duplicate TPM type from query-tpm QMP: TPM QMP and man page documentation updates Igor Mammedov (1): qmp: fix handling of boolean values in qmp-shell Michal Novotny (1): New QMP command query-cpu-max and HMP command cpu_max QMP/qmp-shell| 7 - hmp-commands.hx | 2 ++ hmp.c| 16 +--- hmp.h| 1 + monitor.c| 7 + qapi-schema.json | 23 ++-- qemu-options.hx | 3 ++- qmp-commands.hx | 80 tpm/tpm.c| 9 +++ vl.c | 5 10 files changed, 134 insertions(+), 19 deletions(-) -- 1.8.1.4
[Qemu-devel] [PULL 3/4] qmp: fix handling of boolean values in qmp-shell
From: Igor Mammedov imamm...@redhat.com qmp-shell converts only integer arguments and the rest is assumed to be strings which are faithfully sent as quoted strings by json. But QEMU refuses to accept qmp command with boolean argument whose value is escaped as string. Fix it by special-casing true/false keywords and store value as corresponding boolean. Signed-off-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- QMP/qmp-shell | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/QMP/qmp-shell b/QMP/qmp-shell index 24b665c..d126e63 100755 --- a/QMP/qmp-shell +++ b/QMP/qmp-shell @@ -101,7 +101,12 @@ class QMPShell(qmp.QEMUMonitorProtocol): try: value = int(opt[1]) except ValueError: -value = opt[1] +if opt[1] == 'true': +value = True +elif opt[1] == 'false': +value = False +else: +value = opt[1] qmpcmd['arguments'][opt[0]] = value return qmpcmd -- 1.8.1.4
[Qemu-devel] [PULL 1/4] QMP: Remove duplicate TPM type from query-tpm
From: Corey Bryant cor...@linux.vnet.ibm.com Signed-off-by: Corey Bryant cor...@linux.vnet.ibm.com Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Markus Armbruster arm...@redhat.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- hmp.c| 8 qapi-schema.json | 12 tpm/tpm.c| 9 - 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/hmp.c b/hmp.c index b0a861c..d319897 100644 --- a/hmp.c +++ b/hmp.c @@ -631,11 +631,11 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) c, TpmModel_lookup[ti-model]); monitor_printf(mon, \\ %s: type=%s, - ti-id, TpmType_lookup[ti-type]); + ti-id, TpmTypeOptionsKind_lookup[ti-options-kind]); -switch (ti-tpm_options-kind) { -case TPM_TYPE_OPTIONS_KIND_TPM_PASSTHROUGH_OPTIONS: -tpo = ti-tpm_options-tpm_passthrough_options; +switch (ti-options-kind) { +case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH: +tpo = ti-options-passthrough; monitor_printf(mon, %s%s%s%s, tpo-has_path ? ,path= : , tpo-has_path ? tpo-path : , diff --git a/qapi-schema.json b/qapi-schema.json index 088f4e1..0d16d14 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3403,13 +3403,12 @@ # # A union referencing different TPM backend types' configuration options # -# @tpm-passthough-options: TPMPassthroughOptions describing the TPM -# passthrough configuration options +# @passthrough: The configuration options for the TPM passthrough type # # Since: 1.5 ## { 'union': 'TpmTypeOptions', - 'data': { 'tpm-passthrough-options' : 'TPMPassthroughOptions' } } + 'data': { 'passthrough' : 'TPMPassthroughOptions' } } ## # @TpmInfo: @@ -3420,17 +3419,14 @@ # # @model: The TPM frontend model # -# @type: The TPM (backend) type being used -# -# @tpm-options: The TPM (backend) type configuration options +# @options: The TPM (backend) type configuration options # # Since: 1.5 ## { 'type': 'TPMInfo', 'data': {'id': 'str', 'model': 'TpmModel', - 'type': 'TpmType', - 'tpm-options': 'TpmTypeOptions' } } + 'options': 'TpmTypeOptions' } } ## # @query-tpm: diff --git a/tpm/tpm.c b/tpm/tpm.c index ffd2495..ae00eae 100644 --- a/tpm/tpm.c +++ b/tpm/tpm.c @@ -257,14 +257,13 @@ static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv) res-id = g_strdup(drv-id); res-model = drv-fe_model; -res-type = drv-ops-type; -res-tpm_options = g_new0(TpmTypeOptions, 1); +res-options = g_new0(TpmTypeOptions, 1); -switch (res-type) { +switch (drv-ops-type) { case TPM_TYPE_PASSTHROUGH: -res-tpm_options-kind = TPM_TYPE_OPTIONS_KIND_TPM_PASSTHROUGH_OPTIONS; +res-options-kind = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH; tpo = g_new0(TPMPassthroughOptions, 1); -res-tpm_options-tpm_passthrough_options = tpo; +res-options-passthrough = tpo; if (drv-path) { tpo-path = g_strdup(drv-path); tpo-has_path = true; -- 1.8.1.4
[Qemu-devel] [PULL 2/4] QMP: TPM QMP and man page documentation updates
From: Corey Bryant cor...@linux.vnet.ibm.com Signed-off-by: Corey Bryant cor...@linux.vnet.ibm.com Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Markus Armbruster arm...@redhat.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- qemu-options.hx | 3 ++- qmp-commands.hx | 58 + 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/qemu-options.hx b/qemu-options.hx index d7afeab..c40ba55 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2241,7 +2241,8 @@ Backend type must be: @option{passthrough}. The specific backend type will determine the applicable options. -The @code{-tpmdev} option requires a @code{-device} option. +The @code{-tpmdev} option creates the TPM backend and requires a +@code{-device} option that specifies the TPM frontend interface model. Options to each backend are described below. diff --git a/qmp-commands.hx b/qmp-commands.hx index b370060..3aa6bd1 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2721,18 +2721,76 @@ EQMP .mhandler.cmd_new = qmp_marshal_input_query_tpm, }, +SQMP +query-tpm +- + +Return information about the TPM device. + +Arguments: None + +Example: + +- { execute: query-tpm } +- { return: + [ + { model: tpm-tis, + options: + { type: passthrough, + data: + { cancel-path: /sys/class/misc/tpm0/device/cancel, + path: /dev/tpm0 + } + }, + id: tpm0 + } + ] + } + +EQMP + { .name = query-tpm-models, .args_type = , .mhandler.cmd_new = qmp_marshal_input_query_tpm_models, }, +SQMP +query-tpm-models + + +Return a list of supported TPM models. + +Arguments: None + +Example: + +- { execute: query-tpm-models } +- { return: [ tpm-tis ] } + +EQMP + { .name = query-tpm-types, .args_type = , .mhandler.cmd_new = qmp_marshal_input_query_tpm_types, }, +SQMP +query-tpm-types +--- + +Return a list of supported TPM types. + +Arguments: None + +Example: + +- { execute: query-tpm-types } +- { return: [ passthrough ] } + +EQMP + { .name = chardev-add, .args_type = id:s,backend:q, -- 1.8.1.4
[Qemu-devel] [PULL 4/4] New QMP command query-cpu-max and HMP command cpu_max
From: Michal Novotny minov...@redhat.com These commands return the maximum number of CPUs supported by the currently running emulator instance, as defined in its QEMUMachine struct. Signed-off-by: Michal Novotny minov...@redhat.com Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- hmp-commands.hx | 2 ++ hmp.c| 8 hmp.h| 1 + monitor.c| 7 +++ qapi-schema.json | 11 +++ qmp-commands.hx | 22 ++ vl.c | 5 + 7 files changed, 56 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index df44906..3d98604 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1643,6 +1643,8 @@ show qdev device model list show roms @item info tpm show the TPM device +@item info cpu_max +show the number of CPUs supported by the machine being emulated. @end table ETEXI diff --git a/hmp.c b/hmp.c index d319897..c12c495 100644 --- a/hmp.c +++ b/hmp.c @@ -748,6 +748,14 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict) g_free(data); } +void hmp_query_cpu_max(Monitor *mon, const QDict *qdict) +{ +int cpu_max; + +cpu_max = qmp_query_cpu_max(NULL); +monitor_printf(mon, Maximum number of CPUs is %d\n, cpu_max); +} + static void hmp_cont_cb(void *opaque, int err) { if (!err) { diff --git a/hmp.h b/hmp.h index 95fe76e..80e8b41 100644 --- a/hmp.h +++ b/hmp.h @@ -42,6 +42,7 @@ void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); void hmp_system_powerdown(Monitor *mon, const QDict *qdict); void hmp_cpu(Monitor *mon, const QDict *qdict); +void hmp_query_cpu_max(Monitor *mon, const QDict *qdict); void hmp_memsave(Monitor *mon, const QDict *qdict); void hmp_pmemsave(Monitor *mon, const QDict *qdict); void hmp_ringbuf_write(Monitor *mon, const QDict *qdict); diff --git a/monitor.c b/monitor.c index 2d9e887..e450919 100644 --- a/monitor.c +++ b/monitor.c @@ -2746,6 +2746,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.cmd = hmp_info_tpm, }, { +.name = cpu_max, +.args_type = , +.params = , +.help = Get maximum number of VCPUs supported by machine, +.mhandler.cmd = hmp_query_cpu_max, +}, +{ .name = NULL, }, }; diff --git a/qapi-schema.json b/qapi-schema.json index 0d16d14..af499bd 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1832,6 +1832,17 @@ { 'command': 'query-migrate-cache-size', 'returns': 'int' } ## +## @query-cpu-max +## +## query maximum number of CPUs supported by machine +## +## Returns: number of CPUs +## +## Since: 1.5 +### +{ 'command': 'query-cpu-max', 'returns': 'int' } + +## # @ObjectPropertyInfo: # # @name: the name of the property diff --git a/qmp-commands.hx b/qmp-commands.hx index 3aa6bd1..2051fcb 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -385,6 +385,28 @@ Note: CPUs' indexes are obtained with the 'query-cpus' command. EQMP { +.name = query-cpu-max, +.args_type = , +.mhandler.cmd_new = qmp_marshal_input_query_cpu_max, +}, + +SQMP +query-cpu-max +- + +Get the maximum CPUs supported by the machine being currently +emulated. + +Returns json-int. + +Example: + +- { execute: query-cpu-max } +- { return: 255 } + +EQMP + +{ .name = memsave, .args_type = val:l,size:i,filename:s,cpu:i?, .mhandler.cmd_new = qmp_marshal_input_memsave, diff --git a/vl.c b/vl.c index aeed7f4..7643f16 100644 --- a/vl.c +++ b/vl.c @@ -662,6 +662,11 @@ StatusInfo *qmp_query_status(Error **errp) return info; } +int64_t qmp_query_cpu_max(Error **errp) +{ +return current_machine-max_cpus; +} + /***/ /* real time host monotonic timer */ -- 1.8.1.4
Re: [Qemu-devel] [PATCH 07/11] qemu-char: Move incrementing of avail_connections to qdev-properties-system
Il 26/03/2013 11:07, Hans de Goede ha scritto: The decrement of avail_connections is done in qdev-properties-system move the increment there too for proper balancing of the calls. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/qdev-properties-system.c | 6 -- qemu-char.c | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c index 8795144..12a87d5 100644 --- a/hw/qdev-properties-system.c +++ b/hw/qdev-properties-system.c @@ -136,9 +136,11 @@ static void release_chr(Object *obj, const char *name, void *opaque) DeviceState *dev = DEVICE(obj); Property *prop = opaque; CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); +CharDriverState *chr = *ptr; -if (*ptr) { -qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); +if (chr) { +qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL); +++chr-avail_connections; } } diff --git a/qemu-char.c b/qemu-char.c index 8a66627..368e7f5 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -197,8 +197,6 @@ void qemu_chr_add_handlers(CharDriverState *s, int fe_open; if (!opaque !fd_can_read !fd_read !fd_event) { -/* chr driver being released. */ -++s-avail_connections; fe_open = 0; } else { fe_open = 1; I think this is still wrong (though better than before this patch). This is still not giving an error: qemu-kvm \ -chardev stdio,id=foo -device isa-serial,chardev=foo \ -mon chardev=foo because other users of -chardev (monitor and rng-egd), are not decrementing avail_connections. Can you look at it in a follow-up? Paolo
Re: [Qemu-devel] [PATCH 2/2] pflash_cfi01: Implement migration support
On 19 March 2013 18:24, Peter Maydell peter.mayd...@linaro.org wrote: Add a vmstate to pflash_cfi01, so that it can be live migrated. XXX this device is in pc, so does this break cross version migration??? Oops. I checked that this was going to work ok, but forgot to remove the XXX markers. I'm planning to put these patches into the arm-devs queue, so I'll just remove this line from the commit message at that point. thanks -- PMM
Re: [Qemu-devel] [PATCH 07/11] qemu-char: Move incrementing of avail_connections to qdev-properties-system
Hi, On 03/26/2013 02:07 PM, Paolo Bonzini wrote: Il 26/03/2013 11:07, Hans de Goede ha scritto: The decrement of avail_connections is done in qdev-properties-system move the increment there too for proper balancing of the calls. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/qdev-properties-system.c | 6 -- qemu-char.c | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c index 8795144..12a87d5 100644 --- a/hw/qdev-properties-system.c +++ b/hw/qdev-properties-system.c @@ -136,9 +136,11 @@ static void release_chr(Object *obj, const char *name, void *opaque) DeviceState *dev = DEVICE(obj); Property *prop = opaque; CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); +CharDriverState *chr = *ptr; -if (*ptr) { -qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); +if (chr) { +qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL); +++chr-avail_connections; } } diff --git a/qemu-char.c b/qemu-char.c index 8a66627..368e7f5 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -197,8 +197,6 @@ void qemu_chr_add_handlers(CharDriverState *s, int fe_open; if (!opaque !fd_can_read !fd_read !fd_event) { -/* chr driver being released. */ -++s-avail_connections; fe_open = 0; } else { fe_open = 1; I think this is still wrong (though better than before this patch). This is still not giving an error: qemu-kvm \ -chardev stdio,id=foo -device isa-serial,chardev=foo \ -mon chardev=foo because other users of -chardev (monitor and rng-egd), are not decrementing avail_connections. Can you look at it in a follow-up? I know, I ended up writing this patch mostly as a side-effect. I can put further fixing this on my TODO list but first I've some questions about this which need answering: 1) For most problematic devices, the proper fix would be to make them use a chardev qdev property for there chardev usage, and then this would be automatically fixed, agreed? 2) For some this may not fly and a manual inc / dec of avail_connections is necessary, ie the monitor, agreed? 3) One weird case which I encountered when working on this I noticed that backends/rng-egd.c has its chardev as a string qdev-property, rather then as a chardev qdev-property and then it does a qemu_chr_find itself, is this intentional, iow is there some reason having it as a chardev qdev-property does not work ? Regards, Hans
Re: [Qemu-devel] [PATCH 11/12 v2] qmp: add cpu-set qmp command
On Mon, 25 Mar 2013 14:22:36 -0600 Eric Blake ebl...@redhat.com wrote: On 03/25/2013 02:09 PM, Luiz Capitulino wrote: On Mon, 25 Mar 2013 16:35:11 +0100 Igor Mammedov imamm...@redhat.com wrote: +void qmp_cpu_set(int64_t id, const bool online, Error **errp) +{ +if (online) { +do_cpu_hot_add(id, errp); +} else { +error_setg(errp, Unplug is not implemented); +} +} As a general rule, we don't allow command extensions to be done this way because this is not queriable. A client would have to try online=off to see if QEMU version X supports it, worse: the client would have to parse the error message to be sure the failure actually corresponds to unplug not implemented. The alternative is to have cpu-set-online and later cpu-set-offline. Quite verbose, but doesn't have issues. It looks like better as way to go. Later on we could keep them for compatibility sake and map it to device_add/device_del commands when they are ready. Eric, what do you think? Good point. What is the likelihood of getting offline working before 1.5 is released? If we are certain that offline cpu support won't make this release, then having separate commands would indeed be easier to query. It's not likely to be ready for 1.5, since offline depends on code introduced in this series and lacks VCPU hot-remove on KVM side. Some time ago there were patches on list to introduce VCPU hot-remove in KVM, but it didn't go well I think due to lack of VCPU hot-add and common infrastructure it introduces. On the other hand, why aren't we mirroring the QMP behavior to be similar to what Lazlo already did for qga: https://lists.gnu.org/archive/html/qemu-devel/2013-03/msg01031.html Looks like terms online/offline are confusing, it would be better if cpu-set id=xx online=xxx is replaced with cpu_add/cpu_del commands following pattern of drive_add/del, pci_add/del ... That is, by having a way to query details on the set of all possible cpus (via a new command that returns an array with max cpus elements, rather than just the single int of query-cpu-max in https://lists.gnu.org/archive/html/qemu-devel/2013-03/msg04441.html), with information in that query including a second boolean stating whether that cpu can be taken offline, would be sufficiently queryable. The initial implementation would then state that an offline cpu can be taken online, but that an online cpu must remain in that state. All of it wouldn't be necessary if we have only cpu_add without cpu_del implemented. As for querying present VCPUs, one could use qom to enumerate /machine/unattached/icc-bus childs, looking for childs with type == *-cpu It's possible to pre-allocate empty shortcut links like /machine/cpu[id] for all VCPUs and populate corresponding links in x86_cpu_realizefn() when it is going complete successfully. But query-ability of all possible CPUs could be a bit out of scope of this series and requires changes to qdev, so I've left it out for another time. And while typing that, I also realize that I like Lazlo's approach for another reason - guest-set-vcpus takes an array of actions, and performs as many as possible in one transaction; whereas your current cpu-set command has to be called multiple times to take multiple cpus online. Yep, it has to be called for each CPU since it provides low level API at QEMU level, allowing management to implement higher level ops like transactions and all the logic associated with it (it is like device_add/del commands towards which CPUs are moving slowly). Considering all said above, would it be acceptable to replace cpu-set with cpu_add id=xx command?
Re: [Qemu-devel] [PATCH 07/11] qemu-char: Move incrementing of avail_connections to qdev-properties-system
Il 26/03/2013 14:30, Hans de Goede ha scritto: Hi, On 03/26/2013 02:07 PM, Paolo Bonzini wrote: Il 26/03/2013 11:07, Hans de Goede ha scritto: The decrement of avail_connections is done in qdev-properties-system move the increment there too for proper balancing of the calls. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/qdev-properties-system.c | 6 -- qemu-char.c | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c index 8795144..12a87d5 100644 --- a/hw/qdev-properties-system.c +++ b/hw/qdev-properties-system.c @@ -136,9 +136,11 @@ static void release_chr(Object *obj, const char *name, void *opaque) DeviceState *dev = DEVICE(obj); Property *prop = opaque; CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); +CharDriverState *chr = *ptr; -if (*ptr) { -qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); +if (chr) { +qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL); +++chr-avail_connections; } } diff --git a/qemu-char.c b/qemu-char.c index 8a66627..368e7f5 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -197,8 +197,6 @@ void qemu_chr_add_handlers(CharDriverState *s, int fe_open; if (!opaque !fd_can_read !fd_read !fd_event) { -/* chr driver being released. */ -++s-avail_connections; fe_open = 0; } else { fe_open = 1; I think this is still wrong (though better than before this patch). This is still not giving an error: qemu-kvm \ -chardev stdio,id=foo -device isa-serial,chardev=foo \ -mon chardev=foo because other users of -chardev (monitor and rng-egd), are not decrementing avail_connections. Can you look at it in a follow-up? I know, I ended up writing this patch mostly as a side-effect. I can put further fixing this on my TODO list but first I've some questions about this which need answering: 1) For most problematic devices, the proper fix would be to make them use a chardev qdev property for there chardev usage, and then this would be automatically fixed, agreed? At least on x86, all devices already use a chardev qdev property. 2) For some this may not fly and a manual inc / dec of avail_connections is necessary, ie the monitor, agreed? 3) One weird case which I encountered when working on this I noticed that backends/rng-egd.c has its chardev as a string qdev-property, rather then as a chardev qdev-property and then it does a qemu_chr_find itself, is this intentional, iow is there some reason having it as a chardev qdev-property does not work ? The infrastructure for chardev qdev properties right now is only used within devices. The right thing to do would be to make chardevs QOM objects. Then you do not need any special code, just make chardevs QOM links. Paolo
[Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines
NOTE: Applies on top of the trace: Generic event state description series (already in the tracing tree), and is based on revision a4bcea3 from master. TODO: Make sure no TCG code is executing during 'instr_unload' (qemu_cpu_kick? tb_lock?) The whole set of patch series is available at: https://projects.gso.ac.upc.edu/projects/qemu-dbi Adds the instrument event property to declare which tracing events in QEMU must be instrumentable. Still, in case the user only wants to wrap around the tracing events, the original tracing implementation is accessible through the appropriate routines. The instrumentation can be performed either through a dynamically-loaded library or through user-provided code that is compiled into QEMU itself (useful when instrumenting high-frequency events, as the fast-path of the instrumentation can be inlined into QEMU). As a side-effect this series adds an API for the instrumentation code to have some basic interaction with QEMU. See the documentation added in the first patch for more information. Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu --- Lluís Vilanova (22): instrument: Add documentation trace: [simple] Do not include trace/simple.h in generated tracer headers trace: Let the user specify her own trace-events file tracetool: Use method 'Event.api' to get the name of public routines trace: Minimize inclusions of qemu-common.h to avoid inclusion loops instrument: [none] Add null instrumentation linux-user: Use absolute include path instrument: [static] Call statically linked user-provided routines instrument: [dynamic] Call dynamically linked user-provided routines instrument: Add internal control interface instrument: [hmp] Add control interface qapi: Add a primitive to include other files from a QAPI schema file [trivial] Set the input root directory when parsing QAPI files instrument: [qmp, qapi] Add control interface Let makefiles add entries to the set of target architecture objects instrument: Add commandline options to start with an instrumentation library instrument: Add client-side API to enumerate events instrument: Add client-side API to control tracing state of events instrument: Add client-side API to control event instrumentation build: Fix installation of target-dependant files instrument: Install headers for dynamic instrumentation clients trace: Do not use the word 'new' in event arguments .gitignore |4 Makefile| 46 ++- Makefile.objs |8 Makefile.target |7 bsd-user/main.c | 24 + bsd-user/syscall.c |5 configure | 96 + docs/instrumentation.txt| 481 +++ docs/tracing.txt|9 + hmp-commands.hx | 42 ++ hw/virtio.c |1 include/qapi/qmp/qerror.h |9 + include/trace.h |2 instrument/Makefile.objs| 86 + instrument/api-control.c| 14 + instrument/api-trace.c | 14 + instrument/cmdline.c| 94 + instrument/cmdline.h| 41 ++ instrument/control-internal.h | 33 ++ instrument/control.c| 139 instrument/control.h| 133 +++ instrument/hmp.c| 65 instrument/hmp.h| 21 + instrument/qapi-schema.json | 33 ++ instrument/qemu-instr/control-internal.h| 64 instrument/qemu-instr/control.h | 185 ++ instrument/qemu-instr/trace-internal.h | 27 ++ instrument/qemu-instr/trace.h | 91 + instrument/qemu-instr/visibility-internal.h | 94 + instrument/qmp.c| 59 +++ libcacard/Makefile |2 linux-user/main.c | 29 ++ linux-user/syscall.c|4 monitor.c |5 qapi-schema.json|2 qemu-options.hx | 18 + qmp-commands.hx | 72 qmp.c |4 rules.mak |3 scripts/qapi-commands.py| 10 - scripts/qapi-types.py | 10 - scripts/qapi-visit.py | 10 - scripts/qapi.py | 12 + scripts/tracetool.py| 12 +