Re: [Qemu-devel] [PATCH] target-i386: Fix CC_OP_CLR vs PF
On Fri, Jan 10, 2014 at 12:39:56PM -0800, Richard Henderson wrote: Parity should be set for a zero result. Signed-off-by: Richard Henderson r...@twiddle.net Reviewed-by: Edgar E. Iglesias edgar.igles...@xilinx.com --- target-i386/cc_helper.c | 2 +- target-i386/translate.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c index ee04092..05dd12b 100644 --- a/target-i386/cc_helper.c +++ b/target-i386/cc_helper.c @@ -103,7 +103,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1, case CC_OP_EFLAGS: return src1; case CC_OP_CLR: -return CC_Z; +return CC_Z | CC_P; case CC_OP_MULB: return compute_all_mulb(dst, src1); diff --git a/target-i386/translate.c b/target-i386/translate.c index b0f2279..34f35e7 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -748,7 +748,7 @@ static void gen_compute_eflags(DisasContext *s) return; } if (s-cc_op == CC_OP_CLR) { -tcg_gen_movi_tl(cpu_cc_src, CC_Z); +tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P); set_cc_op(s, CC_OP_EFLAGS); return; } -- 1.8.4.2
Re: [Qemu-devel] [PATCH 7/8] virtio-vga: v1
On Mi, 2014-01-08 at 09:35 +1000, Dave Airlie wrote: On Fri, Dec 6, 2013 at 6:58 PM, Dave Airlie airl...@gmail.com wrote: On Fri, Dec 6, 2013 at 6:24 PM, Gerd Hoffmann kra...@redhat.com wrote: Hi, Now the advice given was to have virtio-vga wrap virtio-gpu-base but from what I can see it really can't. Since it needs to act and look like a PCI device Oops, yes. VirtIOPCIProxy wasn't on my radar. That makes things a bit more messy. Can you just push what you have now somewhere? I'll take a closer look next week. http://cgit.freedesktop.org/~airlied/qemu/log/?h=virtio-gpu-inherit Well I didn't really get anything working, but the top commit in that branch was where I was on my last random fail. I think another object is probably required, or making the base one not abstract. Hi Gerd, just repinging on this, not sure if you can see a solution that works with VirtIOPCIProxy that avoids wrapping. Havn't found time yet. Was sick over xmas/newyear, back online now. So I have a big email backlog to wade through now, and there are also the input/sdl2 bits which need some love to get it merged. Also not checked yet bugzilla for urgent stuff. So I expect this has to wait at least one more week ... happy new years cheers, Gerd
Re: [Qemu-devel] [PATCHv4 6/6] ui/vnc: disable adaptive update calculations if not needed
On 13.01.2014 03:42, Wenchao Xia wrote: 于 2014/1/11 6:28, Peter Lieven 写道: Am 10.01.2014 04:09, schrieb Wenchao Xia: 于 2014/1/10 0:25, Peter Lieven 写道: Am 09.01.2014 09:29, schrieb Wenchao Xia: 于 2014/1/8 17:08, Peter Lieven 写道: Signed-off-by: Peter Lieven p...@kamp.de --- ui/vnc.c |9 + 1 file changed, 9 insertions(+) diff --git a/ui/vnc.c b/ui/vnc.c index da552fe..a742d32 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3170,7 +3170,9 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp) acl = 1; #endif } else if (strncmp(options, lossy, 5) == 0) { +#ifdef CONFIG_VNC_JPEG vs-lossy = true; +#endif } else if (strncmp(options, non-adaptive, 12) == 0) { vs-non_adaptive = true; } else if (strncmp(options, share=, 6) == 0) { @@ -3187,6 +3189,13 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp) } } +/* adaptive updates are only used with tight encoding and + * if lossy updates are enabled so we can disable all the + * calculations otherwise */ +if (!vs-lossy) { +vs-non_adaptive = true; +} + The code seems: if vs-loosy == false, then vs-non_adaptive = true, translate as: if loosy update is not used, then don't do adaptive update., which doesn't conform with the comments. I am not sure if this is on expectation. It don't see the logic break. The option means non_adaptive, not adaptive. I write adaptive updates are only used ... with lossy updates Which So tight encoding means loosy updates? It means you can only enable lossy updates if you have tight encoding. So if you are missing tight encoding or lossy is false then you can set non_adaptive to true. Peter I see the logic, guess I punctuated the comments in a wrong way, the real meaning may be: /* Adaptive updates are only used with tight encoding and * if lossy updates are enabled, so we can disable all the * calculations otherwise */ Agreed. The comma there makes it clearer. Peter -- Mit freundlichen Grüßen Peter Lieven ... KAMP Netzwerkdienste GmbH Vestische Str. 89-91 | 46117 Oberhausen Tel: +49 (0) 208.89 402-50 | Fax: +49 (0) 208.89 402-40 p...@kamp.de | http://www.kamp.de Geschäftsführer: Heiner Lante | Michael Lante Amtsgericht Duisburg | HRB Nr. 12154 USt-Id-Nr.: DE 120607556 ...
[Qemu-devel] [PATCH v3 14/22] exec: Make stw_*_phys input an AddressSpace
From: Edgar E. Iglesias edgar.igles...@xilinx.com Signed-off-by: Edgar E. Iglesias edgar.igles...@xilinx.com --- exec.c | 20 ++-- hw/net/vmware_utils.h |2 +- hw/ppc/ppc405_uc.c |2 +- hw/ppc/spapr_hcall.c |4 ++-- hw/s390x/css.c |3 ++- hw/s390x/s390-virtio-bus.c |8 +--- hw/s390x/virtio-ccw.c |3 ++- hw/sh4/r2d.c |2 +- hw/virtio/virtio.c | 10 ++ include/exec/cpu-common.h |6 +++--- target-i386/smm_helper.c | 12 ++-- target-i386/svm_helper.c |4 ++-- target-s390x/mem_helper.c |3 ++- target-sparc/ldst_helper.c |6 +++--- 14 files changed, 46 insertions(+), 39 deletions(-) diff --git a/exec.c b/exec.c index a64577d..e399d18 100644 --- a/exec.c +++ b/exec.c @@ -1609,7 +1609,7 @@ static void watch_mem_write(void *opaque, hwaddr addr, stb_phys(addr, val); break; case 2: -stw_phys(addr, val); +stw_phys(address_space_memory, addr, val); break; case 4: stl_phys(address_space_memory, addr, val); @@ -2619,7 +2619,8 @@ void stb_phys(hwaddr addr, uint32_t val) } /* warning: addr must be aligned */ -static inline void stw_phys_internal(hwaddr addr, uint32_t val, +static inline void stw_phys_internal(AddressSpace *as, + hwaddr addr, uint32_t val, enum device_endian endian) { uint8_t *ptr; @@ -2627,8 +2628,7 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val, hwaddr l = 2; hwaddr addr1; -mr = address_space_translate(address_space_memory, addr, addr1, l, - true); +mr = address_space_translate(as, addr, addr1, l, true); if (l 2 || !memory_access_is_direct(mr, true)) { #if defined(TARGET_WORDS_BIGENDIAN) if (endian == DEVICE_LITTLE_ENDIAN) { @@ -2659,19 +2659,19 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val, } } -void stw_phys(hwaddr addr, uint32_t val) +void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val) { -stw_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN); +stw_phys_internal(as, addr, val, DEVICE_NATIVE_ENDIAN); } -void stw_le_phys(hwaddr addr, uint32_t val) +void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val) { -stw_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN); +stw_phys_internal(as, addr, val, DEVICE_LITTLE_ENDIAN); } -void stw_be_phys(hwaddr addr, uint32_t val) +void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val) { -stw_phys_internal(addr, val, DEVICE_BIG_ENDIAN); +stw_phys_internal(as, addr, val, DEVICE_BIG_ENDIAN); } /* XXX: optimize */ diff --git a/hw/net/vmware_utils.h b/hw/net/vmware_utils.h index 2ed73af..d8f734f 100644 --- a/hw/net/vmware_utils.h +++ b/hw/net/vmware_utils.h @@ -89,7 +89,7 @@ static inline void vmw_shmem_st16(hwaddr addr, uint16_t value) { VMW_SHPRN(SHMEM store16: % PRIx64 (value 0x%X), addr, value); -stw_le_phys(addr, value); +stw_le_phys(address_space_memory, addr, value); } static inline uint32_t diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c index 47a4242..b0a59c3 100644 --- a/hw/ppc/ppc405_uc.c +++ b/hw/ppc/ppc405_uc.c @@ -65,7 +65,7 @@ ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd, for (i = 0; i 6; i++) { stb_phys(bdloc + 0x24 + i, bd-bi_enetaddr[i]); } -stw_be_phys(bdloc + 0x2A, bd-bi_ethspeed); +stw_be_phys(cs-as, bdloc + 0x2A, bd-bi_ethspeed); stl_be_phys(cs-as, bdloc + 0x2C, bd-bi_intfreq); stl_be_phys(cs-as, bdloc + 0x30, bd-bi_busfreq); stl_be_phys(cs-as, bdloc + 0x34, bd-bi_baudrate); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index f47c3ec..ebf09e9 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -570,7 +570,7 @@ static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPREnvironment *spapr, stb_phys(addr, val); return H_SUCCESS; case 2: -stw_phys(addr, val); +stw_phys(cs-as, addr, val); return H_SUCCESS; case 4: stl_phys(cs-as, addr, val); @@ -635,7 +635,7 @@ static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPREnvironment *spapr, stb_phys(dst, tmp); break; case 1: -stw_phys(dst, tmp); +stw_phys(cs-as, dst, tmp); break; case 2: stl_phys(cs-as, dst, tmp); diff --git a/hw/s390x/css.c b/hw/s390x/css.c index cfa8a9b..75b04b4 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -680,7 +680,8 @@ static void css_update_chnmon(SubchDev *sch) count = lduw_phys(address_space_memory, channel_subsys-chnmon_area + offset); count++; -stw_phys(channel_subsys-chnmon_area + offset, count); +stw_phys(address_space_memory, +
[Qemu-devel] [PULL 1/3] net: Use g_strdup_printf instead of snprintf.
From: Hani Benhabiles kroo...@gmail.com assign_name() in net/net.c is using snprintf + g_strdup to get the same result as g_strdup_printf. Signed-off-by: Hani Benhabiles kroo...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- net/net.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/net.c b/net/net.c index f8db85f..2c3af20 100644 --- a/net/net.c +++ b/net/net.c @@ -164,7 +164,6 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr) static char *assign_name(NetClientState *nc1, const char *model) { NetClientState *nc; -char buf[256]; int id = 0; QTAILQ_FOREACH(nc, net_clients, next) { @@ -176,9 +175,7 @@ static char *assign_name(NetClientState *nc1, const char *model) } } -snprintf(buf, sizeof(buf), %s.%d, model, id); - -return g_strdup(buf); +return g_strdup_printf(%s.%d, model, id); } static void qemu_net_client_destructor(NetClientState *nc) -- 1.8.4.2
Re: [Qemu-devel] [PATCH v5 1/7] Convert -mem-path to QemuOpts and add prealloc, share and unlink properties
On Thu, Jan 09, 2014 at 03:59:55PM +0100, Antonios Motakis wrote: Extend -mem-path with additional properties: - prealloc=on|off - default off, same as -mem-prealloc - share=on|off - default off, memory is mmapped with MAP_SHARED flag - unlink=on|off - default on, inlink the file after openinng it Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com I like this approach and think it will work fine for my use-case, thanks. Reviewed-by: Edgar E. Iglesias edgar.igles...@xilinx.com --- exec.c | 57 +- include/exec/cpu-all.h | 3 --- qemu-options.hx| 10 +++-- vl.c | 41 +++- 4 files changed, 91 insertions(+), 20 deletions(-) diff --git a/exec.c b/exec.c index 7e49e8e..30f4019 100644 --- a/exec.c +++ b/exec.c @@ -957,6 +957,7 @@ void qemu_mutex_unlock_ramlist(void) #include sys/vfs.h #define HUGETLBFS_MAGIC 0x958458f6 +#define MIN_HUGE_PAGE_SIZE(2*1024*1024) static long gethugepagesize(const char *path) { @@ -972,8 +973,9 @@ static long gethugepagesize(const char *path) return 0; } -if (fs.f_type != HUGETLBFS_MAGIC) -fprintf(stderr, Warning: path not on HugeTLBFS: %s\n, path); +if (fs.f_type != HUGETLBFS_MAGIC) { +return 0; +} return fs.f_bsize; } @@ -994,11 +996,14 @@ static void *file_ram_alloc(RAMBlock *block, char *c; void *area; int fd; +int flags; unsigned long hpagesize; +QemuOpts *opts; +unsigned int mem_prealloc = 0, mem_share = 0, mem_unlink = 1; hpagesize = gethugepagesize(path); if (!hpagesize) { -return NULL; +hpagesize = MIN_HUGE_PAGE_SIZE; } if (memory hpagesize) { @@ -1010,6 +1015,14 @@ static void *file_ram_alloc(RAMBlock *block, return NULL; } +/* Fill config options */ +opts = qemu_opts_find(qemu_find_opts(mem-path), NULL); +if (opts) { +mem_prealloc = qemu_opt_get_bool(opts, prealloc, 0); +mem_share = qemu_opt_get_bool(opts, share, 0); +mem_unlink = qemu_opt_get_bool(opts, unlink, 1); +} + /* Make name safe to use with mkstemp by replacing '/' with '_'. */ sanitized_name = g_strdup(block-mr-name); for (c = sanitized_name; *c != '\0'; c++) { @@ -1017,20 +1030,28 @@ static void *file_ram_alloc(RAMBlock *block, *c = '_'; } -filename = g_strdup_printf(%s/qemu_back_mem.%s.XX, path, - sanitized_name); +filename = g_strdup_printf(%s/qemu_back_mem.%s%s, path, sanitized_name, + (mem_unlink) ? .XX : ); g_free(sanitized_name); -fd = mkstemp(filename); +if (mem_unlink) { +fd = mkstemp(filename); +} else { +fd = open(filename, O_CREAT | O_RDWR | O_EXCL, +S_IRWXU | S_IRWXG | S_IRWXO); +} if (fd 0) { -perror(unable to create backing store for hugepages); +perror(unable to create guest RAM backing store); g_free(filename); return NULL; } -unlink(filename); + +if (mem_unlink) { +unlink(filename); +} g_free(filename); -memory = (memory+hpagesize-1) ~(hpagesize-1); +memory = (memory + hpagesize - 1) ~(hpagesize - 1); /* * ftruncate is not supported by hugetlbfs in older @@ -1041,7 +1062,8 @@ static void *file_ram_alloc(RAMBlock *block, if (ftruncate(fd, memory)) perror(ftruncate); -area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); +flags = mem_share ? MAP_SHARED : MAP_PRIVATE; +area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0); if (area == MAP_FAILED) { perror(file_ram_alloc: can't mmap RAM pages); close(fd); @@ -1211,11 +1233,18 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, MemoryRegion *mr) { RAMBlock *block, *new_block; +QemuOpts *opts; +const char *mem_path = 0; size = TARGET_PAGE_ALIGN(size); new_block = g_malloc0(sizeof(*new_block)); new_block-fd = -1; +opts = qemu_opts_find(qemu_find_opts(mem-path), NULL); +if (opts) { +mem_path = qemu_opt_get(opts, path); +} + /* This assumes the iothread lock is taken here too. */ qemu_mutex_lock_ramlist(); new_block-mr = mr; @@ -1348,6 +1377,14 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) ram_addr_t offset; int flags; void *area, *vaddr; +QemuOpts *opts; +unsigned int mem_prealloc = 0; + +/* Fill config options */ +opts = qemu_opts_find(qemu_find_opts(mem-path), NULL); +if (opts) { +mem_prealloc =
Re: [Qemu-devel] [PATCH V5 00/10] qapi script: support enum as discriminator and better enum name
Am 20.12.2013 um 06:23 hat Wenchao Xia geschrieben: This series address two issues: 1. support using enum as discriminator in union. For example, if we have following define in qapi schema: { 'enum': 'EnumOne', 'data': [ 'value1', 'value2', 'value3' ] } { 'type': 'UserDefBase0', 'data': { 'base-string0': 'str', 'base-enum0': 'EnumOne' } } Before this series, discriminator in union must be a string, and a hidden enum type as discriminator is generated. After this series, qapi schema can directly use predefined enum type: { 'union': 'UserDefEnumDiscriminatorUnion', 'base': 'UserDefBase0', 'discriminator' : 'base-enum0', 'data': { 'value1' : 'UserDefA', 'value2' : 'UserDefInherit', 'value3' : 'UserDefB' } } The benefit is that every thing is defined explicitly in schema file, the discriminator enum type can be used in other API define in schema, and a compile time check will be put to verify the correctness according to enum define. Currently BlockdevOptions used discriminator which can be converted, in the future other union can also use enum discriminator. The implement is done by: 1.1 remember the enum defines by qapi scripts.(patch 1) 1.2 use the remembered enum define to check correctness at compile time.(patch 3), more strict check(patch 2) 1.3 use the same enum name generation rule to avoid C code mismatch, esp for case [ENUM_VALUE] in qapi-visit.c.(patch 4,5) 1.4 switch the code path, when pre-defined enum type is used as discriminator, don't generate a hidden enum type, use the enum type instead, add docs/qapi-code-gen.txt.(Patch 6) 1.5 test case shows how it looks like.(Patch 7) 1.6 convert BlockdevOptions. (Patch 8) 2. Better enum name generation Before this patch, AIOContext-A_I_O_CONTEXT, after this patch, AIOContet-AIO_CONTEXT. Since previous patch has foldered enum name generation codes into one function, it is done easily by modifying it.(Patch 9) Not reviewed the code in detail, but from a high-level view the changes make sense and I'm fine with merging it. Acked-by: Kevin Wolf kw...@redhat.com
Re: [Qemu-devel] [PATCH] tests: Correct comment for qdict_array_split test
Am 12.01.2014 um 17:01 hat Max Reitz geschrieben: The comment explaining the expected behavior was actually mistaken (the test code, however, was not). Fix this. Signed-off-by: Max Reitz mre...@redhat.com Thanks. As the original patch wasn't merged into qemu.git master yet, I have updated it with this fix. Kevin
Re: [Qemu-devel] [PATCH] tests: Correct comment for qdict_array_split test
Max Reitz mre...@redhat.com writes: The comment explaining the expected behavior was actually mistaken (the test code, however, was not). Fix this. Signed-off-by: Max Reitz mre...@redhat.com --- tests/check-qdict.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/check-qdict.c b/tests/check-qdict.c index d4ec631..7a7461b 100644 --- a/tests/check-qdict.c +++ b/tests/check-qdict.c @@ -323,11 +323,11 @@ static void qdict_array_split_test(void) * * [ * { - * a: 42 + * a: 42, + * b: 23 * }, * { - * x: 0, - * y: 1 + * x: 0 * } * ] * Looks like this is on top of [PATCH v7 21/24] tests: Add test for qdict_array_split(), which hasn't been committed, yet. Squash it in?
[Qemu-devel] [PATCH] spapr-pci: enable adding PHB via -device
Recent changes introduced cannot_instantiate_with_device_add_yet and removed capability of adding yet another PCI host bridge via command line for SPAPR platform (POWERPC64 server). This brings the capability back and puts SPAPR PHB into bridge category. This is not much use for emulated PHB but it is absolutely required for VFIO as we put an IOMMU group onto a separate PHB on SPAPR. Cc: Markus Armbruster arm...@redhat.com Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Are -device and device_add considered synonims? SPAPR PHB can be added via the command line just fine but cannot from device_add as Bus 'main-system-bus' does not support hotplugging. --- hw/ppc/spapr_pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index ec00300..66ddf10 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -728,6 +728,8 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data) dc-props = spapr_phb_properties; dc-reset = spapr_phb_reset; dc-vmsd = vmstate_spapr_pci; +set_bit(DEVICE_CATEGORY_BRIDGE, dc-categories); +dc-cannot_instantiate_with_device_add_yet = false; } static const TypeInfo spapr_phb_info = { -- 1.8.4.rc4
Re: [Qemu-devel] ARM build error/warning
On 13 January 2014 03:24, Edgar E. Iglesias edgar.igles...@gmail.com wrote: Hi, Just a heads up. I'm seeing a build warning/error on 32bit hosts. I'm on: commit dd089c0a1e928fb80ba8a37983c1b0e9232d1c8b Merge: 42bf25a 30ef3c7 Author: Anthony Liguori aligu...@amazon.com Date: Sun Jan 12 17:50:52 2014 -0800 gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) Best regards, Edgar make: Entering directory `/home/edgari/src/c/qemu/build-qemu' CCaarch64-linux-user/target-arm/cpu.o /home/edgari/src/c/qemu/qemu/target-arm/cpu.c: In function ‘arm_cpu_register_types’: /home/edgari/src/c/qemu/qemu/target-arm/cpu.c:1049:5: error: comparison of unsigned expression 0 is always false [-Werror=type-limits] Ah, this is because for the aarch64 linux-user target the 32-bit cpus array is empty. I don't think it's a specific 32-bit hosts issue, it presumably just depends on whether your C compiler complains about it or not. I build with 4.6.3, which doesn't. We had this with cpu64.c too (for a different reason) so I think the best thing here is just to switch these two arrays to loop until they hit a terminator rather than using ARRAY_SIZE. thanks -- PMM
Re: [Qemu-devel] [PATCH v6 06/11] dump: add API to write dump header
Sorry for responsing late. On 01/07/2014 07:38 PM, Laszlo Ersek wrote: The following fields in dh are left zero-filled: - timestamp - total_ram_blocks - device_blocks - written_blocks - current_cpu I guess we'll either overwrite them later or it's OK to leave them all zeroed. Yes, they are leaved all zeroed here. Tools, like crash will get exact data from dumped memory. Also... is it OK to write these fields to the file in host native byte order? What happens if an i686 / x86_64 target is emulated on a BE host? I will add convert work in v7. + +/* write sub header */ +size = sizeof(KdumpSubHeader32); +kh = g_malloc0(size); + +/* 64bit max_mapnr_64 */ +kh-max_mapnr_64 = s-max_mapnr; +kh-phys_base = PHYS_BASE; +kh-dump_level = DUMP_LEVEL; + +kh-offset_note = DISKDUMP_HEADER_BLOCKS * dh-block_size + size; +kh-note_size = s-note_size; + +if (write_buffer(s-fd, s-flag_flatten, dh-block_size, kh, size) 0) { +ret = -1; +goto out; +} - Same question about endianness as above. - Again, many fields left zeroed in kh, but I guess that's OK. - I would prefer if you repeated the multiplication by DISKDUMP_HEADER_BLOCKS verbatim in the offset write_buffer() argument. write_buffer(s-fd, s-flag_flatten, DISKDUMP_HEADER_BLOCKS * dh-block_size, kh, size) ? Yes, I should change it. - When this write_buffer() is directed to a regular file in non-flat mode, then the file might become sparse (you jump over a range of offsets with lseek() in write_buffer()). If the output has been opened by qemu itself (ie.file:, in qmp_dump_guest_memory()), then due to the O_TRUNC we can't seek over preexistent data (and keep garbage in the file). When libvirt pre-opens the file (to send over the fd later), in doCoreDump(), it also passes O_TRUNC. OK. Do you mean because of O_TRUNC,seek will exceed the end of the file that may cause some problem? -- Regards Qiao Nuohan
Re: [Qemu-devel] [PATCH RFC 2/3] qapi script: add support of event
Ping^2! Markus Armbruster arm...@redhat.com writes: Ping? Markus Armbruster arm...@redhat.com writes: [Licensing problem, cc: Anthony] Kevin Wolf kw...@redhat.com writes: Am 13.12.2013 um 14:31 hat Eric Blake geschrieben: On 11/12/2013 06:44 PM, Wenchao Xia wrote: +++ b/scripts/qapi-event.py @@ -0,0 +1,355 @@ +# +# QAPI event generator +# +# Copyright IBM, Corp. 2013 +# +# Authors: +# Wenchao Xia xiaw...@linux.vnet.ibm.com +# +# This work is licensed under the terms of the GNU GPLv2. Can you please use GPLv2+ (that is, add the or later clause)? We already have GPLv2-only code, but I don't want to increase the size of that unfortunate license choice. In fact, it's even worse: +# This work is licensed under the terms of the GNU GPLv2. +# See the COPYING.LIB file in the top-level directory. These two lines contradict each other, COPYING.LIB contains the LGPL 2.1. The same bad license header is in the other QAPI generator scripts, so it's only copypaste here. Specifically: FileCommit scripts/qapi-commands.pyc17d9908 scripts/qapi-visit.py fb3182ce scripts/qapi-types.py 06d64c62 scripts/qapi.py 0f923be2 All four from Michael Roth via Luiz. This doesn't make things easier, because if things are copied, the license of the source must be respected. And it seems rather dubious to me what this license actually is. If it's GPLv2-only, we can't just change it in the new copy. IANAL, and I wouldn't dare to judge which of the two conflicting license claims takes precedence. Possibly neither, and then the files might technically not be distributable. Anyway, this mess needs to be addressed. Michael, what was your *intended* license? If it wasn't GPLv2+, then why? Do we need formal ACKs from all contributors to fix the licensing comment in these four files?
Re: [Qemu-devel] [PATCH] Docs: Introduce multiport serial support in qemupciserial.inf
On Mi, 2014-01-08 at 17:11 +0100, Paolo Bonzini wrote: Il 08/01/2014 16:07, Yan Vugenfirer ha scritto: +%QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36DEV_0002SUBSYS_11001AF4REV_01 +%QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36DEV_0003SUBSYS_11001AF4REV_01 +%QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36DEV_0004SUBSYS_11001AF4REV_01 I think checking the subsystem is not necessary (and I think downstreams could legitimately change it). Can you check CC and REV but not SUBSYS? PNP ID can be reduced to vendor and device ID only, for example: PCI\VEN_1B36DEV_0002 . But in this case we cannot check revision. Gerd, Michael, what do you think is better? Not check revision, or enforcing subsystem? No need to check the revision. There is only one, I doubt this will ever change, and should we do a rev2 virtual hardware it is supposed to be backward-compatible to rev1 (otherwise we should hand out a new pci id to the device). [ drivers which depend on few features of the hypothetical rev2 hardware and don't work with rev1 would need a revision check ] cheers, Gerd
Re: [Qemu-devel] [PULL 03/18] vring: factor common code for error exits
On 20 December 2013 15:46, Stefan Hajnoczi stefa...@redhat.com wrote: From: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/block/dataplane/virtio-blk.c | 1 + hw/virtio/dataplane/vring.c | 34 +- 2 files changed, 22 insertions(+), 13 deletions(-) This results in a compile warning on gcc 4.6.3, I'm afraid: /home/petmay01/linaro/qemu-from-laptop/qemu/hw/virtio/dataplane/vring.c: In function ‘vring_pop’: /home/petmay01/linaro/qemu-from-laptop/qemu/hw/virtio/dataplane/vring.c:400:29: error: ‘ret’ may be used uninitialised in this function [-Werror=uninitialized] As you suggested on irc, this fixes it: diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c index 250d45e..665a1ff 100644 --- a/hw/virtio/dataplane/vring.c +++ b/hw/virtio/dataplane/vring.c @@ -376,7 +376,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, barrier(); if (desc.flags VRING_DESC_F_INDIRECT) { -int ret = get_indirect(vring, elem, desc); +ret = get_indirect(vring, elem, desc); if (ret 0) { goto out; } thanks -- PMM
[Qemu-devel] [PATCHv6 3/6] qemu-iotests: enable support for NFS protocol
Signed-off-by: Peter Lieven p...@kamp.de --- tests/qemu-iotests/common| 22 +++--- tests/qemu-iotests/common.rc |3 +++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common index 8b4e22c..5795358 100644 --- a/tests/qemu-iotests/common +++ b/tests/qemu-iotests/common @@ -144,10 +144,12 @@ check options -vpctest vpc -vhdx test vhdx -vmdk test vmdk +-file test file (default) -rbdtest rbd -sheepdog test sheepdog -nbdtest nbd -sshtest ssh +-nfstest nfs -xdiff graphical mode diff -nocacheuse O_DIRECT on backing file -misalign misalign memory allocations @@ -211,22 +213,36 @@ testlist options xpand=false ;; +-file) +IMGPROTO=file +xpand=false +;; + -rbd) IMGPROTO=rbd xpand=false ;; + -sheepdog) IMGPROTO=sheepdog xpand=false ;; + -nbd) IMGPROTO=nbd xpand=false ;; + -ssh) IMGPROTO=ssh xpand=false ;; + +-nfs) +IMGPROTO=nfs +xpand=false +;; + -nocache) CACHEMODE=none CACHEMODE_IS_DEFAULT=false @@ -238,10 +254,10 @@ testlist options xpand=false ;; --valgrind) -valgrind=true +-valgrind) +valgrind=true xpand=false -;; +;; -g)# -g group ... pick from group file group=true diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 28ba0d9..940b863 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -61,6 +61,9 @@ elif [ $IMGPROTO = nbd ]; then elif [ $IMGPROTO = ssh ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT TEST_IMG=ssh://127.0.0.1$TEST_IMG_FILE +elif [ $IMGPROTO = nfs ]; then +TEST_DIR=nfs://127.0.0.1/$TEST_DIR +TEST_IMG=$TEST_DIR/t.$IMGFMT else TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT fi -- 1.7.9.5
[Qemu-devel] [PATCHv6 4/6] qemu-iotests: enable test 016 and 025 to work with NFS protocol
Signed-off-by: Peter Lieven p...@kamp.de --- tests/qemu-iotests/016 |2 +- tests/qemu-iotests/025 |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/016 b/tests/qemu-iotests/016 index b87a32b..7ea9e94 100755 --- a/tests/qemu-iotests/016 +++ b/tests/qemu-iotests/016 @@ -39,7 +39,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 . ./common.filter _supported_fmt raw -_supported_proto file sheepdog +_supported_proto file sheepdog nfs _supported_os Linux diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025 index 9426c93..a5f45b4 100755 --- a/tests/qemu-iotests/025 +++ b/tests/qemu-iotests/025 @@ -40,7 +40,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 . ./common.pattern _supported_fmt raw qcow2 qed -_supported_proto file sheepdog rbd +_supported_proto file sheepdog rbd nfs _supported_os Linux echo === Creating image -- 1.7.9.5
[Qemu-devel] [PATCHv6 2/6] qemu-iotests: change _supported_proto to file for various tests
all these tests do anything of the following and thus fail with any protocol other than file: - the tests use rm, cp or mv shell commands which only work on file - the tests use qcow2.py - the images construct new filenames (e.g. backing file names) and the logic is broken for anything else than file Signed-off-by: Peter Lieven p...@kamp.de --- tests/qemu-iotests/013 |2 +- tests/qemu-iotests/014 |2 +- tests/qemu-iotests/018 |2 +- tests/qemu-iotests/019 |2 +- tests/qemu-iotests/020 |2 +- tests/qemu-iotests/023 |2 +- tests/qemu-iotests/024 |2 +- tests/qemu-iotests/026 |2 +- tests/qemu-iotests/028 |2 +- tests/qemu-iotests/031 |2 +- tests/qemu-iotests/034 |2 +- tests/qemu-iotests/036 |2 +- tests/qemu-iotests/037 |2 +- tests/qemu-iotests/038 |2 +- tests/qemu-iotests/039 |2 +- tests/qemu-iotests/043 |2 +- tests/qemu-iotests/046 |2 +- tests/qemu-iotests/052 |2 +- tests/qemu-iotests/054 |2 +- tests/qemu-iotests/059 |2 +- tests/qemu-iotests/060 |2 +- tests/qemu-iotests/061 |2 +- tests/qemu-iotests/063 |2 +- tests/qemu-iotests/069 |2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/qemu-iotests/013 b/tests/qemu-iotests/013 index 389f4b8..ea3cab9 100755 --- a/tests/qemu-iotests/013 +++ b/tests/qemu-iotests/013 @@ -41,7 +41,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # much of this could be generic for any format supporting compression. _supported_fmt qcow qcow2 -_supported_proto generic +_supported_proto file _supported_os Linux TEST_OFFSETS=0 4294967296 diff --git a/tests/qemu-iotests/014 b/tests/qemu-iotests/014 index 0edeb4b..b23c2db 100755 --- a/tests/qemu-iotests/014 +++ b/tests/qemu-iotests/014 @@ -43,7 +43,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # much of this could be generic for any format supporting snapshots _supported_fmt qcow2 -_supported_proto generic +_supported_proto file _supported_os Linux TEST_OFFSETS=0 4294967296 diff --git a/tests/qemu-iotests/018 b/tests/qemu-iotests/018 index 15fcfe5..aa9d3cb 100755 --- a/tests/qemu-iotests/018 +++ b/tests/qemu-iotests/018 @@ -41,7 +41,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # Any format supporting backing files _supported_fmt qcow qcow2 vmdk qed -_supported_proto generic +_supported_proto file _supported_os Linux TEST_OFFSETS=0 4294967296 diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019 index 5bb18d0..d75d125 100755 --- a/tests/qemu-iotests/019 +++ b/tests/qemu-iotests/019 @@ -45,7 +45,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # Any format supporting backing files _supported_fmt qcow qcow2 vmdk qed -_supported_proto generic +_supported_proto file _supported_os Linux TEST_OFFSETS=0 4294967296 diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020 index b3c86d8..a42f32f 100755 --- a/tests/qemu-iotests/020 +++ b/tests/qemu-iotests/020 @@ -43,7 +43,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # Any format supporting backing files _supported_fmt qcow qcow2 vmdk qed -_supported_proto generic +_supported_proto file _supported_os Linux TEST_OFFSETS=0 4294967296 diff --git a/tests/qemu-iotests/023 b/tests/qemu-iotests/023 index 090ed23..9ad06b9 100755 --- a/tests/qemu-iotests/023 +++ b/tests/qemu-iotests/023 @@ -41,7 +41,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # much of this could be generic for any format supporting compression. _supported_fmt qcow qcow2 -_supported_proto generic +_supported_proto file _supported_os Linux TEST_OFFSETS=0 4294967296 diff --git a/tests/qemu-iotests/024 b/tests/qemu-iotests/024 index be974f0..9bf99e1 100755 --- a/tests/qemu-iotests/024 +++ b/tests/qemu-iotests/024 @@ -43,7 +43,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # Currently only qcow2 and qed support rebasing _supported_fmt qcow2 qed -_supported_proto generic +_supported_proto file _supported_os Linux CLUSTER_SIZE=65536 diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026 index c9c5f83..df2884b 100755 --- a/tests/qemu-iotests/026 +++ b/tests/qemu-iotests/026 @@ -42,7 +42,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # Currently only qcow2 supports rebasing _supported_fmt qcow2 -_supported_proto generic +_supported_proto file _supported_os Linux _default_cache_mode writethrough _supported_cache_modes writethrough none diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028 index 93a9fa6..a99e4fa 100755 --- a/tests/qemu-iotests/028 +++ b/tests/qemu-iotests/028 @@ -45,7 +45,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # Any format supporting backing files except vmdk and qcow which do not support # smaller backing files. _supported_fmt qcow2 qed -_supported_proto generic +_supported_proto file _supported_os Linux # Choose a size that is not necessarily a cluster size multiple for image diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031 index c9070b0..1d920ea 100755 --- a/tests/qemu-iotests/031 +++
[Qemu-devel] [PATCHv6 5/6] qemu-iotests: fix expected output of test 067
Signed-off-by: Peter Lieven p...@kamp.de --- tests/qemu-iotests/067.out |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out index 8d271cc..79ed90f 100644 --- a/tests/qemu-iotests/067.out +++ b/tests/qemu-iotests/067.out @@ -12,7 +12,7 @@ QMP_VERSION {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_DELETED, data: {path: /machine/peripheral/virtio0/virtio-backend}} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_DELETED, data: {device: virtio0, path: /machine/peripheral/virtio0}} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: RESET} -{return: [{io-status: ok, device: ide1-cd0, locked: false, removable: true, tray_open: false, type: unknown}, {device: floppy0, locked: false, removable: true, tray_open: false, type: unknown}, {device: sd0, locked: false, removable: true, tray_open: false, type: unknown}]} +{return: [{io-status: ok, device: disk, locked: false, removable: false, inserted: {iops_rd: 0, image: {virtual-size: 134217728, filename: TEST_DIR/t.qcow2, cluster-size: 65536, format: qcow2, actual-size: SIZE, format-specific: {type: qcow2, data: {compat: 1.1, lazy-refcounts: false}}, dirty-flag: false}, iops_wr: 0, ro: false, backing_file_depth: 0, drv: qcow2, iops: 0, bps_wr: 0, encrypted: false, bps: 0, bps_rd: 0, file: TEST_DIR/t.qcow2, encryption_key_missing: false}, type: unknown}, {io-status: ok, device: ide1-cd0, locked: false, removable: true, tray_open: false, type: unknown}, {device: floppy0, locked: false, removable: true, tray_open: false, type: unknown}, {device: sd0, locked: false, removable: true, tray_open: false, type: unknown}]} {return: {}} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: SHUTDOWN} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_TRAY_MOVED, data: {device: ide1-cd0, tray-open: true}} @@ -31,7 +31,7 @@ QMP_VERSION {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_DELETED, data: {path: /machine/peripheral/virtio0/virtio-backend}} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_DELETED, data: {device: virtio0, path: /machine/peripheral/virtio0}} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: RESET} -{return: [{io-status: ok, device: ide1-cd0, locked: false, removable: true, tray_open: false, type: unknown}, {device: floppy0, locked: false, removable: true, tray_open: false, type: unknown}, {device: sd0, locked: false, removable: true, tray_open: false, type: unknown}]} +{return: [{io-status: ok, device: disk, locked: false, removable: false, inserted: {iops_rd: 0, image: {virtual-size: 134217728, filename: TEST_DIR/t.qcow2, cluster-size: 65536, format: qcow2, actual-size: SIZE, format-specific: {type: qcow2, data: {compat: 1.1, lazy-refcounts: false}}, dirty-flag: false}, iops_wr: 0, ro: false, backing_file_depth: 0, drv: qcow2, iops: 0, bps_wr: 0, encrypted: false, bps: 0, bps_rd: 0, file: TEST_DIR/t.qcow2, encryption_key_missing: false}, type: unknown}, {io-status: ok, device: ide1-cd0, locked: false, removable: true, tray_open: false, type: unknown}, {device: floppy0, locked: false, removable: true, tray_open: false, type: unknown}, {device: sd0, locked: false, removable: true, tray_open: false, type: unknown}]} {return: {}} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: SHUTDOWN} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_TRAY_MOVED, data: {device: ide1-cd0, tray-open: true}} @@ -51,7 +51,7 @@ QMP_VERSION {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_DELETED, data: {path: /machine/peripheral/virtio0/virtio-backend}} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_DELETED, data: {device: virtio0, path: /machine/peripheral/virtio0}} {timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: RESET} -{return: [{io-status: ok, device: ide1-cd0, locked: false, removable: true, tray_open: false, type: unknown}, {device: floppy0, locked: false, removable: true, tray_open: false, type: unknown}, {device: sd0, locked: false, removable: true, tray_open: false, type: unknown}]} +{return: [{io-status: ok, device: ide1-cd0, locked: false, removable: true, tray_open: false, type: unknown}, {device: floppy0, locked: false, removable: true, tray_open: false, type: unknown}, {device: sd0, locked: false, removable: true, tray_open: false, type: unknown}, {io-status: ok, device: disk, locked: false, removable: false, inserted: {iops_rd: 0, image: {virtual-size: 134217728, filename: TEST_DIR/t.qcow2, cluster-size: 65536, format: qcow2, actual-size: SIZE, format-specific: {type: qcow2, data: {compat: 1.1, lazy-refcounts: false}}, dirty-flag: false}, iops_wr: 0, ro: false, backing_file_depth: 0, drv: qcow2, iops: 0, bps_wr: 0,
[Qemu-devel] [PATCHv6 0/6] block: add native support for NFS
This adds v6 of the NFS protocol driver + qemu-iotest adjustments. v5-v6: - use internal qemu function to parse the NFS url [Kevin] - zero pad short reads [Kevin, Paolo] - added qemu-iotests patches for basic nfs protocol support v4-v5: - disussed with Ronnie and decided to move URL + Paramter parsing to LibNFS. This allows for URL parameter processing directly in LibNFS without altering the qemu NFS block driver. This bumps the version requirement for LibNFS to 1.9.0 though. - added a pointer to the LibNFS readme where additional information about ROOT privilidge requirements can be found as this raised a few concerns. - removed a trailing dot in an error statement [Fam]. v3-v4: - finally added full implementation of bdrv_get_allocated_file_size [Stefan] - removed trailing \n from error statements [Stefan] v2-v3: - rebased the stefanha/block - use pkg_config to check for libnfs (ignoring cflags which are broken in 1.8.0) [Stefan] - fixed NFSClient declaration [Stefan] - renamed Task variables to task [Stefan] - renamed NFSTask to NFSRPC [Ronnie] - do not update bs-total_sectors in nfs_co_writev [Stefan] - return -ENOMEM on all async call failures [Stefan,Ronnie] - fully implement ftruncate - use util/uri.c for URL parsing [Stefan] - reworked nfs_file_open_common to nfs_client_open which works on NFSClient [Stefan] - added a comment ot the connect message that libnfs support NFSv3 only at the moment. - DID NOT add full implementation of bdrv_get_allocated_file_size because we are not in a coroutine context and I cannot do an async call here. I could do a sync call if there would be a guarantee that no requests are in flight. [Stefan] v1-v2: - fixed block/Makefile.objs [Ronnie] - do not always register a read handler [Ronnie] - add support for reading beyond EOF [Fam] - fixed struct and paramter naming [Fam] - fixed overlong lines and whitespace errors [Fam] - return return status from libnfs whereever possible [Fam] - added comment why we set allocated_file_size to -ENOTSUP after write [Fam] - avoid segfault when parsing filname [Fam] - remove unused close_bh from NFSClient [Fam] - avoid dividing and mutliplying total_size by BDRV_SECTOR_SIZE in nfs_file_create [Fam] Peter Lieven (6): block: add native support for NFS qemu-iotests: change _supported_proto to file for various tests qemu-iotests: enable support for NFS protocol qemu-iotests: enable test 016 and 025 to work with NFS protocol qemu-iotests: fix expected output of test 067 qemu-iotests: blacklist test 020 for NFS protocol MAINTAINERS |5 + block/Makefile.objs |1 + block/nfs.c | 444 ++ configure| 26 +++ qapi-schema.json |1 + tests/qemu-iotests/013 |2 +- tests/qemu-iotests/014 |2 +- tests/qemu-iotests/016 |2 +- tests/qemu-iotests/018 |2 +- tests/qemu-iotests/019 |2 +- tests/qemu-iotests/020 |7 +- tests/qemu-iotests/023 |2 +- tests/qemu-iotests/024 |2 +- tests/qemu-iotests/025 |2 +- tests/qemu-iotests/026 |2 +- tests/qemu-iotests/028 |2 +- tests/qemu-iotests/031 |2 +- tests/qemu-iotests/034 |2 +- tests/qemu-iotests/036 |2 +- tests/qemu-iotests/037 |2 +- tests/qemu-iotests/038 |2 +- tests/qemu-iotests/039 |2 +- tests/qemu-iotests/043 |2 +- tests/qemu-iotests/046 |2 +- tests/qemu-iotests/052 |2 +- tests/qemu-iotests/054 |2 +- tests/qemu-iotests/059 |2 +- tests/qemu-iotests/060 |2 +- tests/qemu-iotests/061 |2 +- tests/qemu-iotests/063 |2 +- tests/qemu-iotests/067.out |8 +- tests/qemu-iotests/069 |2 +- tests/qemu-iotests/common| 22 ++- tests/qemu-iotests/common.rc |3 + 34 files changed, 534 insertions(+), 33 deletions(-) create mode 100644 block/nfs.c -- 1.7.9.5
[Qemu-devel] [PATCHv6 6/6] qemu-iotests: blacklist test 020 for NFS protocol
reopening is currently not supported. Signed-off-by: Peter Lieven p...@kamp.de --- tests/qemu-iotests/020 |5 + 1 file changed, 5 insertions(+) diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020 index a42f32f..f8a849c 100755 --- a/tests/qemu-iotests/020 +++ b/tests/qemu-iotests/020 @@ -46,6 +46,11 @@ _supported_fmt qcow qcow2 vmdk qed _supported_proto file _supported_os Linux +# NFS does not support bdrv_reopen_prepare thus qemu-img commit fails. +if [ $IMGPROTO = nfs ]; then +_notrun image protocol $IMGPROTO does not support bdrv_commit +fi + TEST_OFFSETS=0 4294967296 _make_test_img 6G -- 1.7.9.5
[Qemu-devel] [PATCHv6 1/6] block: add native support for NFS
This patch adds native support for accessing images on NFS shares without the requirement to actually mount the entire NFS share on the host. NFS Images can simply be specified by an url of the form: nfs://host/export/filename[?param=value[param2=value2[...]]] For example: qemu-img create -f qcow2 nfs://10.0.0.1/qemu-images/test.qcow2 You need LibNFS from Ronnie Sahlberg available at: git://github.com/sahlberg/libnfs.git for this to work. During configure it is automatically probed for libnfs and support is enabled on-the-fly. You can forbid or enforce libnfs support with --disable-libnfs or --enable-libnfs respectively. Due to NFS restrictions you might need to execute your binaries as root, allow them to open priviledged ports (1024) or specify insecure option on the NFS server. For additional information on ROOT vs. non-ROOT operation and URL format + parameters see: https://raw.github.com/sahlberg/libnfs/master/README Supported by qemu are the uid, gid and tcp-syncnt URL parameters. LibNFS currently support NFS version 3 only. Signed-off-by: Peter Lieven p...@kamp.de --- MAINTAINERS |5 + block/Makefile.objs |1 + block/nfs.c | 444 +++ configure | 26 +++ qapi-schema.json|1 + 5 files changed, 477 insertions(+) create mode 100644 block/nfs.c diff --git a/MAINTAINERS b/MAINTAINERS index fb53242..f8411f9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -936,6 +936,11 @@ M: Peter Lieven p...@kamp.de S: Supported F: block/iscsi.c +NFS +M: Peter Lieven p...@kamp.de +S: Maintained +F: block/nfs.c + SSH M: Richard W.M. Jones rjo...@redhat.com S: Supported diff --git a/block/Makefile.objs b/block/Makefile.objs index 4e8c91e..e254a21 100644 --- a/block/Makefile.objs +++ b/block/Makefile.objs @@ -12,6 +12,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o ifeq ($(CONFIG_POSIX),y) block-obj-y += nbd.o nbd-client.o sheepdog.o block-obj-$(CONFIG_LIBISCSI) += iscsi.o +block-obj-$(CONFIG_LIBNFS) += nfs.o block-obj-$(CONFIG_CURL) += curl.o block-obj-$(CONFIG_RBD) += rbd.o block-obj-$(CONFIG_GLUSTERFS) += gluster.o diff --git a/block/nfs.c b/block/nfs.c new file mode 100644 index 000..70f817e --- /dev/null +++ b/block/nfs.c @@ -0,0 +1,444 @@ +/* + * QEMU Block driver for native access to files on NFS shares + * + * Copyright (c) 2014 Peter Lieven p...@kamp.de + * + * 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 config-host.h + +#include poll.h +#include qemu-common.h +#include qemu/config-file.h +#include qemu/error-report.h +#include block/block_int.h +#include trace.h +#include qemu/iov.h +#include qemu/uri.h +#include sysemu/sysemu.h + +#include nfsc/libnfs-zdr.h +#include nfsc/libnfs.h +#include nfsc/libnfs-raw.h +#include nfsc/libnfs-raw-mount.h + +typedef struct NFSClient { +struct nfs_context *context; +struct nfsfh *fh; +int events; +bool has_zero_init; +} NFSClient; + +typedef struct NFSRPC { +int status; +int complete; +QEMUIOVector *iov; +struct stat *st; +Coroutine *co; +QEMUBH *bh; +} NFSRPC; + +static void nfs_process_read(void *arg); +static void nfs_process_write(void *arg); + +static void nfs_set_events(NFSClient *client) +{ +int ev = nfs_which_events(client-context); +if (ev != client-events) { +qemu_aio_set_fd_handler(nfs_get_fd(client-context), + (ev POLLIN) ? nfs_process_read : NULL, + (ev POLLOUT) ? nfs_process_write : NULL, + client); + +} +client-events = ev; +} + +static void nfs_process_read(void *arg) +{ +NFSClient *client = arg; +nfs_service(client-context, POLLIN); +nfs_set_events(client); +} + +static void nfs_process_write(void *arg) +{ +NFSClient *client = arg; +nfs_service(client-context, POLLOUT); +nfs_set_events(client); +} + +static void nfs_co_init_task(NFSClient *client,
[Qemu-devel] [PATCH] target-arm: Switch ARMCPUInfo arrays to use terminator entries
Switch the ARMCPUInfo arrays in cpu.c and cpu64.c to use a terminator entry rather than looping based on ARRAY_SIZE. The latter causes compile warnings on some versions of gcc if the configure options happen to result in an empty array. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- Edgar, I think this should fix the compile warning you're seeing with your gcc version. target-arm/cpu.c | 9 ++--- target-arm/cpu64.c | 15 ++- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 408d207..c77a16c 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -980,6 +980,7 @@ static const ARMCPUInfo arm_cpus[] = { { .name = any, .initfn = arm_any_initfn }, #endif #endif +{ .name = NULL } }; static Property arm_cpu_properties[] = { @@ -1043,11 +1044,13 @@ static const TypeInfo arm_cpu_type_info = { static void arm_cpu_register_types(void) { -int i; +const ARMCPUInfo *info = arm_cpus; type_register_static(arm_cpu_type_info); -for (i = 0; i ARRAY_SIZE(arm_cpus); i++) { -cpu_register(arm_cpus[i]); + +while (info-name) { +cpu_register(info); +info++; } } diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c index 60acd24..a639c2e 100644 --- a/target-arm/cpu64.c +++ b/target-arm/cpu64.c @@ -58,7 +58,7 @@ static const ARMCPUInfo aarch64_cpus[] = { #ifdef CONFIG_USER_ONLY { .name = any, .initfn = aarch64_any_initfn }, #endif -{ .name = NULL } /* TODO: drop when we support more CPUs */ +{ .name = NULL } }; static void aarch64_cpu_initfn(Object *obj) @@ -101,11 +101,6 @@ static void aarch64_cpu_register(const ARMCPUInfo *info) .class_init = info-class_init, }; -/* TODO: drop when we support more CPUs - all entries will have name set */ -if (!info-name) { -return; -} - type_info.name = g_strdup_printf(%s- TYPE_ARM_CPU, info-name); type_register(type_info); g_free((void *)type_info.name); @@ -124,11 +119,13 @@ static const TypeInfo aarch64_cpu_type_info = { static void aarch64_cpu_register_types(void) { -int i; +const ARMCPUInfo *info = aarch64_cpus; type_register_static(aarch64_cpu_type_info); -for (i = 0; i ARRAY_SIZE(aarch64_cpus); i++) { -aarch64_cpu_register(aarch64_cpus[i]); + +while (info-name) { +aarch64_cpu_register(info); +info++; } } -- 1.8.5
Re: [Qemu-devel] chroot jailing...
immersive.ex...@gmail.com immersive.ex...@gmail.com writes: Thanks! So it sounds like you're saying selinux is the only meaningful thing to try? Or do people ever bother to place qemu in chroot jails?? I seem to have gotten the impression that people use qemu-static to do this, but it appears to be more for offering secured access of a guest folder to the host OS; not so much for security... chroot() by itself is not a useful security tool. https://lwn.net/Articles/252794/
Re: [Qemu-devel] [PATCH v1 0/3] qcow2: fix bugs when cluster size is larger than the default value
ping again On Mon, Dec 30, 2013 at 01:29:06PM +0800, Hu Tao wrote: See each patches for details. Hu Tao (3): qcow2: remove n_start and n_end of qcow2_alloc_cluster_offset() qcow2: fix offset overflow qcow2: check for NULL l2meta block/qcow2-cluster.c | 14 ++ block/qcow2-refcount.c | 7 ++- block/qcow2.c | 20 +++- block/qcow2.h | 2 +- trace-events | 2 +- 5 files changed, 25 insertions(+), 20 deletions(-) -- 1.7.11.7
Re: [Qemu-devel] [RFC PATCH v4 0/4] qemu-img: add preallocation=full
ping...
[Qemu-devel] [PATCH 3/9] block: Add bdrv_dirty_bitmap_make_anon
This will unset the name of dirty bitmap. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 5 + include/block/block.h | 1 + 2 files changed, 6 insertions(+) diff --git a/block.c b/block.c index 16ef61b..f7e6851 100644 --- a/block.c +++ b/block.c @@ -4545,6 +4545,11 @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, return NULL; } +void bdrv_dirty_bitmap_make_anon(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ +bitmap-name[0] = '\0'; +} + BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity, const char *name, diff --git a/include/block/block.h b/include/block/block.h index 8dafa42..6c88f7a 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -430,6 +430,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, Error **errp); BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name); +void bdrv_dirty_bitmap_make_anon(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_reference_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); -- 1.8.5.2
[Qemu-devel] [PATCH 0/9] QMP: Introduce incremental drive-backup with in-memory dirty bitmap
This implements incremental backup. A few new QMP commands related to dirty bitmap are added: dirty-bitmap-add * dirty-bitmap-disable * dirty-bitmap-remove (*: also supported as transactions) As their name implies, they manipulate a block device's dirty bitmap. This doesn't interfere with dirty bitmap used for migration, backup, mirror, etc, which don't have a name and are invisible to user. Only named bitmaps (created by dirty-bitmap-add) can be disabled/removed by user. They are added to support user controlled write tracking, so as to determine the range of date for incremental backup. A new sync mode for drive-backup is introduced: drive-backup device=.. mode=.. sync=dirty-bitmap bitmap=bitmap0 Which will scan dirty bitmap bitmap0 and only copy all dirty sectors to target. Now, let's see the usage with a simple example: # Start the guest vm = VM() vm.start() # Fake some guest writes with qemu-io, this is before creating dirty # bitmap, so it won't be copied vm.hmp('qemu-io ide0-hd0 write -P 0xa 512k 1M') # Create a dirty bitmap to track writes vm.qmp(dirty-bitmap-add, device=ide0-hd0, name=dirty-0) # Fake some more guest writes with qemu-io, this will be copied vm.hmp('qemu-io ide0-hd0 write -P 0xa 512M 1M') # Now disable the first dirty bitmap, do the backup according to it, # at meantime continue to track dirty with a new dirty bitmap vm.qmp(transaction, actions=[ { 'type': 'dirty-bitmap-disable', 'data': { 'device': 'ide0-hd0', 'name': 'dirty-0' } }, { 'type': 'dirty-bitmap-add', 'data': { 'device': 'ide0-hd0', 'name': 'dirty-1' } }, { 'type': 'drive-backup', 'data': { 'device': 'ide0-hd0', 'target': '/tmp/incre.qcow2', 'bitmap': 'dirty-0', 'sync': 'dirty-bitmap' } } ]) # Once backup job started, the dirty bitmap can be removed (actually only # hidden from user since it is still referenced by block job vm.qmp(dirty-bitmap-remove, device=ide0-hd0, name=dirty-0) Wait the block job to complete, then let's check the target image to see what data is copied: ./qemu-img map /tmp/incre.qcow2 Offset Length Mapped to File 0x2000 0x100x16/tmp/incre.qcow2 Yes, only the data written after dirty0 creation is copied. If this interface looks good, test cases will be included in the next revision. Also, it's quite easy to use an rbd server or other protocols to do the remote backup over network. P.S. Persistent dirty bitmap could be built on top of this series, but is not yet implemented, because the storage format and integrity measures are not quite clear for now. The discussion is still open and any questions, ideas, use cases and concerns are all welcome! Fam Fam Zheng (9): block: Introduce reference count for dirty bitmaps qapi: Add optional field name to block dirty bitmap block: Add bdrv_dirty_bitmap_make_anon qmp: Add dirty-bitmap-add and dirty-bitmap-remove block: Handle error of bdrv_getlength in bdrv_create_dirty_bitmap block: Introduce bdrv_dirty_bitmap_granularity() block: Add support of dirty-bitmap sync mode qmp: Add dirty-bitmap-disable command qapi: Add transaction support to dirty-bitmap-{add,disable} block-migration.c | 3 +- block.c | 79 +-- block/backup.c| 34 +- block/mirror.c| 6 +- blockdev.c| 156 +- hmp.c | 3 +- include/block/block.h | 13 +++- include/block/block_int.h | 2 + qapi-schema.json | 79 +-- qmp-commands.hx | 61 +- 10 files changed, 416 insertions(+), 20 deletions(-) -- 1.8.5.2
[Qemu-devel] [PATCH 4/9] qmp: Add dirty-bitmap-add and dirty-bitmap-remove
The new command pair is added to manage user created dirty bitmap. The dirty bitmap's name is mandatory and must be unique for the same device, but different devices can have bitmaps with the same names. Signed-off-by: Fam Zheng f...@redhat.com --- blockdev.c | 60 qapi-schema.json | 45 ++ qmp-commands.hx | 49 + 3 files changed, 154 insertions(+) diff --git a/blockdev.c b/blockdev.c index 2c3242b..dd0f2ac 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1633,6 +1633,66 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd, } } +void qmp_dirty_bitmap_add(const char *device, const char *name, + bool has_granularity, int64_t granularity, + Error **errp) +{ +BlockDriverState *bs; +BdrvDirtyBitmap *bitmap; + +bs = bdrv_find(device); +if (!bs) { +error_set(errp, QERR_DEVICE_NOT_FOUND, device); +return; +} + +if (!name || name[0] == '\0') { +error_setg(errp, Bitmap name cannot be empty); +return; +} +if (has_granularity) { +if (granularity (granularity - 1)) { +error_setg(errp, Granularity must be power of 2); +return; +} +} else { +granularity = 65536; +} + +bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp); +if (!bitmap) { +return; +} +} + +void qmp_dirty_bitmap_remove(const char *device, const char *name, + Error **errp) +{ +BlockDriverState *bs; +BdrvDirtyBitmap *bitmap; + +bs = bdrv_find(device); +if (!bs) { +error_set(errp, QERR_DEVICE_NOT_FOUND, device); +return; +} + +if (!name || name[0] == '\0') { +error_setg(errp, Bitmap name cannot be empty); +return; +} +bitmap = bdrv_find_dirty_bitmap(bs, name); +if (!bitmap) { +error_setg(errp, Dirty bitmap not found: %s, name); +return; +} + +/* Make it invisible to user in case the following + * bdrv_release_dirty_bitmap doens't free it because of refcnt */ +bdrv_dirty_bitmap_make_anon(bs, bitmap); +bdrv_release_dirty_bitmap(bs, bitmap); +} + int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *id = qdict_get_str(qdict, id); diff --git a/qapi-schema.json b/qapi-schema.json index e91143a..095d6c0 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2062,6 +2062,51 @@ '*on-target-error': 'BlockdevOnError' } } ## +# @DirtyBitmap +# +# @device: name of device which the bitmap is tracking +# +# @name: name of the dirty bitmap +# +# @granularity: #optional the bitmap granularity, default is 64k for +# dirty-bitmap-add +# +# Since 2.0 +## +{ 'type': 'DirtyBitmap', + 'data': { 'device': 'str', 'name': 'str', '*granularity': 'int' } } + +## +# @dirty-bitmap-add +# +# Create a dirty bitmap with a name on the device +# +# Returns: nothing on success +# If @device is not a valid block device, DeviceNotFound +# If @name is already taken, GenericError with an explaining message +# +# Since 2.0 +## +{'command': 'dirty-bitmap-add', + 'data': 'DirtyBitmap' } + +## +# @dirty-bitmap-remove +# +# Remove a dirty bitmap on the device +# +# Setting granularity has no effect here. +# +# Returns: nothing on success +# If @device is not a valid block device, DeviceNotFound +# If @name is not found, GenericError with an explaining message +# +# Since 2.0 +## +{'command': 'dirty-bitmap-remove', + 'data': { 'device': 'str', 'name': 'str' } } + +## # @migrate_cancel # # Cancel the current executing migration process. diff --git a/qmp-commands.hx b/qmp-commands.hx index fba15cd..fbbf29c 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1064,6 +1064,55 @@ Example: EQMP { +.name = dirty-bitmap-add, +.args_type = device:B,name:s,granularity:i?, +.mhandler.cmd_new = qmp_marshal_input_dirty_bitmap_add, +}, +{ +.name = dirty-bitmap-remove, +.args_type = device:B,name:s, +.mhandler.cmd_new = qmp_marshal_input_dirty_bitmap_remove, +}, + +SQMP + +dirty-bitmap-add + + +Create a dirty bitmap with a name on the device, and start tracking the writes. + +Arguments: + +- device: device name to create dirty bitmap (json-string) +- name: name of the new dirty bitmap (json-string) +- granularity: granularity to track writes with. (int) + +Example: + +- { execute: dirty-bitmap-add, arguments: { device: drive0, + name: bitmap0 } } +- { return: {} } + +dirty-bitmap-remove + + +Stop write tracking and remove the dirty bitmap that was created with +dirty-bitmap-add. + +Arguments: + +- device: device name to remove dirty
[Qemu-devel] [PATCH 7/9] block: Add support of dirty-bitmap sync mode
For dirty-bitmap sync mode, the block job will iterate through the given dirty bitmap to decide if a sector needs backup (backup all the dirty clusters and skip clean ones), just as allocation conditions of top sync mode. If the dirty bitmap is updated (because of guest writes) while the block job is scanning it, an extra time of copy of written sectors could happen because of overlapping of write interception and dirty bitmap. User should build a transaction to: - Deactive the dirty bitmap. - Start a backup job with the dirty bitmap. - Create another dirty bitmap for continuity of incremental tracking. With coming dirty bitmap transaction patches. Signed-off-by: Fam Zheng f...@redhat.com --- block/backup.c| 34 +- block/mirror.c| 4 blockdev.c| 6 +- hmp.c | 3 ++- include/block/block_int.h | 2 ++ qapi-schema.json | 10 ++ qmp-commands.hx | 7 --- 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/block/backup.c b/block/backup.c index 0198514..78ca9b1 100644 --- a/block/backup.c +++ b/block/backup.c @@ -37,6 +37,8 @@ typedef struct CowRequest { typedef struct BackupBlockJob { BlockJob common; BlockDriverState *target; +BdrvDirtyBitmap *sync_bitmap; +int sync_bitmap_gran; MirrorSyncMode sync_mode; RateLimit limit; BlockdevOnError on_source_error; @@ -258,7 +260,7 @@ static void coroutine_fn backup_run(void *opaque) job-common.busy = true; } } else { -/* Both FULL and TOP SYNC_MODE's require copying.. */ +/* FULL, TOP and DIRTY_BITMAP SYNC_MODE's require copying.. */ for (; start end; start++) { bool error_is_read; @@ -312,7 +314,21 @@ static void coroutine_fn backup_run(void *opaque) if (alloced == 0) { continue; } +} else if (job-sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP) { +int i, dirty = 0; +for (i = 0; i BACKUP_SECTORS_PER_CLUSTER; + i += job-sync_bitmap_gran) { +if (bdrv_get_dirty(bs, job-sync_bitmap, +start * BACKUP_SECTORS_PER_CLUSTER + i)) { +dirty = 1; +break; +} +} +if (!dirty) { +continue; +} } + /* FULL sync mode we copy the whole drive. */ ret = backup_do_cow(bs, start * BACKUP_SECTORS_PER_CLUSTER, BACKUP_SECTORS_PER_CLUSTER, error_is_read); @@ -336,6 +352,9 @@ static void coroutine_fn backup_run(void *opaque) qemu_co_rwlock_wrlock(job-flush_rwlock); qemu_co_rwlock_unlock(job-flush_rwlock); +if (job-sync_bitmap) { +bdrv_release_dirty_bitmap(bs, job-sync_bitmap); +} hbitmap_free(job-bitmap); bdrv_iostatus_disable(target); @@ -346,6 +365,7 @@ static void coroutine_fn backup_run(void *opaque) void backup_start(BlockDriverState *bs, BlockDriverState *target, int64_t speed, MirrorSyncMode sync_mode, + BdrvDirtyBitmap *sync_bitmap, BlockdevOnError on_source_error, BlockdevOnError on_target_error, BlockDriverCompletionFunc *cb, void *opaque, @@ -364,6 +384,16 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target, return; } +if (sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP !sync_bitmap) { +error_setg(errp, must provide a valid bitmap name for \dirty-bitmap\ + sync mode); +return; +} + +if (sync_bitmap) { +bdrv_reference_dirty_bitmap(bs, sync_bitmap); +} + len = bdrv_getlength(bs); if (len 0) { error_setg_errno(errp, -len, unable to get length for '%s', @@ -381,6 +411,8 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target, job-on_target_error = on_target_error; job-target = target; job-sync_mode = sync_mode; +job-sync_bitmap = sync_bitmap; +job-sync_bitmap_gran = bdrv_dirty_bitmap_granularity(bs, job-sync_bitmap); job-common.len = len; job-common.co = qemu_coroutine_create(backup_run); qemu_coroutine_enter(job-common.co, job); diff --git a/block/mirror.c b/block/mirror.c index cc0665b..ccab15a 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -617,6 +617,10 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target, bool is_none_mode; BlockDriverState *base; +if (mode == MIRROR_SYNC_MODE_DIRTY_BITMAP) { +error_setg(errp, Sync mode 'dirty-bitmap' not supported); +return; +} is_none_mode = mode == MIRROR_SYNC_MODE_NONE; base = mode == MIRROR_SYNC_MODE_TOP ? bs-backing_hd : NULL; mirror_start_job(bs, target, speed, granularity,
[Qemu-devel] [PATCH 5/9] block: Handle error of bdrv_getlength in bdrv_create_dirty_bitmap
bdrv_getlength could fail, check the return value before using it. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index f7e6851..cc9c530 100644 --- a/block.c +++ b/block.c @@ -4568,7 +4568,12 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, } granularity = BDRV_SECTOR_BITS; assert(granularity); -bitmap_size = (bdrv_getlength(bs) BDRV_SECTOR_BITS); +bitmap_size = bdrv_getlength(bs); +if (bitmap_size 0) { +error_setg(errp, could not get length of device); +return NULL; +} +bitmap_size = BDRV_SECTOR_BITS; bitmap = g_malloc0(sizeof(BdrvDirtyBitmap)); bitmap-bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1); bitmap-refcnt = 1; -- 1.8.5.2
[Qemu-devel] [PATCH 9/9] qapi: Add transaction support to dirty-bitmap-{add, disable}
This adds dirty-bitmap-add and dirty-bitmap-disable to transactions. With this, user can stop a dirty bitmap, start backup of it, and start another dirty bitmap atomically, so that the dirty bitmap is tracked incrementally and we don't miss any write. Signed-off-by: Fam Zheng f...@redhat.com --- blockdev.c | 68 qapi-schema.json | 4 +++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/blockdev.c b/blockdev.c index 090a681..3a8fbf2 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1335,6 +1335,64 @@ static void drive_backup_abort(BlkTransactionState *common) } } +static void dirty_bitmap_add_prepare(BlkTransactionState *common, Error **errp) +{ +DirtyBitmap *action; +Error *local_err = NULL; + +action = common-action-dirty_bitmap_add; +qmp_dirty_bitmap_add(action-device, action-name, false, 0, local_err); +if (error_is_set(local_err)) { +error_propagate(errp, local_err); +} +} + +static void dirty_bitmap_add_abort(BlkTransactionState *common) +{ +DirtyBitmap *action; +BdrvDirtyBitmap *bm; +BlockDriverState *bs; + +action = common-action-dirty_bitmap_add; +bs = bdrv_find(action-device); +if (bs) { +bm = bdrv_find_dirty_bitmap(bs, action-name); +if (bm) { +bdrv_release_dirty_bitmap(bs, bm); +} +} +} + +static void dirty_bitmap_disable_prepare(BlkTransactionState *common, + Error **errp) +{ +DirtyBitmap *action; +Error *local_err = NULL; + +action = common-action-dirty_bitmap_disable; +qmp_dirty_bitmap_disable(action-device, action-name, + false, 0, local_err); +if (error_is_set(local_err)) { +error_propagate(errp, local_err); +} +} + +static void dirty_bitmap_disable_abort(BlkTransactionState *common) +{ +DirtyBitmap *action; +BdrvDirtyBitmap *bitmap; +BlockDriverState *bs; + +action = common-action-dirty_bitmap_disable; +bs = bdrv_find(action-device); +if (bs) { +bitmap = bdrv_find_dirty_bitmap(bs, action-name); +if (bitmap) { +bdrv_enable_dirty_bitmap(bs, bitmap); +} +} +} + static void abort_prepare(BlkTransactionState *common, Error **errp) { error_setg(errp, Transaction aborted using Abort action); @@ -1367,6 +1425,16 @@ static const BdrvActionOps actions[] = { .prepare = internal_snapshot_prepare, .abort = internal_snapshot_abort, }, +[TRANSACTION_ACTION_KIND_DIRTY_BITMAP_ADD] = { +.instance_size = sizeof(BlkTransactionState), +.prepare = dirty_bitmap_add_prepare, +.abort = dirty_bitmap_add_abort, +}, +[TRANSACTION_ACTION_KIND_DIRTY_BITMAP_DISABLE] = { +.instance_size = sizeof(BlkTransactionState), +.prepare = dirty_bitmap_disable_prepare, +.abort = dirty_bitmap_disable_abort, +}, }; /* diff --git a/qapi-schema.json b/qapi-schema.json index 8a81026..22cf010 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1843,7 +1843,9 @@ 'blockdev-snapshot-sync': 'BlockdevSnapshot', 'drive-backup': 'DriveBackup', 'abort': 'Abort', - 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal' + 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal', + 'dirty-bitmap-add': 'DirtyBitmap', + 'dirty-bitmap-disable': 'DirtyBitmap' } } ## -- 1.8.5.2
[Qemu-devel] [PATCH 1/9] block: Introduce reference count for dirty bitmaps
A dirty bitmap may be created by user via QMP, then reference by other QMP commands, such as backup. We need reference count machanism to manage the lifecycle of dirty bitmap. This adds bdrv_release_dirty_bitmap and changes bdrv_release_dirty_bitmap to only free the structure when refcnt goes to 0. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 17 ++--- include/block/block.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 64e7d22..6ad0368 100644 --- a/block.c +++ b/block.c @@ -51,6 +51,7 @@ struct BdrvDirtyBitmap { HBitmap *bitmap; +int refcnt; QLIST_ENTRY(BdrvDirtyBitmap) list; }; @@ -4543,6 +4544,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity) bitmap_size = (bdrv_getlength(bs) BDRV_SECTOR_BITS); bitmap = g_malloc0(sizeof(BdrvDirtyBitmap)); bitmap-bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1); +bitmap-refcnt = 1; QLIST_INSERT_HEAD(bs-dirty_bitmaps, bitmap, list); return bitmap; } @@ -4552,14 +4554,23 @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) BdrvDirtyBitmap *bm, *next; QLIST_FOREACH_SAFE(bm, bs-dirty_bitmaps, list, next) { if (bm == bitmap) { -QLIST_REMOVE(bitmap, list); -hbitmap_free(bitmap-bitmap); -g_free(bitmap); +assert(bitmap-refcnt 0); +bitmap-refcnt--; +if (bitmap-refcnt == 0) { +QLIST_REMOVE(bitmap, list); +hbitmap_free(bitmap-bitmap); +g_free(bitmap); +} return; } } } +void bdrv_reference_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ +bitmap-refcnt++; +} + BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) { BdrvDirtyBitmap *bm; diff --git a/include/block/block.h b/include/block/block.h index 36efaea..0c776e3 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -426,6 +426,7 @@ struct HBitmapIter; typedef struct BdrvDirtyBitmap BdrvDirtyBitmap; BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +void bdrv_reference_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector); void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); -- 1.8.5.2
[Qemu-devel] [PATCH 2/9] qapi: Add optional field name to block dirty bitmap
This field will be set for user created dirty bitmap. Also pass in an error pointer to bdrv_create_dirty_bitmap, so when a name is already taken on this BDS, it can report an error message. This is not global check, two BDSes can have dirty bitmap with a common name. Implemented bdrv_find_dirty_bitmap to find a dirty bitmap by name, will be used later when other QMP commands want to reference dirty bitmap by name. Signed-off-by: Fam Zheng f...@redhat.com --- block-migration.c | 3 ++- block.c | 29 - block/mirror.c| 2 +- include/block/block.h | 7 ++- qapi-schema.json | 4 +++- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/block-migration.c b/block-migration.c index 897fdba..e6e016a 100644 --- a/block-migration.c +++ b/block-migration.c @@ -315,7 +315,8 @@ static void set_dirty_tracking(void) BlkMigDevState *bmds; QSIMPLEQ_FOREACH(bmds, block_mig_state.bmds_list, entry) { -bmds-dirty_bitmap = bdrv_create_dirty_bitmap(bmds-bs, BLOCK_SIZE); +bmds-dirty_bitmap = bdrv_create_dirty_bitmap(bmds-bs, BLOCK_SIZE, + NULL, NULL); } } diff --git a/block.c b/block.c index 6ad0368..16ef61b 100644 --- a/block.c +++ b/block.c @@ -52,6 +52,7 @@ struct BdrvDirtyBitmap { HBitmap *bitmap; int refcnt; +char name[1024]; QLIST_ENTRY(BdrvDirtyBitmap) list; }; @@ -4532,19 +4533,43 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) return true; } -BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity) +BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, +const char *name) +{ +BdrvDirtyBitmap *bm; +QLIST_FOREACH(bm, bs-dirty_bitmaps, list) { +if (!strcmp(name, bm-name)) { +return bm; +} +} +return NULL; +} + +BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, + int granularity, + const char *name, + Error **errp) { int64_t bitmap_size; BdrvDirtyBitmap *bitmap; assert((granularity (granularity - 1)) == 0); +if (name bdrv_find_dirty_bitmap(bs, name)) { +if (errp) { +error_setg(errp, Bitmap already exists: %s, name); +} +return NULL; +} granularity = BDRV_SECTOR_BITS; assert(granularity); bitmap_size = (bdrv_getlength(bs) BDRV_SECTOR_BITS); bitmap = g_malloc0(sizeof(BdrvDirtyBitmap)); bitmap-bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1); bitmap-refcnt = 1; +if (name) { +pstrcpy(bitmap-name, sizeof(bitmap-name), name); +} QLIST_INSERT_HEAD(bs-dirty_bitmaps, bitmap, list); return bitmap; } @@ -4583,6 +4608,8 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) info-count = bdrv_get_dirty_count(bs, bm); info-granularity = ((int64_t) BDRV_SECTOR_SIZE hbitmap_granularity(bm-bitmap)); +info-has_name = bm-name[0] != '\0'; +info-name = g_strdup(bm-name); entry-value = info; *plist = entry; plist = entry-next; diff --git a/block/mirror.c b/block/mirror.c index 2932bab..cc0665b 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -598,7 +598,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, s-granularity = granularity; s-buf_size = MAX(buf_size, granularity); -s-dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity); +s-dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp); bdrv_set_enable_write_cache(s-target, true); bdrv_set_on_error(s-target, on_target_error, on_target_error); bdrv_iostatus_enable(s-target); diff --git a/include/block/block.h b/include/block/block.h index 0c776e3..8dafa42 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -424,7 +424,12 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov); struct HBitmapIter; typedef struct BdrvDirtyBitmap BdrvDirtyBitmap; -BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity); +BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, + int granularity, + const char *name, + Error **errp); +BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, +const char *name); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_reference_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); diff --git a/qapi-schema.json b/qapi-schema.json index b9b051c..e91143a 100644
Re: [Qemu-devel] [PATCH v6 06/11] dump: add API to write dump header
On 01/13/14 11:03, Qiao Nuohan wrote: Sorry for responsing late. On 01/07/2014 07:38 PM, Laszlo Ersek wrote: +kh-offset_note = DISKDUMP_HEADER_BLOCKS * dh-block_size + size; +kh-note_size = s-note_size; + +if (write_buffer(s-fd, s-flag_flatten, dh-block_size, kh, size) 0) { +ret = -1; +goto out; +} - I would prefer if you repeated the multiplication by DISKDUMP_HEADER_BLOCKS verbatim in the offset write_buffer() argument. write_buffer(s-fd, s-flag_flatten, DISKDUMP_HEADER_BLOCKS * dh-block_size, kh, size) ? Yes, I should change it. Yes that's what I meant. - When this write_buffer() is directed to a regular file in non-flat mode, then the file might become sparse (you jump over a range of offsets with lseek() in write_buffer()). If the output has been opened by qemu itself (ie.file:, in qmp_dump_guest_memory()), then due to the O_TRUNC we can't seek over preexistent data (and keep garbage in the file). When libvirt pre-opens the file (to send over the fd later), in doCoreDump(), it also passes O_TRUNC. OK. Do you mean because of O_TRUNC,seek will exceed the end of the file that may cause some problem? I meant that lseek() would seek over an unwritten portion of the file. If that portion had any kind of data written into it earlier, then that data would now likely turn into garbage (lose meaning, become truncated etc.) It wouldn't be corrupted or anything like that, it would just become a leftover with potential to cause misinterpretation. But, since we have O_TRUNC at open() time, we're seeking past the end of the file, and this sought-over portion will read back as zeroes (and the file might become sparse, dependent on the filesystem and the size of the range sought-over). Seeking past the end of the file is explicitly allowed by POSIX: The lseek() function shall allow the file offset to be set beyond the end of the existing data in the file. If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written into the gap. http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html So this is fine. Thanks Laszlo
[Qemu-devel] [PATCH 6/9] block: Introduce bdrv_dirty_bitmap_granularity()
This returns the granularity (in sectors) of dirty bitmap. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 6 ++ include/block/block.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/block.c b/block.c index cc9c530..0e59a9a 100644 --- a/block.c +++ b/block.c @@ -4637,6 +4637,12 @@ int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector } } +int bdrv_dirty_bitmap_granularity(BlockDriverState *bs, + BdrvDirtyBitmap *bitmap) +{ +return hbitmap_granularity(bitmap-bitmap); +} + void bdrv_dirty_iter_init(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, HBitmapIter *hbi) { diff --git a/include/block/block.h b/include/block/block.h index 6c88f7a..858baad 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -434,6 +434,8 @@ void bdrv_dirty_bitmap_make_anon(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_reference_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); +int bdrv_dirty_bitmap_granularity(BlockDriverState *bs, + BdrvDirtyBitmap *bitmap); int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector); void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); -- 1.8.5.2
[Qemu-devel] [PATCH 8/9] qmp: Add dirty-bitmap-disable command
This will put the dirty bitmap into a disabled state and no more writes will be tracked. It will be used before backup or writing to persistent file. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 15 +++ blockdev.c| 22 ++ include/block/block.h | 2 ++ qapi-schema.json | 16 qmp-commands.hx | 5 + 5 files changed, 60 insertions(+) diff --git a/block.c b/block.c index 0e59a9a..62efb93 100644 --- a/block.c +++ b/block.c @@ -53,6 +53,7 @@ struct BdrvDirtyBitmap { HBitmap *bitmap; int refcnt; char name[1024]; +bool enabled; QLIST_ENTRY(BdrvDirtyBitmap) list; }; @@ -4580,6 +4581,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, if (name) { pstrcpy(bitmap-name, sizeof(bitmap-name), name); } +bitmap-enabled = true; QLIST_INSERT_HEAD(bs-dirty_bitmaps, bitmap, list); return bitmap; } @@ -4606,6 +4608,16 @@ void bdrv_reference_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) bitmap-refcnt++; } +void bdrv_disable_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ +bitmap-enabled = false; +} + +void bdrv_enable_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ +bitmap-enabled = true; +} + BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) { BdrvDirtyBitmap *bm; @@ -4654,6 +4666,9 @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, { BdrvDirtyBitmap *bitmap; QLIST_FOREACH(bitmap, bs-dirty_bitmaps, list) { +if (!bitmap-enabled) { +continue; +} hbitmap_set(bitmap-bitmap, cur_sector, nr_sectors); } } diff --git a/blockdev.c b/blockdev.c index ac00562..090a681 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1694,6 +1694,28 @@ void qmp_dirty_bitmap_remove(const char *device, const char *name, bdrv_release_dirty_bitmap(bs, bitmap); } +void qmp_dirty_bitmap_disable(const char *device, const char *name, + bool has_granularity, int64_t granularity, + Error **errp) +{ +BlockDriverState *bs; +BdrvDirtyBitmap *bitmap; + +bs = bdrv_find(device); +if (!bs) { +error_set(errp, QERR_DEVICE_NOT_FOUND, device); +return; +} + +bitmap = bdrv_find_dirty_bitmap(bs, name); +if (!bitmap) { +error_setg(errp, Dirty bitmap not found: %s, name); +return; +} + +bdrv_disable_dirty_bitmap(bs, bitmap); +} + int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *id = qdict_get_str(qdict, id); diff --git a/include/block/block.h b/include/block/block.h index 858baad..8b9b142 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -433,6 +433,8 @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, void bdrv_dirty_bitmap_make_anon(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_reference_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +void bdrv_disable_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +void bdrv_enable_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); int bdrv_dirty_bitmap_granularity(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); diff --git a/qapi-schema.json b/qapi-schema.json index eef894c..8a81026 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2109,6 +2109,22 @@ 'data': { 'device': 'str', 'name': 'str' } } ## +# @dirty-bitmap-disable +# +# Disable a dirty bitmap on the device +# +# Setting granularity has no effect here. +# +# Returns: nothing on success +# If @device is not a valid block device, DeviceNotFound +# If @name is not found, GenericError with an explaining message +# +# Since 2.0 +## +{'command': 'dirty-bitmap-disable', + 'data': 'DirtyBitmap' } + +## # @migrate_cancel # # Cancel the current executing migration process. diff --git a/qmp-commands.hx b/qmp-commands.hx index eaae70e..88b5f58 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1074,6 +1074,11 @@ EQMP .args_type = device:B,name:s, .mhandler.cmd_new = qmp_marshal_input_dirty_bitmap_remove, }, +{ +.name = dirty-bitmap-disable, +.args_type = device:B,name:s, +.mhandler.cmd_new = qmp_marshal_input_dirty_bitmap_disable, +}, SQMP -- 1.8.5.2
Re: [Qemu-devel] [PATCH 0/2] acpi: Fix PCI hole handling on SRAT table
On Do, 2014-01-09 at 17:12 -0200, Eduardo Habkost wrote: The original SeaBIOS code used the RamSize variable, that was used by SeaBIOS for the size of RAM below 4GB, not for all RAM. When copied to QEMU, the code was changed to use the full RAM size, and this broke the build_srat() code that handles the PCI hole. This series fixes the problem by restoring the original behavior from SeaBIOS. Looks good to me. Reviewed-by: Gerd Hoffmann kra...@redhat.com cheers, Gerd
Re: [Qemu-devel] [PATCH 1/1] KVM: Retry KVM_CREATE_VM on EINTR or EAGAIN
Il 10/01/2014 23:15, Tom Knych ha scritto: I'll flip the conditional check So I traced thru the code and the one path I saw returning EINTR was: kvm_dev_ioctl_create_vm - kvm_create_vm - kvm_init_mmu_notifier - mmu_notifier_register - do_mmu_notifier_register - mm_take_all_locks Which checks if any signals have been raised while it was attaining locks and returns EINTR. Going thru my logs - all of my errors actually are EINTRs I'll remove the EAGAIN Andrea, what do you think here? Is it intended that kvm_init_mmu_notifier return an EINTR that percolates up to userspace? Paolo
Re: [Qemu-devel] Using virtio-net and vhost_net on an ARM machine using qemu-system-arm KVM
Ying-Shiuan Pan, Your experiments with arndale Exynos-5250 board can help me greatly and i would really appreciate if you share with me the following information: 1. Which Linux kernel did you use for the host and for the guest? 2. Which Linux kernel patches did you use for KVM? 3. Which config files did you use for both the host and guest? 4. Which QEMU did you use? 5. Which QEMU patches did you use? 6. What is the exact command line you used for invoking the guest, with and without vhost-net? Many thanks in advance! Regards, Barak On Mon, Jan 13, 2014 at 5:47 AM, Ying-Shiuan Pan yingshiuan@gmail.comwrote: Hi, Barak, We've tried vhost-net in kvm-arm on arndale Exynos-5250 board (it requires some patches in qemu and kvm, of course). It works (without irqfd support), however, the performance does not increase much. The throughput (iperf) of virtio-net and vhost-net are 93.5Mbps and 93.6Mbps respectively. I thought the result are because both virtio-net and vhost-net almost reached the limitation of 100Mbps Ethernet. The good news is that we even ported vhost-net in our kvm-a9 hypervisor (refer: http://academic.odysci.com/article/1010113020064758/evaluation-of-a-server-grade-software-only-arm-hypervisor), and the throughput of vhost-net on that platform (with 1Gbps Ethernet) increased from 323Mbps to 435Mbps. -- Ying-Shiuan Pan, H Div., CCMA, ITRI, TW Best Regards, 潘穎軒Ying-Shiuan Pan 2014/1/13 Peter Maydell peter.mayd...@linaro.org On 12 January 2014 21:49, Barak Wasserstrom wba...@gmail.com wrote: Thanks - I got virtio-net-device running now, but performance is terrible. When i look at the guest's ethernet interface features (ethtool -k eth0) i see all offload features are disabled. I'm using a virtual tap on the host (tap0 bridged to eth3). On the tap i also see all offload features are disabled, while on br0 and eth3 i see the expected offload features. Can this explain the terrible performance i'm facing? If so, how can this be changed? If not, what else can cause such bad performance? Do you know if vhost_net can be used on ARM Cortex A15 host/guest, even though the guest doesn't support PCI MSIX? I have no idea, I'm afraid. I don't have enough time available to investigate performance issues at the moment; if you find anything specific you can submit patches... thanks -- PMM
Re: [Qemu-devel] [PATCH v2 19/24] block: Allow wait_serialising_requests() at any point
Am 27.12.2013 um 05:17 hat Wenchao Xia geschrieben: 于 2013/12/13 21:22, Kevin Wolf 写道: We can only have a single wait_serialising_requests() call per request because otherwise we can run into deadlocks where requests are waiting for each other. do you mean: mark_request_serialising(req) ... wait_serialising_requests(req); ... wait_serialising_requests(req); will have deadlock? Yes, it can deadlock (it doesn't have to, it depends on whether another overlapping request is started concurrently). More precisely, the problematic pattern is: mark_request_serialising(req); ... qemu_coroutine_yield(); /* Other requests may be issued now */ ... wait_serialising_requests(req); What you mentioned above is a special case of this. I thought it is already resolved by patch 15? Maybe here is another deadlock reason? The problematic pattern in patch 15 was: mark_request_serialising(req); ... /* no yield here */ wait_serialising_requests(req); As opposed to the originally used: wait_serialising_requests(req); ... /* no yield here */ mark_request_serialising(req); Kevin
Re: [Qemu-devel] [PATCH 1/3] configure: add option to disable -fstack-protector flags
Il 11/01/2014 08:46, Stefan Weil ha scritto: Hi Steven, --disable-stack-protector would also be useful for platforms which make debugging of executables with stack protection difficult. When I must debug Windows executables, I always disable stack protection, because otherwise the stack back traces are unreadable. So, for MinGW it might be reasonable to set the default to no stack protection if --enable-debug is selected. This requires some modifications in your patch. # Don't set it to yes initially: stack_protector= # Do the compile test if it is not no: if test $stack_protector != no; then Apart from this little detail, the patch looks good. Steven, please resend the patch as a top-level message with the patch inline rather than attached. This is needed so that Anthony's script will pick it up. Including these changes would be nice too. Paolo The usual logic is do nothing if the user says no. Run the compile tests otherwise. Show an error message if the compile tests fail and the user said yes. See the code which handles $pie for an example. Please send your next patch inline - this makes it easier to add comments. Best regards Stefan
[Qemu-devel] [PATCH] linux-user: sync syscall numbers upto 3.13
From: Riku Voipio riku.voi...@linaro.org All others updated except unicore, which doesn't look right to begin with. Signed-off-by: Riku Voipio riku.voi...@linaro.org --- linux-user/alpha/syscall_nr.h | 7 +++ linux-user/arm/syscall_nr.h| 6 ++ linux-user/cris/syscall_nr.h | 1 + linux-user/i386/syscall_nr.h | 6 ++ linux-user/m68k/syscall_nr.h | 5 + linux-user/microblaze/syscall_nr.h | 7 ++- linux-user/mips/syscall_nr.h | 6 ++ linux-user/mips64/syscall_nr.h | 13 + linux-user/openrisc/syscall_nr.h | 6 +- linux-user/ppc/syscall_nr.h| 6 ++ linux-user/s390x/syscall_nr.h | 7 ++- linux-user/sh4/syscall_nr.h| 6 ++ linux-user/sparc/syscall_nr.h | 7 +++ linux-user/sparc64/syscall_nr.h| 7 +++ linux-user/x86_64/syscall_nr.h | 7 +++ 15 files changed, 94 insertions(+), 3 deletions(-) diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h index d52d76e..625f301 100644 --- a/linux-user/alpha/syscall_nr.h +++ b/linux-user/alpha/syscall_nr.h @@ -433,3 +433,10 @@ #define TARGET_NR_open_by_handle_at 498 #define TARGET_NR_clock_adjtime 499 #define TARGET_NR_syncfs500 +#define TARGET_NR_setns 501 +#define TARGET_NR_accept4 502 +#define TARGET_NR_sendmmsg 503 +#define TARGET_NR_process_vm_readv 504 +#define TARGET_NR_process_vm_writev 505 +#define TARGET_NR_kcmp 506 +#define TARGET_NR_finit_module 507 diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h index 42d6855..bef847c 100644 --- a/linux-user/arm/syscall_nr.h +++ b/linux-user/arm/syscall_nr.h @@ -378,3 +378,9 @@ #define TARGET_NR_open_by_handle_at(371) #define TARGET_NR_clock_adjtime(372) #define TARGET_NR_syncfs (373) +#define TARGET_NR_sendmmsg (374) +#define TARGET_NR_setns(375) +#define TARGET_NR_process_vm_readv (376) +#define TARGET_NR_process_vm_writev(377) +#define TARGET_NR_kcmp (378) +#define TARGET_NR_finit_module (379) diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h index 98f1a0b..694bd02 100644 --- a/linux-user/cris/syscall_nr.h +++ b/linux-user/cris/syscall_nr.h @@ -335,3 +335,4 @@ #define TARGET_NR_inotify_init1 332 #define TARGET_NR_preadv 333 #define TARGET_NR_pwritev334 +#define TARGET_NR_setns 335 diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h index f080305..c8f7302 100644 --- a/linux-user/i386/syscall_nr.h +++ b/linux-user/i386/syscall_nr.h @@ -347,3 +347,9 @@ #define TARGET_NR_open_by_handle_at 342 #define TARGET_NR_clock_adjtime 343 #define TARGET_NR_syncfs344 +#define TARGET_NR_sendmmsg 345 +#define TARGET_NR_setns 346 +#define TARGET_NR_process_vm_readv 347 +#define TARGET_NR_process_vm_writev 348 +#define TARGET_NR_kcmp 349 +#define TARGET_NR_finit_module 350 diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h index 4d0937e..25f8521 100644 --- a/linux-user/m68k/syscall_nr.h +++ b/linux-user/m68k/syscall_nr.h @@ -344,3 +344,8 @@ #define TARGET_NR_open_by_handle_at 341 #define TARGET_NR_clock_adjtime 342 #define TARGET_NR_syncfs343 +#define TARGET_NR_setns 344 +#define TARGET_NR_process_vm_readv 345 +#define TARGET_NR_process_vm_writev 346 +#define TARGET_NR_kcmp 347 +#define TARGET_NR_finit_module 348 diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h index f1fe0e7..6f530f9 100644 --- a/linux-user/microblaze/syscall_nr.h +++ b/linux-user/microblaze/syscall_nr.h @@ -376,4 +376,9 @@ #define TARGET_NR_open_by_handle_at 372 #define TARGET_NR_clock_adjtime 373 #define TARGET_NR_syncfs374 - +#define TARGET_NR_setns 375 +#define TARGET_NR_sendmmsg 376 +#define TARGET_NR_process_vm_readv 377 +#define TARGET_NR_process_vm_writev 378 +#define TARGET_NR_kcmp 379 +#define TARGET_NR_finit_module 380 diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h index fbdc348..2d1a13e 100644 --- a/linux-user/mips/syscall_nr.h +++ b/linux-user/mips/syscall_nr.h @@ -345,3 +345,9 @@ #define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 340) #define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 341) #define TARGET_NR_syncfs(TARGET_NR_Linux + 342) +#define TARGET_NR_sendmmsg (TARGET_NR_Linux + 343) +#define TARGET_NR_setns
Re: [Qemu-devel] [PATCH v2 1/2] hw/net: add support for Allwinner EMAC Fast Ethernet controller
On Sat, Jan 11, 2014 at 8:13 PM, Beniamino Galvani b.galv...@gmail.com wrote: This patch adds support for the Fast Ethernet MAC found on Allwinner SoCs, together with a basic emulation of Realtek RTL8201CP PHY. Since there is no public documentation of the Allwinner controller, the implementation is based on Linux kernel driver. Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- default-configs/arm-softmmu.mak |1 + hw/net/Makefile.objs|1 + hw/net/allwinner_emac.c | 472 +++ include/hw/net/allwinner_emac.h | 204 + 4 files changed, 678 insertions(+) create mode 100644 hw/net/allwinner_emac.c create mode 100644 include/hw/net/allwinner_emac.h diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index ce1d620..f3513fa 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -27,6 +27,7 @@ CONFIG_SSI_SD=y CONFIG_SSI_M25P80=y CONFIG_LAN9118=y CONFIG_SMC91C111=y +CONFIG_ALLWINNER_EMAC=y CONFIG_DS1338=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index 951cca3..75e80c2 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o common-obj-$(CONFIG_XGMAC) += xgmac.o common-obj-$(CONFIG_MIPSNET) += mipsnet.o common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o +common-obj-$(CONFIG_ALLWINNER_EMAC) += allwinner_emac.o common-obj-$(CONFIG_CADENCE) += cadence_gem.o common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c new file mode 100644 index 000..0c37df2 --- /dev/null +++ b/hw/net/allwinner_emac.c @@ -0,0 +1,472 @@ +/* + * Emulation of Allwinner EMAC Fast Ethernet controller and + * Realtek RTL8201CP PHY + * + * Copyright (C) 2013 Beniamino Galvani b.galv...@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include hw/sysbus.h +#include net/net.h +#include hw/net/allwinner_emac.h +#include zlib.h + +static void mii_set_link(AwEmacMii *mii, bool link_ok) +{ +if (link_ok) { +mii-bmsr |= MII_BMSR_LINK_ST; +mii-anlpar |= MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | + MII_ANAR_10 | MII_ANAR_CSMACD; mii-anlpar.MII_ANAR_TX is always set so you can drop its transient setting entirely. Here and below. +} else { +mii-bmsr = ~MII_BMSR_LINK_ST; +mii-anlpar = MII_ANAR_TX; +} +mii-link_ok = link_ok; +} + +static void mii_reset(AwEmacMii *mii) +{ +mii-bmcr = MII_BMCR_FD | MII_BMCR_AUTOEN | MII_BMCR_SPEED; +mii-bmsr = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD | +MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AUTONEG; +mii-anar = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | MII_ANAR_10 | +MII_ANAR_CSMACD; +mii-anlpar = MII_ANAR_TX; +mii_set_link(mii, mii-link_ok); If this is actually needed, it smells like a bug in the net layer. Is the net layer not doing it's resets properly? It's quite odd that you are preserving old state across a reset. +} + +static uint16_t mii_read(AwEmacMii *mii, uint8_t addr, uint8_t reg) From the architectural discussion RE MII/MDIO busification we concluded to limit to MDIO only. So I think this should be *_mdio_read. A device specific prefix would be good as well. +{ +uint16_t ret = 0x; + +if (addr == mii-phy_addr) { +switch (reg) { +case MII_BMCR: +ret = mii-bmcr; +break; +case MII_BMSR: +ret = mii-bmsr; +break; +case MII_PHYID1: +ret = RTL8201CP_PHYID1; And this PHY is really the RTL8201CP not an allwinner phy. Despite being married to the allwinner EMAC for the moment (pending the PHY refactorings) you should badge the PHY with its proper name something like s/AwEmacMii/RTL8201CPState. +break; +case MII_PHYID2: +ret = RTL8201CP_PHYID2; +break; +case MII_ANAR: +ret = mii-anar; +break; +case MII_ANLPAR: +ret = mii-anlpar; +break; +default: +qemu_log_mask(LOG_UNIMP, + allwinner_emac: read from unknown mii reg 0x%x\n, + reg); Is this really a
Re: [Qemu-devel] [PATCH v2 1/2] hw/net: add support for Allwinner EMAC Fast Ethernet controller
cc Stefan On Mon, Jan 13, 2014 at 11:15 PM, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Sat, Jan 11, 2014 at 8:13 PM, Beniamino Galvani b.galv...@gmail.com wrote: This patch adds support for the Fast Ethernet MAC found on Allwinner SoCs, together with a basic emulation of Realtek RTL8201CP PHY. Since there is no public documentation of the Allwinner controller, the implementation is based on Linux kernel driver. Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- default-configs/arm-softmmu.mak |1 + hw/net/Makefile.objs|1 + hw/net/allwinner_emac.c | 472 +++ include/hw/net/allwinner_emac.h | 204 + 4 files changed, 678 insertions(+) create mode 100644 hw/net/allwinner_emac.c create mode 100644 include/hw/net/allwinner_emac.h diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index ce1d620..f3513fa 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -27,6 +27,7 @@ CONFIG_SSI_SD=y CONFIG_SSI_M25P80=y CONFIG_LAN9118=y CONFIG_SMC91C111=y +CONFIG_ALLWINNER_EMAC=y CONFIG_DS1338=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index 951cca3..75e80c2 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o common-obj-$(CONFIG_XGMAC) += xgmac.o common-obj-$(CONFIG_MIPSNET) += mipsnet.o common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o +common-obj-$(CONFIG_ALLWINNER_EMAC) += allwinner_emac.o common-obj-$(CONFIG_CADENCE) += cadence_gem.o common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c new file mode 100644 index 000..0c37df2 --- /dev/null +++ b/hw/net/allwinner_emac.c @@ -0,0 +1,472 @@ +/* + * Emulation of Allwinner EMAC Fast Ethernet controller and + * Realtek RTL8201CP PHY + * + * Copyright (C) 2013 Beniamino Galvani b.galv...@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include hw/sysbus.h +#include net/net.h +#include hw/net/allwinner_emac.h +#include zlib.h + +static void mii_set_link(AwEmacMii *mii, bool link_ok) +{ +if (link_ok) { +mii-bmsr |= MII_BMSR_LINK_ST; +mii-anlpar |= MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | + MII_ANAR_10 | MII_ANAR_CSMACD; mii-anlpar.MII_ANAR_TX is always set so you can drop its transient setting entirely. Here and below. +} else { +mii-bmsr = ~MII_BMSR_LINK_ST; +mii-anlpar = MII_ANAR_TX; +} +mii-link_ok = link_ok; +} + +static void mii_reset(AwEmacMii *mii) +{ +mii-bmcr = MII_BMCR_FD | MII_BMCR_AUTOEN | MII_BMCR_SPEED; +mii-bmsr = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD | +MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AUTONEG; +mii-anar = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | MII_ANAR_10 | +MII_ANAR_CSMACD; +mii-anlpar = MII_ANAR_TX; +mii_set_link(mii, mii-link_ok); If this is actually needed, it smells like a bug in the net layer. Is the net layer not doing it's resets properly? It's quite odd that you are preserving old state across a reset. +} + +static uint16_t mii_read(AwEmacMii *mii, uint8_t addr, uint8_t reg) From the architectural discussion RE MII/MDIO busification we concluded to limit to MDIO only. So I think this should be *_mdio_read. A device specific prefix would be good as well. +{ +uint16_t ret = 0x; + +if (addr == mii-phy_addr) { +switch (reg) { +case MII_BMCR: +ret = mii-bmcr; +break; +case MII_BMSR: +ret = mii-bmsr; +break; +case MII_PHYID1: +ret = RTL8201CP_PHYID1; And this PHY is really the RTL8201CP not an allwinner phy. Despite being married to the allwinner EMAC for the moment (pending the PHY refactorings) you should badge the PHY with its proper name something like s/AwEmacMii/RTL8201CPState. +break; +case MII_PHYID2: +ret = RTL8201CP_PHYID2; +break; +case MII_ANAR: +ret = mii-anar; +break; +case MII_ANLPAR: +ret = mii-anlpar; +break; +default: +qemu_log_mask(LOG_UNIMP, +
Re: [Qemu-devel] [PATCH] linux-user: sync syscall numbers upto 3.13
On 13 January 2014 12:33, riku.voi...@linaro.org wrote: From: Riku Voipio riku.voi...@linaro.org All others updated except unicore, which doesn't look right to begin with. Yes, I've noticed before that the Unicore syscall numbers are just completely wrong. Guan, would you like to submit a patch to fix them or should we just rip out the linux-user support for unicore completely? There's no point carrying something around that won't be able to do even basic syscalls... thanks -- PMM
Re: [Qemu-devel] [PATCH] block/vmdk: add basic .bdrv_check support
On Mon, 01/13 12:24, Peter Lieven wrote: this adds a basic vmdk corruption check. it should detect severe table corruptions and file truncation. Signed-off-by: Peter Lieven p...@kamp.de --- block/vmdk.c | 46 ++ 1 file changed, 46 insertions(+) diff --git a/block/vmdk.c b/block/vmdk.c index c6b60b4..1d66858 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1918,6 +1918,51 @@ static ImageInfo *vmdk_get_extent_info(VmdkExtent *extent) return info; } +static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result, + BdrvCheckMode fix) +{ +BDRVVmdkState *s = bs-opaque; +VmdkExtent *extent = NULL; +int64_t sector_num = 0; +int64_t total_sectors = bdrv_getlength(bs) / BDRV_SECTOR_SIZE; +int ret; +uint64_t cluster_offset; + +if (fix) { +return -ENOTSUP; +} + +for (;;) { +if (sector_num = total_sectors) { +return 0; +} +extent = find_extent(s, sector_num, extent); +if (!extent) { +fprintf(stderr, ERROR: could not find extend for sector %ld\n, +sector_num); +break; +} +ret = get_cluster_offset(bs, extent, NULL, sector_num BDRV_SECTOR_BITS, + 0, cluster_offset); +if (ret == VMDK_ERROR) { +fprintf(stderr, +ERROR: could not get cluster_offset for sector %ld\n, +sector_num); +break; +} +if (ret == VMDK_OK cluster_offset = bdrv_getlength(extent-file)) { +fprintf(stderr, +ERROR: cluster offset for sector %ld points after EOF\n, +sector_num); +break; +} +sector_num += extent-cluster_sectors; +} + +result-corruptions++; +return 0; +} + static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs) { int i; @@ -1991,6 +2036,7 @@ static BlockDriver bdrv_vmdk = { .instance_size= sizeof(BDRVVmdkState), .bdrv_probe = vmdk_probe, .bdrv_open= vmdk_open, +.bdrv_check = vmdk_check, .bdrv_reopen_prepare = vmdk_reopen_prepare, .bdrv_read= vmdk_co_read, .bdrv_write = vmdk_co_write, Works for me. Thank. And BTW, is it worth comparing with the grain_offset header field? This should be the first data cluster's offset. When you have a fresh image with no data cluster allocated, and it's truncated, this patch doesn't catch it. Anyway, Reviewed-by: Fam Zheng f...@redhat.com
Re: [Qemu-devel] [PATCH 1/5] net: extend NetClientInfo for offloading manipulations
Ok. I did not include those modifications into the patch in order to avoid modifications to the TAP netdev. 2014/1/13 Stefan Hajnoczi stefa...@gmail.com On Fri, Dec 13, 2013 at 01:04:59PM +0100, Vincenzo Maffione wrote: diff --git a/include/net/net.h b/include/net/net.h index 11e1468..f5b5bae 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -50,6 +50,12 @@ typedef void (NetCleanup) (NetClientState *); typedef void (LinkStatusChanged)(NetClientState *); typedef void (NetClientDestructor)(NetClientState *); typedef RxFilterInfo *(QueryRxFilter)(NetClientState *); +typedef bool (HasUfo)(NetClientState *); +typedef int (HasVnetHdr)(NetClientState *); Please change the return type to bool. bool is easier to understand since the reader can be sure the variable only takes true/false values. +typedef int (HasVnetHdrLen)(NetClientState *, int); Please change the return type to bool. -- Vincenzo Maffione
[Qemu-devel] [PATCH v2 06/10] target-arm: A64: Add SIMD ZIP/UZP/TRN
From: Michael Matz m...@suse.de Add support for the SIMD ZIP/UZIP/TRN instruction group (C3.6.3). Signed-off-by: Michael Matz m...@suse.de [PMM: use new do_vec_get/set etc functions and generally update to new codebase standards; refactor to pull per-element loop outside switch] Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 76 +- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 3eae175..1c28c0f 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -4807,7 +4807,81 @@ static void disas_simd_tb(DisasContext *s, uint32_t insn) */ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int rm = extract32(insn, 16, 5); +int size = extract32(insn, 22, 2); +/* opc field bits [1:0] indicate ZIP/UZP/TRN; + * bit 2 indicates 1 vs 2 variant of the insn. + */ +int opcode = extract32(insn, 12, 2); +bool part = extract32(insn, 14, 1); +bool is_q = extract32(insn, 30, 1); +int esize = 8 size; +int i, ofs; +int datasize = is_q ? 128 : 64; +int elements = datasize / esize; +TCGv_i64 tcg_res, tcg_resl, tcg_resh; + +if (opcode == 0 || (size == 3 !is_q)) { +unallocated_encoding(s); +return; +} + +tcg_resl = tcg_const_i64(0); +tcg_resh = tcg_const_i64(0); +tcg_res = tcg_temp_new_i64(); + +for (i = 0; i elements; i++) { +switch (opcode) { +case 1: /* UZP1/2 */ +{ +int midpoint = elements / 2; +if (i midpoint) { +read_vec_element(s, tcg_res, rn, 2 * i + part, size); +} else { +read_vec_element(s, tcg_res, rm, + 2 * (i - midpoint) + part, size); +} +break; +} +case 2: /* TRN1/2 */ +if (i 1) { +read_vec_element(s, tcg_res, rm, (i ~1) + part, size); +} else { +read_vec_element(s, tcg_res, rn, (i ~1) + part, size); +} +break; +case 3: /* ZIP1/2 */ +{ +int base = part * elements / 2; +if (i 1) { +read_vec_element(s, tcg_res, rm, base + (i 1), size); +} else { +read_vec_element(s, tcg_res, rn, base + (i 1), size); +} +break; +} +default: +g_assert_not_reached(); +} + +ofs = i * esize; +if (ofs 64) { +tcg_gen_shli_i64(tcg_res, tcg_res, ofs); +tcg_gen_or_i64(tcg_resl, tcg_resl, tcg_res); +} else { +tcg_gen_shli_i64(tcg_res, tcg_res, ofs - 64); +tcg_gen_or_i64(tcg_resh, tcg_resh, tcg_res); +} +} + +tcg_temp_free_i64(tcg_res); + +write_vec_element(s, tcg_resl, rd, 0, MO_64); +tcg_temp_free_i64(tcg_resl); +write_vec_element(s, tcg_resh, rd, 1, MO_64); +tcg_temp_free_i64(tcg_resh); } /* C3.6.4 AdvSIMD across lanes -- 1.8.5
[Qemu-devel] [PATCH v2 10/10] target-arm: A64: Add SIMD scalar copy instructions
Add support for the SIMD scalar copy instruction group (C3.6.7), which consists of the single instruction DUP (element, scalar). Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- v1-v2: fixed error in insn diagram comment --- target-arm/translate-a64.c | 42 +- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 5f56db9..2870675 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5109,6 +5109,35 @@ static void handle_simd_dupe(DisasContext *s, int is_q, int rd, int rn, tcg_temp_free_i64(tmp); } +/* C6.3.31 DUP (element, scalar) + * 31 21 2016 1510 95 40 + * +---++-+--+--+ + * | 0 1 0 1 1 1 1 0 0 0 0 | imm5 | 0 0 0 0 0 1 | Rn | Rd | + * +---++-+--+--+ + */ +static void handle_simd_dupes(DisasContext *s, int rd, int rn, + int imm5) +{ +int size = ctz32(imm5); +int index; +TCGv_i64 tmp; + +if (size 3) { +unallocated_encoding(s); +return; +} + +index = imm5 (size + 1); + +/* This instruction just extracts the specified element and + * zero-extends it into the bottom of the destination register. + */ +tmp = tcg_temp_new_i64(); +read_vec_element(s, tmp, rn, index, size); +write_fp_dreg(s, rd, tmp); +tcg_temp_free_i64(tmp); +} + /* C6.3.32 DUP (General) * * 31 30 29 21 2016 1510 95 40 @@ -5426,7 +5455,18 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn) */ static void disas_simd_scalar_copy(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int imm4 = extract32(insn, 11, 4); +int imm5 = extract32(insn, 16, 5); +int op = extract32(insn, 29, 1); + +if (op != 0 || imm4 != 0) { +unallocated_encoding(s); +} + +/* DUP (element, scalar) */ +handle_simd_dupes(s, rd, rn, imm5); } /* C3.6.8 AdvSIMD scalar pairwise -- 1.8.5
[Qemu-devel] [PATCH v2 09/10] target-arm: A64: Add SIMD modified immediate group
From: Alex Bennée alex.ben...@linaro.org This patch adds support for the AdvSIMD modified immediate group (C3.6.6) with all its suboperations (movi, orr, fmov, mvni, bic). Signed-off-by: Alexander Graf ag...@suse.de [AJB: new decode struct, minor bug fixes, optimisation] Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- v1-v2: use bitfield_replicate() rather than opencoded shift-and-or --- target-arm/translate-a64.c | 120 - 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 85daca9..5f56db9 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5294,10 +5294,128 @@ static void disas_simd_copy(DisasContext *s, uint32_t insn) * +---+---++-+-+---++---+---+--+ * | 0 | Q | op | 0 1 1 1 1 0 0 0 0 0 | abc | cmode | o2 | 1 | defgh | Rd | * +---+---++-+-+---++---+---+--+ + * + * There are a number of operations that can be carried out here: + * MOVI - move (shifted) imm into register + * MVNI - move inverted (shifted) imm into register + * ORR - bitwise OR of (shifted) imm with register + * BIC - bitwise clear of (shifted) imm with register */ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int cmode = extract32(insn, 12, 4); +int cmode_3_1 = extract32(cmode, 1, 3); +int cmode_0 = extract32(cmode, 0, 1); +int o2 = extract32(insn, 11, 1); +uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) 5); +bool is_neg = extract32(insn, 29, 1); +bool is_q = extract32(insn, 30, 1); +uint64_t imm = 0; +TCGv_i64 tcg_rd, tcg_imm; +int i; + +if (o2 != 0 || ((cmode == 0xf) is_neg !is_q)) { +unallocated_encoding(s); +return; +} + +/* See AdvSIMDExpandImm() in ARM ARM */ +switch (cmode_3_1) { +case 0: /* Replicate(Zeros(24):imm8, 2) */ +case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */ +case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */ +case 3: /* Replicate(imm8:Zeros(24), 2) */ +{ +int shift = cmode_3_1 * 8; +imm = bitfield_replicate(abcdefgh shift, 32); +break; +} +case 4: /* Replicate(Zeros(8):imm8, 4) */ +case 5: /* Replicate(imm8:Zeros(8), 4) */ +{ +int shift = (cmode_3_1 0x1) * 8; +imm = bitfield_replicate(abcdefgh shift, 16); +break; +} +case 6: +if (cmode_0) { +/* Replicate(Zeros(8):imm8:Ones(16), 2) */ +imm = (abcdefgh 16) | 0x; +} else { +/* Replicate(Zeros(16):imm8:Ones(8), 2) */ +imm = (abcdefgh 8) | 0xff; +} +imm = bitfield_replicate(imm, 32); +break; +case 7: +if (!cmode_0 !is_neg) { +imm = bitfield_replicate(abcdefgh, 8); +} else if (!cmode_0 is_neg) { +int i; +imm = 0; +for (i = 0; i 8; i++) { +if ((abcdefgh) (1 i)) { +imm |= 0xffULL (i * 8); +} +} +} else if (cmode_0) { +if (is_neg) { +imm = (abcdefgh 0x3f) 48; +if (abcdefgh 0x80) { +imm |= 0x8000ULL; +} +if (abcdefgh 0x40) { +imm |= 0x3fc0ULL; +} else { +imm |= 0x4000ULL; +} +} else { +imm = (abcdefgh 0x3f) 19; +if (abcdefgh 0x80) { +imm |= 0x8000; +} +if (abcdefgh 0x40) { +imm |= 0x3e00; +} else { +imm |= 0x4000; +} +imm |= (imm 32); +} +} +break; +} + +if (cmode_3_1 != 7 is_neg) { +imm = ~imm; +} + +tcg_imm = tcg_const_i64(imm); +tcg_rd = new_tmp_a64(s); + +for (i = 0; i 2; i++) { +int foffs = i ? fp_reg_hi_offset(rd) : fp_reg_offset(rd, MO_64); + +if (i == 1 !is_q) { +/* non-quad ops clear high half of vector */ +tcg_gen_movi_i64(tcg_rd, 0); +} else if ((cmode 0x9) == 0x1 || (cmode 0xd) == 0x9) { +tcg_gen_ld_i64(tcg_rd, cpu_env, foffs); +if (is_neg) { +/* AND (BIC) */ +tcg_gen_and_i64(tcg_rd, tcg_rd, tcg_imm); +} else { +/* ORR */ +tcg_gen_or_i64(tcg_rd, tcg_rd, tcg_imm); +} +} else { +/* MOVI */ +tcg_gen_mov_i64(tcg_rd, tcg_imm); +} +
[Qemu-devel] [PATCH v2 02/10] target-arm: A64: Add SIMD ld/st single
Implement the SIMD ld/st single structure instructions. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- public v1-v2 changes: * same tcg_rn cleanup/fix as ld/st multiple --- target-arm/translate-a64.c | 144 - 1 file changed, 142 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index e4fdf00..6e31740 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -2087,10 +2087,150 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn) tcg_temp_free_i64(tcg_addr); } -/* AdvSIMD load/store single structure */ +/* C3.3.3 AdvSIMD load/store single structure + * + * 31 30 29 23 22 21 20 16 15 13 12 11 10 95 40 + * +---+---+---+-+---+-+---+--+--+--+ + * | 0 | Q | 0 0 1 1 0 1 0 | L R | 0 0 0 0 0 | opc | S | size | Rn | Rt | + * +---+---+---+-+---+-+---+--+--+--+ + * + * C3.3.4 AdvSIMD load/store single structure (post-indexed) + * + * 31 30 29 23 22 21 20 16 15 13 12 11 10 95 40 + * +---+---+---+-+---+-+---+--+--+--+ + * | 0 | Q | 0 0 1 1 0 1 1 | L R | Rm| opc | S | size | Rn | Rt | + * +---+---+---+-+---+-+---+--+--+--+ + * + * Rt: first (or only) SIMDFP register to be transferred + * Rn: base address or SP + * Rm (post-index only): post-index register (when !31) or size dependent #imm + * index = encoded in Q:S:size dependent on size + * + * lane_size = encoded in R, opc + * transfer width = encoded in opc, S, size + */ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rt = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int size = extract32(insn, 10, 2); +int S = extract32(insn, 12, 1); +int opc = extract32(insn, 13, 3); +int R = extract32(insn, 21, 1); +int is_load = extract32(insn, 22, 1); +int is_postidx = extract32(insn, 23, 1); +int is_q = extract32(insn, 30, 1); + +int scale = extract32(opc, 1, 2); +int selem = (extract32(opc, 0, 1) 1 | R) + 1; +bool replicate = false; +int index = is_q 3 | S 2 | size; +int ebytes, xs; +TCGv_i64 tcg_addr, tcg_rn; + +switch (scale) { +case 3: +if (!is_load || S) { +unallocated_encoding(s); +return; +} +scale = size; +replicate = true; +break; +case 0: +break; +case 1: +if (extract32(size, 0, 1)) { +unallocated_encoding(s); +return; +} +index = 1; +break; +case 2: +if (extract32(size, 1, 1)) { +unallocated_encoding(s); +return; +} +if (!extract32(size, 0, 1)) { +index = 2; +} else { +if (S) { +unallocated_encoding(s); +return; +} +index = 3; +scale = 3; +} +break; +default: +g_assert_not_reached(); +} + +ebytes = 1 scale; + +if (rn == 31) { +gen_check_sp_alignment(s); +} + +tcg_rn = cpu_reg_sp(s, rn); +tcg_addr = tcg_temp_new_i64(); +tcg_gen_mov_i64(tcg_addr, tcg_rn); + +for (xs = 0; xs selem; xs++) { +if (replicate) { +/* Load and replicate to all elements */ +uint64_t mulconst; +TCGv_i64 tcg_tmp = tcg_temp_new_i64(); + +tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, +get_mem_index(s), MO_TE + scale); +switch (scale) { +case 0: +mulconst = 0x0101010101010101ULL; +break; +case 1: +mulconst = 0x0001000100010001ULL; +break; +case 2: +mulconst = 0x00010001ULL; +break; +case 3: +mulconst = 0; +break; +default: +g_assert_not_reached(); +} +if (mulconst) { +tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst); +} +write_vec_element(s, tcg_tmp, rt, 0, MO_64); +if (is_q) { +write_vec_element(s, tcg_tmp, rt, 1, MO_64); +} else { +clear_vec_high(s, rt); +} +tcg_temp_free_i64(tcg_tmp); +} else { +/* Load/store one element per register */ +if (is_load) { +do_vec_ld(s, rt, index, tcg_addr, MO_TE + scale); +} else { +do_vec_st(s, rt, index, tcg_addr, MO_TE + scale); +} +} +tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes); +rt = (rt + 1) % 32; +} + +if (is_postidx) { +
[Qemu-devel] [PATCH v2 00/10] A64 SIMD patchset one: ld/st, C3.6.1..C3.6.7
This is an initial set of patches which make a start on SIMD (Neon) emulation in the A64 decoder. The patches implement all the SIMD load/store operations, provide a decoder skeleton for the SIMD dp instructions, and implement all the instructions in the ARM ARM's groupings C3.6.1 through C3.6.7. Changes v1-v2: * minor tweaks as suggested by rth (noted more specifically below the fold in the affected patches) * reworked EXT to do vector accesses outside do_ext64 and thus avoid accessing the middle element twice * fixed incorrect handling of rn==sp, cleaned up tcg_rn code in the ld/st single and multiple patches thanks -- PMM Alex Bennée (4): target-arm: A64: Add SIMD ld/st multiple target-arm: A64: Add decode skeleton for SIMD data processing insns target-arm: A64: Add SIMD copy operations target-arm: A64: Add SIMD modified immediate group Michael Matz (3): target-arm: A64: Add SIMD TBL/TBLX target-arm: A64: Add SIMD ZIP/UZP/TRN target-arm: A64: Add SIMD across-lanes instructions Peter Maydell (3): target-arm: A64: Add SIMD ld/st single target-arm: A64: Add SIMD EXT target-arm: A64: Add SIMD scalar copy instructions target-arm/helper-a64.c| 31 + target-arm/helper-a64.h|1 + target-arm/translate-a64.c | 1454 +++- 3 files changed, 1477 insertions(+), 9 deletions(-) -- 1.8.5
[Qemu-devel] [PATCH v6 0/8] Vhost and vhost-net support for userspace based backends
In this patch series we would like to introduce our approach for putting a virtio-net backend in an external userspace process. Our eventual target is to run the network backend in the Snabbswitch ethernet switch, while receiving traffic from a guest inside QEMU/KVM which runs an unmodified virtio-net implementation. For this, we are working into extending vhost to allow equivalent functionality for userspace. Vhost already passes control of the data plane of virtio-net to the host kernel; we want to realize a similar model, but for userspace. In this patch series the concept of a vhost-backend is introduced. We define two vhost backend types - vhost-kernel and vhost-user. The former is the interface to the current kernel module implementation. Its control plane is ioctl based. The data plane is the kernel directly accessing the QEMU allocated, guest memory. In the new vhost-user backend, the control plane is based on communication between QEMU and another userspace process using a unix domain socket. This allows to implement a virtio backend for a guest running in QEMU, inside the other userspace process. We change -mem-path to QemuOpts and add prealloc, share and unlink as properties to it. HugeTLBFS requirements of -mem-path are relaxed, so any valid path can be used now. The new properties allow more fine grained control over the guest RAM backing store. The data path is realized by directly accessing the vrings and the buffer data off the guest's memory. The current user of vhost-user is only vhost-net. We add new netdev backend that is intended to initialize vhost-net with vhost-user backend. Example usage: qemu -m 1024 -mem-path /hugetlbfs,prealloc=on,share=on \ -netdev type=vhost-user,id=net0,path=/path/to/sock,poll_time=2500 \ -device virtio-net-pci,netdev=net0 Changes from v5: - Split -mem-path unlink option to a separate patch - Fds are passed only in the ancillary data - Stricter message size checks on receive/send - Netdev vhost-user now includes path and poll_time options - The connection probing interval is configurable Changes from v4: - Use error_report for errors - VhostUserMsg has new field `size` indicating the following payload length. Field `flags` now has version and reply bits. The structure is packed. - Send data is of variable length (`size` field in message) - Receive in 2 steps, header and payload - Add new message type VHOST_USER_ECHO, to check connection status Changes from v3: - Convert -mem-path to QemuOpts with prealloc, share and unlink properties - Set 1 sec timeout when read/write to the unix domain socket - Fix file descriptor leak Changes from v2: - Reconnect when the backend disappears Changes from v1: - Implementation of vhost-user netdev backend - Code improvements Antonios Motakis (8): Convert -mem-path to QemuOpts and add prealloc and share properties New -mem-path option - unlink. Decouple vhost from kernel interface Add vhost-user skeleton Add domain socket communication for vhost-user backend Add vhost-user calls implementation Add new vhost-user netdev backend Add vhost-user reconnection exec.c| 57 +++- hmp-commands.hx | 4 +- hw/net/vhost_net.c| 144 +++--- hw/net/virtio-net.c | 42 ++- hw/scsi/vhost-scsi.c | 13 +- hw/virtio/Makefile.objs | 2 +- hw/virtio/vhost-backend.c | 556 ++ hw/virtio/vhost.c | 46 ++-- include/exec/cpu-all.h| 3 - include/hw/virtio/vhost-backend.h | 40 +++ include/hw/virtio/vhost.h | 4 +- include/net/vhost-user.h | 17 ++ include/net/vhost_net.h | 15 +- net/Makefile.objs | 2 +- net/clients.h | 3 + net/hub.c | 1 + net/net.c | 2 + net/tap.c | 16 +- net/vhost-user.c | 177 qapi-schema.json | 21 +- qemu-options.hx | 24 +- vl.c | 41 ++- 22 files changed, 1106 insertions(+), 124 deletions(-) create mode 100644 hw/virtio/vhost-backend.c create mode 100644 include/hw/virtio/vhost-backend.h create mode 100644 include/net/vhost-user.h create mode 100644 net/vhost-user.c -- 1.8.3.2
[Qemu-devel] [PATCH v6 1/8] Convert -mem-path to QemuOpts and add prealloc and share properties
Extend -mem-path with additional properties: - prealloc=on|off - default off, same as -mem-prealloc - share=on|off - default off, memory is mmapped with MAP_SHARED flag Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com --- exec.c | 41 +++-- include/exec/cpu-all.h | 3 --- qemu-options.hx| 9 +++-- vl.c | 37 - 4 files changed, 74 insertions(+), 16 deletions(-) diff --git a/exec.c b/exec.c index 7e49e8e..1c40a0d 100644 --- a/exec.c +++ b/exec.c @@ -957,6 +957,7 @@ void qemu_mutex_unlock_ramlist(void) #include sys/vfs.h #define HUGETLBFS_MAGIC 0x958458f6 +#define MIN_HUGE_PAGE_SIZE(2*1024*1024) static long gethugepagesize(const char *path) { @@ -972,8 +973,9 @@ static long gethugepagesize(const char *path) return 0; } -if (fs.f_type != HUGETLBFS_MAGIC) -fprintf(stderr, Warning: path not on HugeTLBFS: %s\n, path); +if (fs.f_type != HUGETLBFS_MAGIC) { +return 0; +} return fs.f_bsize; } @@ -994,11 +996,14 @@ static void *file_ram_alloc(RAMBlock *block, char *c; void *area; int fd; +int flags; unsigned long hpagesize; +QemuOpts *opts; +unsigned int mem_prealloc = 0, mem_share = 0; hpagesize = gethugepagesize(path); if (!hpagesize) { -return NULL; +hpagesize = MIN_HUGE_PAGE_SIZE; } if (memory hpagesize) { @@ -1010,6 +1015,13 @@ static void *file_ram_alloc(RAMBlock *block, return NULL; } +/* Fill config options */ +opts = qemu_opts_find(qemu_find_opts(mem-path), NULL); +if (opts) { +mem_prealloc = qemu_opt_get_bool(opts, prealloc, 0); +mem_share = qemu_opt_get_bool(opts, share, 0); +} + /* Make name safe to use with mkstemp by replacing '/' with '_'. */ sanitized_name = g_strdup(block-mr-name); for (c = sanitized_name; *c != '\0'; c++) { @@ -1023,14 +1035,15 @@ static void *file_ram_alloc(RAMBlock *block, fd = mkstemp(filename); if (fd 0) { -perror(unable to create backing store for hugepages); +perror(unable to create guest RAM backing store); g_free(filename); return NULL; } + unlink(filename); g_free(filename); -memory = (memory+hpagesize-1) ~(hpagesize-1); +memory = (memory + hpagesize - 1) ~(hpagesize - 1); /* * ftruncate is not supported by hugetlbfs in older @@ -1041,7 +1054,8 @@ static void *file_ram_alloc(RAMBlock *block, if (ftruncate(fd, memory)) perror(ftruncate); -area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); +flags = mem_share ? MAP_SHARED : MAP_PRIVATE; +area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0); if (area == MAP_FAILED) { perror(file_ram_alloc: can't mmap RAM pages); close(fd); @@ -1211,11 +1225,18 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, MemoryRegion *mr) { RAMBlock *block, *new_block; +QemuOpts *opts; +const char *mem_path = 0; size = TARGET_PAGE_ALIGN(size); new_block = g_malloc0(sizeof(*new_block)); new_block-fd = -1; +opts = qemu_opts_find(qemu_find_opts(mem-path), NULL); +if (opts) { +mem_path = qemu_opt_get(opts, path); +} + /* This assumes the iothread lock is taken here too. */ qemu_mutex_lock_ramlist(); new_block-mr = mr; @@ -1348,6 +1369,14 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) ram_addr_t offset; int flags; void *area, *vaddr; +QemuOpts *opts; +unsigned int mem_prealloc = 0; + +/* Fill config options */ +opts = qemu_opts_find(qemu_find_opts(mem-path), NULL); +if (opts) { +mem_prealloc = qemu_opt_get_bool(opts, prealloc, 0); +} QTAILQ_FOREACH(block, ram_list.blocks, next) { offset = addr - block-offset; diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index b6998f0..4f8e989 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -467,9 +467,6 @@ typedef struct RAMList { } RAMList; extern RAMList ram_list; -extern const char *mem_path; -extern int mem_prealloc; - /* Flags stored in the low bits of the TLB virtual address. These are defined so that fast path ram access is all zeros. */ /* Zero if TLB entry is valid. */ diff --git a/qemu-options.hx b/qemu-options.hx index 56e5fdf..60ecc95 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -221,9 +221,14 @@ gigabytes respectively. ETEXI DEF(mem-path, HAS_ARG, QEMU_OPTION_mempath, --mem-path FILE provide backing storage for guest RAM\n, QEMU_ARCH_ALL) +-mem-path [path=]path[,prealloc=on|off][,share=on|off]\n +provide backing storage for guest RAM\n +path= a
[Qemu-devel] [PATCH v6 3/8] Decouple vhost from kernel interface
We introduce the concept of vhost-backend, which can be either vhost-kernel or vhost-user. The existing vhost interface to the kernel is abstracted behind the vhost-kernel backend. We replace all direct ioctls to the kernel with a vhost_call to the backend. vhost dev-control is referenced only in the vhost-backend (ioctl, open, close). Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com --- hw/net/vhost_net.c| 13 +--- hw/scsi/vhost-scsi.c | 13 +--- hw/virtio/Makefile.objs | 2 +- hw/virtio/vhost-backend.c | 65 +++ hw/virtio/vhost.c | 47 +++- include/hw/virtio/vhost-backend.h | 37 ++ include/hw/virtio/vhost.h | 4 ++- 7 files changed, 148 insertions(+), 33 deletions(-) create mode 100644 hw/virtio/vhost-backend.c create mode 100644 include/hw/virtio/vhost-backend.h diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 006576d..4aaf0b4 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -27,7 +27,6 @@ #include sys/socket.h #include linux/kvm.h #include fcntl.h -#include sys/ioctl.h #include linux/virtio_ring.h #include netpacket/packet.h #include net/ethernet.h @@ -113,7 +112,8 @@ struct vhost_net *vhost_net_init(NetClientState *backend, int devfd, net-dev.nvqs = 2; net-dev.vqs = net-vqs; -r = vhost_dev_init(net-dev, devfd, /dev/vhost-net, force); +r = vhost_dev_init(net-dev, devfd, /dev/vhost-net, + VHOST_BACKEND_TYPE_KERNEL, force); if (r 0) { goto fail; } @@ -170,7 +170,8 @@ static int vhost_net_start_one(struct vhost_net *net, qemu_set_fd_handler(net-backend, NULL, NULL, NULL); file.fd = net-backend; for (file.index = 0; file.index net-dev.nvqs; ++file.index) { -r = ioctl(net-dev.control, VHOST_NET_SET_BACKEND, file); +const VhostOps *vhost_ops = net-dev.vhost_ops; +r = vhost_ops-vhost_call(net-dev, VHOST_NET_SET_BACKEND, file); if (r 0) { r = -errno; goto fail; @@ -180,7 +181,8 @@ static int vhost_net_start_one(struct vhost_net *net, fail: file.fd = -1; while (file.index-- 0) { -int r = ioctl(net-dev.control, VHOST_NET_SET_BACKEND, file); +const VhostOps *vhost_ops = net-dev.vhost_ops; +int r = vhost_ops-vhost_call(net-dev, VHOST_NET_SET_BACKEND, file); assert(r = 0); } net-nc-info-poll(net-nc, true); @@ -201,7 +203,8 @@ static void vhost_net_stop_one(struct vhost_net *net, } for (file.index = 0; file.index net-dev.nvqs; ++file.index) { -int r = ioctl(net-dev.control, VHOST_NET_SET_BACKEND, file); +const VhostOps *vhost_ops = net-dev.vhost_ops; +int r = vhost_ops-vhost_call(net-dev, VHOST_NET_SET_BACKEND, file); assert(r = 0); } net-nc-info-poll(net-nc, true); diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index 3983a5b..3faff65 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -27,12 +27,13 @@ static int vhost_scsi_set_endpoint(VHostSCSI *s) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); +const VhostOps *vhost_ops = s-dev.vhost_ops; struct vhost_scsi_target backend; int ret; memset(backend, 0, sizeof(backend)); pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs-conf.wwpn); -ret = ioctl(s-dev.control, VHOST_SCSI_SET_ENDPOINT, backend); +ret = vhost_ops-vhost_call(s-dev, VHOST_SCSI_SET_ENDPOINT, backend); if (ret 0) { return -errno; } @@ -43,10 +44,11 @@ static void vhost_scsi_clear_endpoint(VHostSCSI *s) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); struct vhost_scsi_target backend; +const VhostOps *vhost_ops = s-dev.vhost_ops; memset(backend, 0, sizeof(backend)); pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs-conf.wwpn); -ioctl(s-dev.control, VHOST_SCSI_CLEAR_ENDPOINT, backend); +vhost_ops-vhost_call(s-dev, VHOST_SCSI_CLEAR_ENDPOINT, backend); } static int vhost_scsi_start(VHostSCSI *s) @@ -55,13 +57,15 @@ static int vhost_scsi_start(VHostSCSI *s) VirtIODevice *vdev = VIRTIO_DEVICE(s); BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); +const VhostOps *vhost_ops = s-dev.vhost_ops; if (!k-set_guest_notifiers) { error_report(binding does not support guest notifiers); return -ENOSYS; } -ret = ioctl(s-dev.control, VHOST_SCSI_GET_ABI_VERSION, abi_version); +ret = vhost_ops-vhost_call(s-dev, +VHOST_SCSI_GET_ABI_VERSION, abi_version); if (ret 0) { return -errno; } @@ -227,7 +231,8 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) s-dev.vqs = g_new(struct vhost_virtqueue,
[Qemu-devel] [PATCH v6 8/8] Add vhost-user reconnection
At runtime vhost-user netdev will detect if the vhost backend is up or down. Upon disconnection it will set link_down accordingly and notify virtio-net. The virtio-net interface goes down. On the next polling cycle the connection will be re-attempted. The poll cycle length is set through a -netdev option: -netdev vhost-user,path=/path/to/sock[,poll_time=poll_time] Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com --- hw/net/vhost_net.c| 16 + hw/virtio/vhost-backend.c | 25 -- include/hw/virtio/vhost-backend.h | 2 ++ include/net/vhost_net.h | 1 + net/vhost-user.c | 70 +-- qapi-schema.json | 5 ++- qemu-options.hx | 7 ++-- 7 files changed, 118 insertions(+), 8 deletions(-) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index e42f4d6..56c218e 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -304,6 +304,17 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, vhost_virtqueue_mask(net-dev, dev, idx, mask); } +int vhost_net_link_status(VHostNetState *net) +{ +int r = 0; + +if (net-dev.vhost_ops-vhost_status) { +r = net-dev.vhost_ops-vhost_status(net-dev); +} + +return r; +} + VHostNetState *get_vhost_net(NetClientState *nc) { VHostNetState *vhost_net = 0; @@ -372,6 +383,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, { } +int vhost_net_link_status(VHostNetState *net) +{ +return 0; +} + VHostNetState *get_vhost_net(NetClientState *nc) { return 0; diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c index 8f98562..65c7385 100644 --- a/hw/virtio/vhost-backend.c +++ b/hw/virtio/vhost-backend.c @@ -360,12 +360,12 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, } if (vhost_user_send_fds(fd, msg, fds, fd_num) 0) { -return -1; +goto fail; } if (need_reply) { if (vhost_user_recv(fd, msg) 0) { -return -1; +goto fail; } if (msg_request != msg.request) { @@ -398,6 +398,25 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, } return 0; + +fail: +/* mark the backend non operational */ +error_report(Disconnect detected\n); +dev-vhost_ops-vhost_backend_cleanup(dev); +return -1; +} + +static int vhost_user_status(struct vhost_dev *dev) +{ +int result = 1; + +if (vhost_user_echo(dev) 0) { +error_report(Disconnect detected\n); +dev-vhost_ops-vhost_backend_cleanup(dev); +result = 0; +} + +return result; } static int vhost_user_init(struct vhost_dev *dev, const char *devpath) @@ -479,6 +498,7 @@ static int vhost_user_cleanup(struct vhost_dev *dev) static const VhostOps user_ops = { .backend_type = VHOST_BACKEND_TYPE_USER, .vhost_call = vhost_user_call, +.vhost_status = vhost_user_status, .vhost_backend_init = vhost_user_init, .vhost_backend_cleanup = vhost_user_cleanup }; @@ -511,6 +531,7 @@ static int vhost_kernel_cleanup(struct vhost_dev *dev) static const VhostOps kernel_ops = { .backend_type = VHOST_BACKEND_TYPE_KERNEL, .vhost_call = vhost_kernel_call, +.vhost_status = 0, .vhost_backend_init = vhost_kernel_init, .vhost_backend_cleanup = vhost_kernel_cleanup }; diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index ef87ffa..f2b4a6c 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -22,12 +22,14 @@ struct vhost_dev; typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request, void *arg); +typedef int (*vhost_status)(struct vhost_dev *dev); typedef int (*vhost_backend_init)(struct vhost_dev *dev, const char *devpath); typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev); typedef struct VhostOps { VhostBackendType backend_type; vhost_call vhost_call; +vhost_status vhost_status; vhost_backend_init vhost_backend_init; vhost_backend_cleanup vhost_backend_cleanup; } VhostOps; diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index abd3d0b..6390907 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -31,5 +31,6 @@ void vhost_net_ack_features(VHostNetState *net, unsigned features); bool vhost_net_virtqueue_pending(VHostNetState *net, int n); void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, int idx, bool mask); +int vhost_net_link_status(VHostNetState *net); VHostNetState *get_vhost_net(NetClientState *nc); #endif diff --git a/net/vhost-user.c b/net/vhost-user.c index 5ad8fd0..40c1265 100644 --- a/net/vhost-user.c +++
[Qemu-devel] [PATCH v6 4/8] Add vhost-user skeleton
Add empty vhost_call, init and cleanup for the vhost-user backend. Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com --- hw/net/vhost_net.c| 57 ++- hw/virtio/vhost-backend.c | 35 include/hw/virtio/vhost-backend.h | 3 ++- include/net/vhost_net.h | 13 - net/tap.c | 16 ++- 5 files changed, 91 insertions(+), 33 deletions(-) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 4aaf0b4..3614e6c 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -91,43 +91,51 @@ static int vhost_net_get_fd(NetClientState *backend) } } -struct vhost_net *vhost_net_init(NetClientState *backend, int devfd, - bool force) +struct vhost_net *vhost_net_init(VhostNetOptions *options) { -int r; +int r = -1; struct vhost_net *net = g_malloc(sizeof *net); -if (!backend) { -fprintf(stderr, vhost-net requires backend to be setup\n); + +if (!options-net_backend) { +fprintf(stderr, vhost-net requires net backend to be setup\n); goto fail; } -r = vhost_net_get_fd(backend); -if (r 0) { -goto fail; + +if (options-backend_type == VHOST_BACKEND_TYPE_KERNEL) { +r = vhost_net_get_fd(options-net_backend); +if (r 0) { +goto fail; +} + +net-dev.backend_features = +tap_has_vnet_hdr(options-net_backend) ? 0 : +(1 VHOST_NET_F_VIRTIO_NET_HDR); } -net-nc = backend; -net-dev.backend_features = tap_has_vnet_hdr(backend) ? 0 : -(1 VHOST_NET_F_VIRTIO_NET_HDR); + +net-nc = options-net_backend; net-backend = r; net-dev.nvqs = 2; net-dev.vqs = net-vqs; -r = vhost_dev_init(net-dev, devfd, /dev/vhost-net, - VHOST_BACKEND_TYPE_KERNEL, force); +r = vhost_dev_init(net-dev, options-devfd, options-devpath, + options-backend_type, options-force); if (r 0) { goto fail; } -if (!tap_has_vnet_hdr_len(backend, - sizeof(struct virtio_net_hdr_mrg_rxbuf))) { -net-dev.features = ~(1 VIRTIO_NET_F_MRG_RXBUF); -} -if (~net-dev.features net-dev.backend_features) { -fprintf(stderr, vhost lacks feature mask % PRIu64 for backend\n, -(uint64_t)(~net-dev.features net-dev.backend_features)); -vhost_dev_cleanup(net-dev); -goto fail; +if (options-backend_type == VHOST_BACKEND_TYPE_KERNEL) { +if (!tap_has_vnet_hdr_len(options-net_backend, +sizeof(struct virtio_net_hdr_mrg_rxbuf))) { +net-dev.features = ~(1 VIRTIO_NET_F_MRG_RXBUF); +} +if (~net-dev.features net-dev.backend_features) { +fprintf(stderr, vhost lacks feature mask % PRIu64 +for backend\n, + (uint64_t)(~net-dev.features net-dev.backend_features)); +vhost_dev_cleanup(net-dev); +goto fail; +} } - /* Set sane init value. Override when guest acks. */ vhost_net_ack_features(net, 0); return net; @@ -286,8 +294,7 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, vhost_virtqueue_mask(net-dev, dev, idx, mask); } #else -struct vhost_net *vhost_net_init(NetClientState *backend, int devfd, - bool force) +struct vhost_net *vhost_net_init(VhostNetOptions *options) { error_report(vhost-net support is not compiled in); return NULL; diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c index c0f11e4..1d83e1d 100644 --- a/hw/virtio/vhost-backend.c +++ b/hw/virtio/vhost-backend.c @@ -16,6 +16,38 @@ #include unistd.h #include sys/ioctl.h +static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, +void *arg) +{ +assert(dev-vhost_ops-backend_type == VHOST_BACKEND_TYPE_USER); +error_report(vhost_user_call not implemented\n); + +return -1; +} + +static int vhost_user_init(struct vhost_dev *dev, const char *devpath) +{ +assert(dev-vhost_ops-backend_type == VHOST_BACKEND_TYPE_USER); +error_report(vhost_user_init not implemented\n); + +return -1; +} + +static int vhost_user_cleanup(struct vhost_dev *dev) +{ +assert(dev-vhost_ops-backend_type == VHOST_BACKEND_TYPE_USER); +error_report(vhost_user_cleanup not implemented\n); + +return -1; +} + +static const VhostOps user_ops = { +.backend_type = VHOST_BACKEND_TYPE_USER, +.vhost_call = vhost_user_call, +.vhost_backend_init = vhost_user_init, +.vhost_backend_cleanup = vhost_user_cleanup +}; + static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request, void *arg) { @@ -56,6
[Qemu-devel] [PATCH v6 2/8] New -mem-path option - unlink.
The unlink option allows the created file to be externally deleted after QEMU is terminated. - unlink=on|off - default on, unlink the file after opening it Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com --- exec.c | 18 +- qemu-options.hx | 7 --- vl.c| 4 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/exec.c b/exec.c index 1c40a0d..30f4019 100644 --- a/exec.c +++ b/exec.c @@ -999,7 +999,7 @@ static void *file_ram_alloc(RAMBlock *block, int flags; unsigned long hpagesize; QemuOpts *opts; -unsigned int mem_prealloc = 0, mem_share = 0; +unsigned int mem_prealloc = 0, mem_share = 0, mem_unlink = 1; hpagesize = gethugepagesize(path); if (!hpagesize) { @@ -1020,6 +1020,7 @@ static void *file_ram_alloc(RAMBlock *block, if (opts) { mem_prealloc = qemu_opt_get_bool(opts, prealloc, 0); mem_share = qemu_opt_get_bool(opts, share, 0); +mem_unlink = qemu_opt_get_bool(opts, unlink, 1); } /* Make name safe to use with mkstemp by replacing '/' with '_'. */ @@ -1029,18 +1030,25 @@ static void *file_ram_alloc(RAMBlock *block, *c = '_'; } -filename = g_strdup_printf(%s/qemu_back_mem.%s.XX, path, - sanitized_name); +filename = g_strdup_printf(%s/qemu_back_mem.%s%s, path, sanitized_name, + (mem_unlink) ? .XX : ); g_free(sanitized_name); -fd = mkstemp(filename); +if (mem_unlink) { +fd = mkstemp(filename); +} else { +fd = open(filename, O_CREAT | O_RDWR | O_EXCL, +S_IRWXU | S_IRWXG | S_IRWXO); +} if (fd 0) { perror(unable to create guest RAM backing store); g_free(filename); return NULL; } -unlink(filename); +if (mem_unlink) { +unlink(filename); +} g_free(filename); memory = (memory + hpagesize - 1) ~(hpagesize - 1); diff --git a/qemu-options.hx b/qemu-options.hx index 60ecc95..a12af97 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -221,14 +221,15 @@ gigabytes respectively. ETEXI DEF(mem-path, HAS_ARG, QEMU_OPTION_mempath, --mem-path [path=]path[,prealloc=on|off][,share=on|off]\n +-mem-path [path=]path[,prealloc=on|off][,share=on|off][,unlink=on|off]\n provide backing storage for guest RAM\n path= a directory path for the backing store\n prealloc= preallocate guest memory [default disabled]\n -share= enable mmap share flag [default disabled]\n, +share= enable mmap share flag [default disabled]\n +unlink= enable unlinking the guest RAM files [default enabled]\n, QEMU_ARCH_ALL) STEXI -@item -mem-path [path=]@var{path}[,prealloc=on|off][,share=on|off] +@item -mem-path [path=]@var{path}[,prealloc=on|off][,share=on|off][,unlink=on|off] @findex -mem-path Allocate guest RAM from a temporarily created file in @var{path}. ETEXI diff --git a/vl.c b/vl.c index e98abc8..5034bb6 100644 --- a/vl.c +++ b/vl.c @@ -546,6 +546,10 @@ static QemuOptsList qemu_mem_path_opts = { .name = share, .type = QEMU_OPT_BOOL, }, +{ +.name = unlink, +.type = QEMU_OPT_BOOL, +}, { /* end of list */ } }, }; -- 1.8.3.2
[Qemu-devel] [PATCH v6 5/8] Add domain socket communication for vhost-user backend
Add structures for passing vhost-user messages over a unix domain socket. This is the equivalent of the existing vhost-kernel ioctls. Connect to the named unix domain socket. The system call sendmsg is used for communication. To be able to pass file descriptors between processes - we use SCM_RIGHTS type in the message control header. Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com --- hw/virtio/vhost-backend.c | 306 +- 1 file changed, 301 insertions(+), 5 deletions(-) diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c index 1d83e1d..460ee02 100644 --- a/hw/virtio/vhost-backend.c +++ b/hw/virtio/vhost-backend.c @@ -11,34 +11,330 @@ #include hw/virtio/vhost.h #include hw/virtio/vhost-backend.h #include qemu/error-report.h +#include qemu/sockets.h #include fcntl.h #include unistd.h #include sys/ioctl.h +#include sys/socket.h +#include sys/un.h +#include linux/vhost.h + +#define VHOST_MEMORY_MAX_NREGIONS8 +#define VHOST_USER_SOCKTO(300) /* msec */ + +typedef enum VhostUserRequest { +VHOST_USER_NONE = 0, +VHOST_USER_GET_FEATURES = 1, +VHOST_USER_SET_FEATURES = 2, +VHOST_USER_SET_OWNER = 3, +VHOST_USER_RESET_OWNER = 4, +VHOST_USER_SET_MEM_TABLE = 5, +VHOST_USER_SET_LOG_BASE = 6, +VHOST_USER_SET_LOG_FD = 7, +VHOST_USER_SET_VRING_NUM = 8, +VHOST_USER_SET_VRING_ADDR = 9, +VHOST_USER_SET_VRING_BASE = 10, +VHOST_USER_GET_VRING_BASE = 11, +VHOST_USER_SET_VRING_KICK = 12, +VHOST_USER_SET_VRING_CALL = 13, +VHOST_USER_SET_VRING_ERR = 14, +VHOST_USER_NET_SET_BACKEND = 15, +VHOST_USER_ECHO = 16, +VHOST_USER_MAX +} VhostUserRequest; + +typedef struct VhostUserMemoryRegion { +uint64_t guest_phys_addr; +uint64_t memory_size; +uint64_t userspace_addr; +} VhostUserMemoryRegion; + +typedef struct VhostUserMemory { +uint32_t nregions; +uint32_t padding; +VhostUserMemoryRegion regions[VHOST_MEMORY_MAX_NREGIONS]; +} VhostUserMemory; + +typedef struct VhostUserMsg { +VhostUserRequest request; + +#define VHOST_USER_VERSION_MASK (0x3) +#define VHOST_USER_REPLY_MASK (0x12) +uint32_t flags; +uint32_t size; /* the following payload size */ +union { +uint64_t u64; +struct vhost_vring_state state; +struct vhost_vring_addr addr; +VhostUserMemory memory; +}; +} QEMU_PACKED VhostUserMsg; + +static VhostUserMsg m __attribute__ ((unused)); +#define VHOST_USER_HDR_SIZE (sizeof(m.request) \ ++ sizeof(m.flags) \ ++ sizeof(m.size)) + +#define VHOST_USER_PAYLOAD_SIZE (sizeof(m) - VHOST_USER_HDR_SIZE) + +/* The version of the protocol we support */ +#define VHOST_USER_VERSION(0x1) + +static int vhost_user_recv(int fd, VhostUserMsg *msg) +{ +ssize_t r; +uint8_t *p = (uint8_t *) msg; + +/* read the header */ +do { +r = read(fd, p, VHOST_USER_HDR_SIZE); +} while (r 0 errno == EINTR); + +if (r 0) { +error_report(Failed to read msg header, reason: %s\n, + strerror(errno)); +goto fail; +} + +if (r != VHOST_USER_HDR_SIZE) { +error_report(Failed to read msg header. Read %zu instead of %zu.\n, + r, VHOST_USER_HDR_SIZE); +goto fail; +} + +/* validate received flags */ +if (msg-flags != (VHOST_USER_REPLY_MASK | VHOST_USER_VERSION)) { +error_report(Failed to read msg header. + Flags 0x%x instead of 0x%x.\n, + msg-flags, VHOST_USER_REPLY_MASK | VHOST_USER_VERSION); +goto fail; +} + +/* validate message size is sane */ +if (msg-size VHOST_USER_PAYLOAD_SIZE) { +error_report(Failed to read msg header. + Size %d exceeds the maximum %zu.\n, + msg-size, VHOST_USER_PAYLOAD_SIZE); +goto fail; +} + +p += VHOST_USER_HDR_SIZE; + +/* read the payload */ +do { +r = read(fd, p, msg-size); +} while (r 0 errno == EINTR); + +if (r 0) { +error_report(Failed to read msg payload, reason: %s\n, + strerror(errno)); +goto fail; +} + +if (r != msg-size) { +error_report(Failed to read msg payload. Read %zu instead of %d.\n, + r, msg-size); +goto fail; +} + +return 0; + +fail: +return -1; +} + +static int vhost_user_send_fds(int fd, VhostUserMsg *msg, int *fds, +size_t fd_num) +{ +int r; + +struct msghdr msgh; +struct iovec iov; + +size_t fd_size = fd_num * sizeof(int); +char control[CMSG_SPACE(fd_size)]; +struct cmsghdr *cmsg; + +memset(msgh, 0, sizeof(msgh)); +memset(control, 0, sizeof(control)); + +/* set the payload */ +iov.iov_base = msg; +iov.iov_len = VHOST_USER_HDR_SIZE +
[Qemu-devel] [PATCH v6 6/8] Add vhost-user calls implementation
Each ioctl request of vhost-kernel has a vhost-user message equivalent, which is sent over the control socket. The general approach is to copy the data from the supplied argument pointer to a designated field in the message. If a file descriptor is to be passed it will be placed in the fds array for inclusion in the sendmsd control header. VHOST_SET_MEM_TABLE ignores the supplied vhost_memory structure and scans the global ram_list for ram blocks with a valid fd field set. This would be set when the -mem-path option with shared=on property is used. Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com --- hw/virtio/vhost-backend.c | 147 -- 1 file changed, 143 insertions(+), 4 deletions(-) diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c index 460ee02..8f98562 100644 --- a/hw/virtio/vhost-backend.c +++ b/hw/virtio/vhost-backend.c @@ -81,6 +81,39 @@ static VhostUserMsg m __attribute__ ((unused)); /* The version of the protocol we support */ #define VHOST_USER_VERSION(0x1) +static unsigned long int ioctl_to_vhost_user_request[VHOST_USER_MAX] = { +-1, /* VHOST_USER_NONE */ +VHOST_GET_FEATURES, /* VHOST_USER_GET_FEATURES */ +VHOST_SET_FEATURES, /* VHOST_USER_SET_FEATURES */ +VHOST_SET_OWNER, /* VHOST_USER_SET_OWNER */ +VHOST_RESET_OWNER, /* VHOST_USER_RESET_OWNER */ +VHOST_SET_MEM_TABLE, /* VHOST_USER_SET_MEM_TABLE */ +VHOST_SET_LOG_BASE, /* VHOST_USER_SET_LOG_BASE */ +VHOST_SET_LOG_FD, /* VHOST_USER_SET_LOG_FD */ +VHOST_SET_VRING_NUM, /* VHOST_USER_SET_VRING_NUM */ +VHOST_SET_VRING_ADDR, /* VHOST_USER_SET_VRING_ADDR */ +VHOST_SET_VRING_BASE, /* VHOST_USER_SET_VRING_BASE */ +VHOST_GET_VRING_BASE, /* VHOST_USER_GET_VRING_BASE */ +VHOST_SET_VRING_KICK, /* VHOST_USER_SET_VRING_KICK */ +VHOST_SET_VRING_CALL, /* VHOST_USER_SET_VRING_CALL */ +VHOST_SET_VRING_ERR, /* VHOST_USER_SET_VRING_ERR */ +VHOST_NET_SET_BACKEND, /* VHOST_USER_NET_SET_BACKEND */ +-1 /* VHOST_USER_ECHO */ +}; + +static VhostUserRequest vhost_user_request_translate(unsigned long int request) +{ +VhostUserRequest idx; + +for (idx = 0; idx VHOST_USER_MAX; idx++) { +if (ioctl_to_vhost_user_request[idx] == request) { +break; +} +} + +return (idx == VHOST_USER_MAX) ? VHOST_USER_NONE : idx; +} + static int vhost_user_recv(int fd, VhostUserMsg *msg) { ssize_t r; @@ -235,7 +268,10 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, { int fd = dev-control; VhostUserMsg msg; -int result = 0; +VhostUserRequest msg_request; +RAMBlock *block = 0; +struct vhost_vring_file *file = 0; +int need_reply = 0; int fds[VHOST_MEMORY_MAX_NREGIONS]; size_t fd_num = 0; @@ -245,20 +281,123 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, return 0; } -msg.request = VHOST_USER_NONE; +msg_request = vhost_user_request_translate(request); +msg.request = msg_request; msg.flags = VHOST_USER_VERSION; msg.size = 0; switch (request) { +case VHOST_GET_FEATURES: +case VHOST_GET_VRING_BASE: +need_reply = 1; +break; + +case VHOST_SET_FEATURES: +case VHOST_SET_LOG_BASE: +msg.u64 = *((__u64 *) arg); +msg.size = sizeof(m.u64); +break; + +case VHOST_SET_OWNER: +case VHOST_RESET_OWNER: +break; + +case VHOST_SET_MEM_TABLE: +QTAILQ_FOREACH(block, ram_list.blocks, next) +{ +if (block-fd 0) { +msg.memory.regions[fd_num].userspace_addr = (__u64) block-host; +msg.memory.regions[fd_num].memory_size = block-length; +msg.memory.regions[fd_num].guest_phys_addr = block-offset; +fds[fd_num++] = block-fd; +} +} + +msg.memory.nregions = fd_num; + +if (!fd_num) { +error_report(Failed initializing vhost-user memory map\n +consider using -mem-path option\n); +return -1; +} + +msg.size = sizeof(m.memory.nregions); +msg.size += sizeof(m.memory.padding); +msg.size += fd_num * sizeof(VhostUserMemoryRegion); + +break; + +case VHOST_SET_LOG_FD: +fds[fd_num++] = *((int *) arg); +break; + +case VHOST_SET_VRING_NUM: +case VHOST_SET_VRING_BASE: +memcpy(msg.state, arg, sizeof(struct vhost_vring_state)); +msg.size = sizeof(m.state); +break; + +case VHOST_SET_VRING_ADDR: +memcpy(msg.addr, arg, sizeof(struct vhost_vring_addr)); +msg.size = sizeof(m.addr); +break; + +case VHOST_SET_VRING_KICK: +case VHOST_SET_VRING_CALL: +case VHOST_SET_VRING_ERR: +case VHOST_NET_SET_BACKEND: +file = arg; +msg.u64 = file-index; +
[Qemu-devel] [PATCH v2 03/10] target-arm: A64: Add decode skeleton for SIMD data processing insns
From: Alex Bennée alex.ben...@linaro.org Add decode skeleton and function placeholders for all the SIMD data processing instructions. Due to the complexity of this part of the table the normal extract and switch approach gets very messy very quickly, so we use a simple data-driven pattern-and-mask approach. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- v1-v2: * made data_proc_simd table const * fixed errors in insn diagram comments * fixed coding style for fn pointer call --- target-arm/translate-a64.c | 306 - 1 file changed, 305 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 6e31740..8060c9f 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -61,6 +61,17 @@ enum a64_shift_type { A64_SHIFT_TYPE_ROR = 3 }; +/* Table based decoder typedefs - used when the relevant bits for decode + * are too awkwardly scattered across the instruction (eg SIMD). + */ +typedef void AArch64DecodeFn(DisasContext *s, uint32_t insn); + +typedef struct AArch64DecodeTable { +uint32_t pattern; +uint32_t mask; +AArch64DecodeFn *disas_fn; +} AArch64DecodeTable; + /* initialize TCG globals. */ void a64_translate_init(void) { @@ -846,6 +857,31 @@ static inline void gen_check_sp_alignment(DisasContext *s) } /* + * This provides a simple table based table lookup decoder. It is + * intended to be used when the relevant bits for decode are too + * awkwardly placed and switch/if based logic would be confusing and + * deeply nested. Since it's a linear search through the table, tables + * should be kept small. + * + * It returns the first handler where insn mask == pattern, or + * NULL if there is no match. + * The table is terminated by an empty mask (i.e. 0) + */ +static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table, + uint32_t insn) +{ +const AArch64DecodeTable *tptr = table; + +while (tptr-mask) { +if ((insn tptr-mask) == tptr-pattern) { +return tptr-disas_fn; +} +tptr++; +} +return NULL; +} + +/* * the instruction disassembly implemented here matches * the instruction encoding classifications in chapter 3 (C3) * of the ARM Architecture Reference Manual (DDI0487A_a) @@ -4610,13 +4646,281 @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) } } +/* C3.6.1 EXT + * 31 30 29 24 23 22 21 20 16 15 14 11 10 95 40 + * +---+---+-+-+---+--+---+--+---+--+--+ + * | 0 | Q | 1 0 1 1 1 0 | op2 | 0 | Rm | 0 | imm4 | 0 | Rn | Rd | + * +---+---+-+-+---+--+---+--+---+--+--+ + */ +static void disas_simd_ext(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.2 TBL/TBX + * 31 30 29 24 23 22 21 20 16 15 14 13 12 11 10 95 40 + * +---+---+-+-+---+--+---+-++-+--+--+ + * | 0 | Q | 0 0 1 1 1 0 | op2 | 0 | Rm | 0 | len | op | 0 0 | Rn | Rd | + * +---+---+-+-+---+--+---+-++-+--+--+ + */ +static void disas_simd_tb(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.3 ZIP/UZP/TRN + * 31 30 29 24 23 22 21 20 16 15 14 12 11 10 95 40 + * +---+---+-+--+---+--+---+--+--+ + * | 0 | Q | 0 0 1 1 1 0 | size | 0 | Rm | 0 | opc | 1 0 | Rn | Rd | + * +---+---+-+--+---+--+---+--+--+ + */ +static void disas_simd_zip_trn(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.4 AdvSIMD across lanes + * 31 30 29 28 24 23 22 21 17 1612 11 10 95 40 + * +---+---+---+---+--+---++-+--+--+ + * | 0 | Q | U | 0 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 | Rn | Rd | + * +---+---+---+---+--+---++-+--+--+ + */ +static void disas_simd_across_lanes(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.5 AdvSIMD copy + * 31 30 29 28 21 20 16 15 14 11 10 95 40 + * +---+---++-+--+---+--+---+--+--+ + * | 0 | Q | op | 0 1 1 1 0 0 0 0 | imm5 | 0 | imm4 | 1 | Rn | Rd | + * +---+---++-+--+---+--+---+--+--+ + */ +static void disas_simd_copy(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* C3.6.6 AdvSIMD modified immediate + * 31 30 29 28 19 18 16 15 12 11 10 9 5 40 + * +---+---++-+-+---++---+---+--+ + * | 0 | Q | op | 0 1 1 1 1 0 0 0 0 0
[Qemu-devel] [PATCH v2 04/10] target-arm: A64: Add SIMD EXT
Add support for the SIMD EXT instruction (the only one in its group, C3.6.1). Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- v1-v2: * reworked to do the vector element reads outside do_ext64; this turned out to be a substantial enough change that I haven't carried rth's reviewed-by tag across --- target-arm/translate-a64.c | 80 +- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 8060c9f..219af78 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -4646,6 +4646,25 @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) } } +static void do_ext64(DisasContext *s, TCGv_i64 tcg_left, TCGv_i64 tcg_right, + int pos) +{ +/* Extract 64 bits from the middle of two concatenated 64 bit + * vector register slices left:right. The extracted bits start + * at 'pos' bits into the right (least significant) side. + * We return the result in tcg_right, and guarantee not to + * trash tcg_left. + */ +TCGv_i64 tcg_tmp = tcg_temp_new_i64(); +assert(pos 0 pos 64); + +tcg_gen_shri_i64(tcg_right, tcg_right, pos); +tcg_gen_shli_i64(tcg_tmp, tcg_left, 64 - pos); +tcg_gen_or_i64(tcg_right, tcg_right, tcg_tmp); + +tcg_temp_free_i64(tcg_tmp); +} + /* C3.6.1 EXT * 31 30 29 24 23 22 21 20 16 15 14 11 10 95 40 * +---+---+-+-+---+--+---+--+---+--+--+ @@ -4654,7 +4673,66 @@ static void disas_data_proc_fp(DisasContext *s, uint32_t insn) */ static void disas_simd_ext(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int is_q = extract32(insn, 30, 1); +int op2 = extract32(insn, 22, 2); +int imm4 = extract32(insn, 11, 4); +int rm = extract32(insn, 16, 5); +int rn = extract32(insn, 5, 5); +int rd = extract32(insn, 0, 5); +int pos = imm4 3; +TCGv_i64 tcg_resl, tcg_resh; + +if (op2 != 0 || (!is_q extract32(imm4, 3, 1))) { +unallocated_encoding(s); +return; +} + +tcg_resh = tcg_temp_new_i64(); +tcg_resl = tcg_temp_new_i64(); + +/* Vd gets bits starting at pos bits into Vm:Vn. This is + * either extracting 128 bits from a 128:128 concatenation, or + * extracting 64 bits from a 64:64 concatenation. + */ +if (!is_q) { +read_vec_element(s, tcg_resl, rn, 0, MO_64); +if (pos != 0) { +read_vec_element(s, tcg_resh, rm, 0, MO_64); +read_vec_element(s, tcg_resl, rn, 0, MO_64); +do_ext64(s, tcg_resh, tcg_resl, pos); +} +tcg_gen_movi_i64(tcg_resh, 0); +} else { +TCGv_i64 tcg_hh; +typedef struct { +int reg; +int elt; +} EltPosns; +EltPosns eltposns[] = { {rn, 0}, {rn, 1}, {rm, 0}, {rm, 1} }; +EltPosns *elt = eltposns; + +if (pos = 64) { +elt++; +pos -= 64; +} + +read_vec_element(s, tcg_resl, elt-reg, elt-elt, MO_64); +elt++; +read_vec_element(s, tcg_resh, elt-reg, elt-elt, MO_64); +elt++; +if (pos != 0) { +do_ext64(s, tcg_resh, tcg_resl, pos); +tcg_hh = tcg_temp_new_i64(); +read_vec_element(s, tcg_hh, elt-reg, elt-elt, MO_64); +do_ext64(s, tcg_hh, tcg_resh, pos); +tcg_temp_free_i64(tcg_hh); +} +} + +write_vec_element(s, tcg_resl, rd, 0, MO_64); +tcg_temp_free_i64(tcg_resl); +write_vec_element(s, tcg_resh, rd, 1, MO_64); +tcg_temp_free_i64(tcg_resh); } /* C3.6.2 TBL/TBX -- 1.8.5
[Qemu-devel] [PATCH v6 7/8] Add new vhost-user netdev backend
Add a new QEMU netdev backend that is intended to invoke vhost_net with the vhost-user backend. Also decouple virtio-net from the tap backend. Signed-off-by: Antonios Motakis a.mota...@virtualopensystems.com Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com --- hmp-commands.hx | 4 +- hw/net/vhost_net.c | 66 ++-- hw/net/virtio-net.c | 42 -- hw/virtio/vhost.c| 1 - include/net/vhost-user.h | 17 include/net/vhost_net.h | 1 + net/Makefile.objs| 2 +- net/clients.h| 3 ++ net/hub.c| 1 + net/net.c| 2 + net/vhost-user.c | 111 +++ qapi-schema.json | 18 +++- qemu-options.hx | 13 ++ 13 files changed, 237 insertions(+), 44 deletions(-) create mode 100644 include/net/vhost-user.h create mode 100644 net/vhost-user.c diff --git a/hmp-commands.hx b/hmp-commands.hx index ebe8e78..d5a3774 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1190,7 +1190,7 @@ ETEXI { .name = host_net_add, .args_type = device:s,opts:s?, -.params = tap|user|socket|vde|netmap|dump [options], +.params = tap|user|socket|vde|netmap|vhost-user|dump [options], .help = add host VLAN client, .mhandler.cmd = net_host_device_add, }, @@ -1218,7 +1218,7 @@ ETEXI { .name = netdev_add, .args_type = netdev:O, -.params = [user|tap|socket|hubport|netmap],id=str[,prop=value][,...], +.params = [user|tap|socket|hubport|netmap|vhost-user],id=str[,prop=value][,...], .help = add host network device, .mhandler.cmd = hmp_netdev_add, }, diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 3614e6c..e42f4d6 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -15,6 +15,7 @@ #include net/net.h #include net/tap.h +#include net/vhost-user.h #include hw/virtio/virtio-net.h #include net/vhost_net.h @@ -174,15 +175,20 @@ static int vhost_net_start_one(struct vhost_net *net, goto fail_start; } -net-nc-info-poll(net-nc, false); -qemu_set_fd_handler(net-backend, NULL, NULL, NULL); -file.fd = net-backend; -for (file.index = 0; file.index net-dev.nvqs; ++file.index) { -const VhostOps *vhost_ops = net-dev.vhost_ops; -r = vhost_ops-vhost_call(net-dev, VHOST_NET_SET_BACKEND, file); -if (r 0) { -r = -errno; -goto fail; +if (net-nc-info-poll) { +net-nc-info-poll(net-nc, false); +} + +if (net-nc-info-type == NET_CLIENT_OPTIONS_KIND_TAP) { +qemu_set_fd_handler(net-backend, NULL, NULL, NULL); +file.fd = net-backend; +for (file.index = 0; file.index net-dev.nvqs; ++file.index) { +const VhostOps *vhost_ops = net-dev.vhost_ops; +r = vhost_ops-vhost_call(net-dev, VHOST_NET_SET_BACKEND, file); +if (r 0) { +r = -errno; +goto fail; +} } } return 0; @@ -193,7 +199,9 @@ fail: int r = vhost_ops-vhost_call(net-dev, VHOST_NET_SET_BACKEND, file); assert(r = 0); } -net-nc-info-poll(net-nc, true); +if (net-nc-info-poll) { +net-nc-info-poll(net-nc, true); +} vhost_dev_stop(net-dev, dev); fail_start: vhost_dev_disable_notifiers(net-dev, dev); @@ -215,7 +223,9 @@ static void vhost_net_stop_one(struct vhost_net *net, int r = vhost_ops-vhost_call(net-dev, VHOST_NET_SET_BACKEND, file); assert(r = 0); } -net-nc-info-poll(net-nc, true); +if (net-nc-info-poll) { +net-nc-info-poll(net-nc, true); +} vhost_dev_stop(net-dev, dev); vhost_dev_disable_notifiers(net-dev, dev); } @@ -235,7 +245,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, } for (i = 0; i total_queues; i++) { -r = vhost_net_start_one(tap_get_vhost_net(ncs[i].peer), dev, i * 2); +r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev, i * 2); if (r 0) { goto err; @@ -252,7 +262,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, err: while (--i = 0) { -vhost_net_stop_one(tap_get_vhost_net(ncs[i].peer), dev); +vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev); } return r; } @@ -273,7 +283,7 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs, assert(r = 0); for (i = 0; i total_queues; i++) { -vhost_net_stop_one(tap_get_vhost_net(ncs[i].peer), dev); +vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev); } } @@ -293,6 +303,29 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, { vhost_virtqueue_mask(net-dev, dev, idx, mask); } + +VHostNetState *get_vhost_net(NetClientState *nc) +{ +
[Qemu-devel] [PATCH v2 05/10] target-arm: A64: Add SIMD TBL/TBLX
From: Michael Matz m...@suse.de Add support for the SIMD TBL/TBLX instructions (group C3.6.2). Signed-off-by: Michael Matz m...@suse.de [PMM: rewritten to do more of the decode in translate-a64.c, and to do only one 64 bit pass at a time in the helper] Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- v1-v2: change rn and numregs args to helper to i32 --- target-arm/helper-a64.c| 31 ++ target-arm/helper-a64.h| 1 + target-arm/translate-a64.c | 55 +- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index 4ce0d01..6ca958a 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -122,3 +122,34 @@ uint64_t HELPER(vfp_cmped_a64)(float64 x, float64 y, void *fp_status) { return float_rel_to_flags(float64_compare(x, y, fp_status)); } + +uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices, + uint32_t rn, uint32_t numregs) +{ +/* Helper function for SIMD TBL and TBX. We have to do the table + * lookup part for the 64 bits worth of indices we're passed in. + * result is the initial results vector (either zeroes for TBL + * or some guest values for TBX), rn the register number where + * the table starts, and numregs the number of registers in the table. + * We return the results of the lookups. + */ +int shift; + +for (shift = 0; shift 64; shift += 8) { +int index = extract64(indices, shift, 8); +if (index 16 * numregs) { +/* Convert index (a byte offset into the virtual table + * which is a series of 128-bit vectors concatenated) + * into the correct vfp.regs[] element plus a bit offset + * into that element, bearing in mind that the table + * can wrap around from V31 to V0. + */ +int elt = (rn * 2 + (index 3)) % 64; +int bitidx = (index 7) * 8; +uint64_t val = extract64(env-vfp.regs[elt], bitidx, 8); + +result = deposit64(result, shift, 8, val); +} +} +return result; +} diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h index bca19f3..99832ee 100644 --- a/target-arm/helper-a64.h +++ b/target-arm/helper-a64.h @@ -26,3 +26,4 @@ DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr) DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr) DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr) DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr) +DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 219af78..3eae175 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -4743,7 +4743,60 @@ static void disas_simd_ext(DisasContext *s, uint32_t insn) */ static void disas_simd_tb(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int op2 = extract32(insn, 22, 2); +int is_q = extract32(insn, 30, 1); +int rm = extract32(insn, 16, 5); +int rn = extract32(insn, 5, 5); +int rd = extract32(insn, 0, 5); +int is_tblx = extract32(insn, 12, 1); +int len = extract32(insn, 13, 2); +TCGv_i64 tcg_resl, tcg_resh, tcg_idx; +TCGv_i32 tcg_regno, tcg_numregs; + +if (op2 != 0) { +unallocated_encoding(s); +return; +} + +/* This does a table lookup: for every byte element in the input + * we index into a table formed from up to four vector registers, + * and then the output is the result of the lookups. Our helper + * function does the lookup operation for a single 64 bit part of + * the input. + */ +tcg_resl = tcg_temp_new_i64(); +tcg_resh = tcg_temp_new_i64(); + +if (is_tblx) { +read_vec_element(s, tcg_resl, rd, 0, MO_64); +} else { +tcg_gen_movi_i64(tcg_resl, 0); +} +if (is_tblx is_q) { +read_vec_element(s, tcg_resh, rd, 1, MO_64); +} else { +tcg_gen_movi_i64(tcg_resh, 0); +} + +tcg_idx = tcg_temp_new_i64(); +tcg_regno = tcg_const_i32(rn); +tcg_numregs = tcg_const_i32(len + 1); +read_vec_element(s, tcg_idx, rm, 0, MO_64); +gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx, +tcg_regno, tcg_numregs); +if (is_q) { +read_vec_element(s, tcg_idx, rm, 1, MO_64); +gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx, +tcg_regno, tcg_numregs); +} +tcg_temp_free_i64(tcg_idx); +tcg_temp_free_i32(tcg_regno); +tcg_temp_free_i32(tcg_numregs); + +write_vec_element(s, tcg_resl, rd, 0, MO_64); +tcg_temp_free_i64(tcg_resl); +write_vec_element(s, tcg_resh, rd, 1, MO_64); +tcg_temp_free_i64(tcg_resh); } /* C3.6.3 ZIP/UZP/TRN -- 1.8.5
[Qemu-devel] [PATCH v2 08/10] target-arm: A64: Add SIMD copy operations
From: Alex Bennée alex.ben...@linaro.org This adds support for the all the AdvSIMD vector copy operations (ARM ARM 3.6.5). Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 210 - 1 file changed, 209 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 94f00c0..85daca9 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5070,6 +5070,173 @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn) tcg_temp_free_i64(tcg_res); } +/* C6.3.31 DUP (Element, Vector) + * + * 31 30 29 21 2016 1510 95 40 + * +---+---+---++-+--+--+ + * | 0 | Q | 0 0 1 1 1 0 0 0 0 | imm5 | 0 0 0 0 0 1 | Rn | Rd | + * +---+---+---++-+--+--+ + * + * size: encoded in imm5 (see ARM ARM LowestSetBit()) + */ +static void handle_simd_dupe(DisasContext *s, int is_q, int rd, int rn, + int imm5) +{ +int size = ctz32(imm5); +int esize = 8 size; +int elements = (is_q ? 128 : 64) / esize; +int index, i; +TCGv_i64 tmp; + +if (size 3 || (size == 3 !is_q)) { +unallocated_encoding(s); +return; +} + +index = imm5 (size + 1); + +tmp = tcg_temp_new_i64(); +read_vec_element(s, tmp, rn, index, size); + +for (i = 0; i elements; i++) { +write_vec_element(s, tmp, rd, i, size); +} + +if (!is_q) { +clear_vec_high(s, rd); +} + +tcg_temp_free_i64(tmp); +} + +/* C6.3.32 DUP (General) + * + * 31 30 29 21 2016 1510 95 40 + * +---+---+---++-+--+--+ + * | 0 | Q | 0 0 1 1 1 0 0 0 0 | imm5 | 0 0 0 0 1 1 | Rn | Rd | + * +---+---+---++-+--+--+ + * + * size: encoded in imm5 (see ARM ARM LowestSetBit()) + */ +static void handle_simd_dupg(DisasContext *s, int is_q, int rd, int rn, + int imm5) +{ +int size = ctz32(imm5); +int esize = 8 size; +int elements = (is_q ? 128 : 64)/esize; +int i = 0; + +if (size 3 || ((size == 3) !is_q)) { +unallocated_encoding(s); +return; +} +for (i = 0; i elements; i++) { +write_vec_element(s, cpu_reg(s, rn), rd, i, size); +} +if (!is_q) { +clear_vec_high(s, rd); +} +} + +/* C6.3.150 INS (Element) + * + * 31 21 2016 15 1411 10 95 40 + * +---+++---+--+--+ + * | 0 1 1 0 1 1 1 0 0 0 0 | imm5 | 0 | imm4 | 1 | Rn | Rd | + * +---+++---+--+--+ + * + * size: encoded in imm5 (see ARM ARM LowestSetBit()) + * index: encoded in imm54:size+1 + */ +static void handle_simd_inse(DisasContext *s, int rd, int rn, + int imm4, int imm5) +{ +int size = ctz32(imm5); +int src_index, dst_index; +TCGv_i64 tmp; + +if (size 3) { +unallocated_encoding(s); +return; +} +dst_index = extract32(imm5, 1+size, 5); +src_index = extract32(imm4, size, 4); + +tmp = tcg_temp_new_i64(); + +read_vec_element(s, tmp, rn, src_index, size); +write_vec_element(s, tmp, rd, dst_index, size); + +tcg_temp_free_i64(tmp); +} + + +/* C6.3.151 INS (General) + * + * 31 21 2016 1510 95 40 + * +---++-+--+--+ + * | 0 1 0 0 1 1 1 0 0 0 0 | imm5 | 0 0 0 1 1 1 | Rn | Rd | + * +---++-+--+--+ + * + * size: encoded in imm5 (see ARM ARM LowestSetBit()) + * index: encoded in imm54:size+1 + */ +static void handle_simd_insg(DisasContext *s, int rd, int rn, int imm5) +{ +int size = ctz32(imm5); +int idx; + +if (size 3) { +unallocated_encoding(s); +return; +} + +idx = extract32(imm5, 1 + size, 4 - size); +write_vec_element(s, cpu_reg(s, rn), rd, idx, size); +} + +/* + * C6.3.321 UMOV (General) + * C6.3.237 SMOV (General) + * + * 31 30 29 21 2016 1512 10 95 40 + * +---+---+---++-+--+--+ + * | 0 | Q | 0 0 1 1 1 0 0 0 0 | imm5 | 0 0 1 U 1 1 | Rn | Rd | + * +---+---+---++-+--+--+ + * + * U: unsigned when set + * size: encoded in imm5 (see ARM ARM LowestSetBit()) + */ +static void handle_simd_umov_smov(DisasContext *s, int is_q, int is_signed, + int rn, int rd, int imm5) +{ +int size = ctz32(imm5); +int element; +TCGv_i64 tcg_rd; + +/* Check for UnallocatedEncodings */ +if
[Qemu-devel] [PATCH v2 01/10] target-arm: A64: Add SIMD ld/st multiple
From: Alex Bennée alex.ben...@linaro.org This adds support support for the SIMD load/store multiple category of instructions. This also brings in a couple of helper functions for manipulating sections of the SIMD registers: * do_vec_get - fetch value from a slice of a vector register * do_vec_set - set a slice of a vector register which use vec_reg_offset for consistent processing of offsets in an endian aware manner. There are also additional helpers: * do_vec_ld - load value into SIMD * do_vec_st - store value from SIMD which load or store a slice of a vector register to memory. These don't zero extend like the fp variants. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- public v1-v2 changes: removed stray double-spacing fixed incorrect handling of rn==sp, cleaned up tcg_rn code --- target-arm/translate-a64.c | 250 - 1 file changed, 248 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index cf80c46..e4fdf00 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -308,6 +308,28 @@ static TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf) return v; } +/* Return the offset into CPUARMState of an element of specified + * size, 'element' places in from the least significant end of + * the FP/vector register Qn. + */ +static inline int vec_reg_offset(int regno, int element, TCGMemOp size) +{ +int offs = offsetof(CPUARMState, vfp.regs[regno * 2]); +#ifdef HOST_WORDS_BIGENDIAN +/* This is complicated slightly because vfp.regs[2n] is + * still the low half and vfp.regs[2n+1] the high half + * of the 128 bit vector, even on big endian systems. + * Calculate the offset assuming a fully bigendian 128 bits, + * then XOR to account for the order of the two 64 bit halves. + */ +offs += (16 - ((element + 1) * (1 size))); +offs ^= 8; +#else +offs += element * (1 size); +#endif +return offs; +} + /* Return the offset into CPUARMState of a slice (from * the least significant end) of FP register Qn (ie * Dn, Sn, Hn or Bn). @@ -661,6 +683,108 @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size) } /* + * Vector load/store helpers. + * + * The principal difference between this and a FP load is that we don't + * zero extend as we are filling a partial chunk of the vector register. + * These functions don't support 128 bit loads/stores, which would be + * normal load/store operations. + */ + +/* Get value of an element within a vector register */ +static void read_vec_element(DisasContext *s, TCGv_i64 tcg_dest, int srcidx, + int element, TCGMemOp memop) +{ +int vect_off = vec_reg_offset(srcidx, element, memop MO_SIZE); +switch (memop) { +case MO_8: +tcg_gen_ld8u_i64(tcg_dest, cpu_env, vect_off); +break; +case MO_16: +tcg_gen_ld16u_i64(tcg_dest, cpu_env, vect_off); +break; +case MO_32: +tcg_gen_ld32u_i64(tcg_dest, cpu_env, vect_off); +break; +case MO_8|MO_SIGN: +tcg_gen_ld8s_i64(tcg_dest, cpu_env, vect_off); +break; +case MO_16|MO_SIGN: +tcg_gen_ld16s_i64(tcg_dest, cpu_env, vect_off); +break; +case MO_32|MO_SIGN: +tcg_gen_ld32s_i64(tcg_dest, cpu_env, vect_off); +break; +case MO_64: +case MO_64|MO_SIGN: +tcg_gen_ld_i64(tcg_dest, cpu_env, vect_off); +break; +default: +g_assert_not_reached(); +} +} + +/* Set value of an element within a vector register */ +static void write_vec_element(DisasContext *s, TCGv_i64 tcg_src, int destidx, + int element, TCGMemOp memop) +{ +int vect_off = vec_reg_offset(destidx, element, memop MO_SIZE); +switch (memop) { +case MO_8: +tcg_gen_st8_i64(tcg_src, cpu_env, vect_off); +break; +case MO_16: +tcg_gen_st16_i64(tcg_src, cpu_env, vect_off); +break; +case MO_32: +tcg_gen_st32_i64(tcg_src, cpu_env, vect_off); +break; +case MO_64: +tcg_gen_st_i64(tcg_src, cpu_env, vect_off); +break; +default: +g_assert_not_reached(); +} +} + +/* Clear the high 64 bits of a 128 bit vector (in general non-quad + * vector ops all need to do this). + */ +static void clear_vec_high(DisasContext *s, int rd) +{ +TCGv_i64 tcg_zero = tcg_const_i64(0); + +write_vec_element(s, tcg_zero, rd, 1, MO_64); +tcg_temp_free_i64(tcg_zero); +} + +/* Store from vector register to memory */ +static void do_vec_st(DisasContext *s, int srcidx, int element, + TCGv_i64 tcg_addr, int size) +{ +TCGMemOp memop = MO_TE + size; +TCGv_i64 tcg_tmp = tcg_temp_new_i64(); + +read_vec_element(s, tcg_tmp, srcidx, element, size); +tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
[Qemu-devel] [PATCH v2 07/10] target-arm: A64: Add SIMD across-lanes instructions
From: Michael Matz m...@suse.de Add support for the SIMD across lanes instruction group (C3.6.4). Signed-off-by: Michael Matz m...@suse.de [PMM: Updated to current codebase, added fp min/max ops, added unallocated encoding checks] Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 177 - 1 file changed, 176 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 1c28c0f..94f00c0 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -4884,6 +4884,29 @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn) tcg_temp_free_i64(tcg_resh); } +static void do_minmaxop(DisasContext *s, TCGv_i32 tcg_elt1, TCGv_i32 tcg_elt2, +int opc, bool is_min, TCGv_ptr fpst) +{ +/* Helper function for disas_simd_across_lanes: do a single precision + * min/max operation on the specified two inputs, + * and return the result in tcg_elt1. + */ +if (opc == 0xc) { +if (is_min) { +gen_helper_vfp_minnums(tcg_elt1, tcg_elt1, tcg_elt2, fpst); +} else { +gen_helper_vfp_maxnums(tcg_elt1, tcg_elt1, tcg_elt2, fpst); +} +} else { +assert(opc == 0xf); +if (is_min) { +gen_helper_vfp_mins(tcg_elt1, tcg_elt1, tcg_elt2, fpst); +} else { +gen_helper_vfp_maxs(tcg_elt1, tcg_elt1, tcg_elt2, fpst); +} +} +} + /* C3.6.4 AdvSIMD across lanes * 31 30 29 28 24 23 22 21 17 1612 11 10 95 40 * +---+---+---+---+--+---++-+--+--+ @@ -4892,7 +4915,159 @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn) */ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int size = extract32(insn, 22, 2); +int opcode = extract32(insn, 12, 5); +bool is_q = extract32(insn, 30, 1); +bool is_u = extract32(insn, 29, 1); +bool is_fp = false; +bool is_min = false; +int esize; +int elements; +int i; +TCGv_i64 tcg_res, tcg_elt; + +switch (opcode) { +case 0x1b: /* ADDV */ +if (is_u) { +unallocated_encoding(s); +return; +} +/* fall through */ +case 0x3: /* SADDLV, UADDLV */ +case 0xa: /* SMAXV, UMAXV */ +case 0x1a: /* SMINV, UMINV */ +if (size == 3 || (size == 2 !is_q)) { +unallocated_encoding(s); +return; +} +break; +case 0xc: /* FMAXNMV, FMINNMV */ +case 0xf: /* FMAXV, FMINV */ +if (!is_u || !is_q || extract32(size, 0, 1)) { +unallocated_encoding(s); +return; +} +/* Bit 1 of size field encodes min vs max, and actual size is always + * 32 bits: adjust the size variable so following code can rely on it + */ +is_min = extract32(size, 1, 1); +is_fp = true; +size = 2; +break; +default: +unallocated_encoding(s); +return; +} + +esize = 8 size; +elements = (is_q ? 128 : 64) / esize; + +tcg_res = tcg_temp_new_i64(); +tcg_elt = tcg_temp_new_i64(); + +/* These instructions operate across all lanes of a vector + * to produce a single result. We can guarantee that a 64 + * bit intermediate is sufficient: + * + for [US]ADDLV the maximum element size is 32 bits, and + *the result type is 64 bits + * + for FMAX*V, FMIN*V, ADDV the intermediate type is the + *same as the element size, which is 32 bits at most + * For the integer operations we can choose to work at 64 + * or 32 bits and truncate at the end; for simplicity + * we use 64 bits always. The floating point + * ops do require 32 bit intermediates, though. + */ +if (!is_fp) { +read_vec_element(s, tcg_res, rn, 0, size | (is_u ? 0 : MO_SIGN)); + +for (i = 1; i elements; i++) { +read_vec_element(s, tcg_elt, rn, i, size | (is_u ? 0 : MO_SIGN)); + +switch (opcode) { +case 0x03: /* SADDLV / UADDLV */ +case 0x1b: /* ADDV */ +tcg_gen_add_i64(tcg_res, tcg_res, tcg_elt); +break; +case 0x0a: /* SMAXV / UMAXV */ +tcg_gen_movcond_i64(is_u ? TCG_COND_GEU : TCG_COND_GE, +tcg_res, +tcg_res, tcg_elt, tcg_res, tcg_elt); +break; +case 0x1a: /* SMINV / UMINV */ +tcg_gen_movcond_i64(is_u ? TCG_COND_LEU : TCG_COND_LE, +tcg_res, +tcg_res, tcg_elt, tcg_res, tcg_elt); +break; +break; +
Re: [Qemu-devel] [PATCH] Docs: Introduce multiport serial support in qemupciserial.inf
On Mon, Jan 13, 2014 at 11:13:07AM +0100, Gerd Hoffmann wrote: On Mi, 2014-01-08 at 17:11 +0100, Paolo Bonzini wrote: Il 08/01/2014 16:07, Yan Vugenfirer ha scritto: +%QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36DEV_0002SUBSYS_11001AF4REV_01 +%QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36DEV_0003SUBSYS_11001AF4REV_01 +%QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36DEV_0004SUBSYS_11001AF4REV_01 I think checking the subsystem is not necessary (and I think downstreams could legitimately change it). Can you check CC and REV but not SUBSYS? PNP ID can be reduced to vendor and device ID only, for example: PCI\VEN_1B36DEV_0002 . But in this case we cannot check revision. Gerd, Michael, what do you think is better? Not check revision, or enforcing subsystem? No need to check the revision. There is only one, I doubt this will ever change, and should we do a rev2 virtual hardware it is supposed to be backward-compatible to rev1 (otherwise we should hand out a new pci id to the device). [ drivers which depend on few features of the hypothetical rev2 hardware and don't work with rev1 would need a revision check ] cheers, Gerd Well linux checks revision: if (pci_dev-revision != VIRTIO_PCI_ABI_VERSION) { printk(KERN_ERR virtio_pci: expected ABI version %d, got %d\n, VIRTIO_PCI_ABI_VERSION, pci_dev-revision); return -ENODEV; } so it seems better to be consistent. in any case, we must check subsystem ids, the spec is very explicit on this point. -- MST
Re: [Qemu-devel] [Bug 1268596] Re: Compilation Error: hw/virtio/dataplane/vring.c:400:5: error: ‘ret’ may be used uninitialised in this function
On 13 January 2014 14:40, Paolo Bonzini bonz...@gnu.org wrote: What compiler is this? The variable is quite obviously initialized before that line. The issue is that one of the code paths has a shadowing declaration of 'ret' which is what gets assigned to, and so in that code path the compiler is correct that the outer 'ret' is not assigned to. Stefan said he was going to send out a fix for this. thanks -- PMM
Re: [Qemu-devel] [PATCH] Docs: Introduce multiport serial support in qemupciserial.inf
Il 13/01/2014 15:48, Michael S. Tsirkin ha scritto: if (pci_dev-revision != VIRTIO_PCI_ABI_VERSION) { printk(KERN_ERR virtio_pci: expected ABI version %d, got %d\n, VIRTIO_PCI_ABI_VERSION, pci_dev-revision); return -ENODEV; } so it seems better to be consistent. in any case, we must check subsystem ids, the spec is very explicit on this point. This is not a virtio device. Paolo
[Qemu-devel] [Bug 1268596] Re: Compilation Error: hw/virtio/dataplane/vring.c:400:5: error: ‘ret’ may be used uninitialised in this function
What compiler is this? The variable is quite obviously initialized before that line. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1268596 Title: Compilation Error: hw/virtio/dataplane/vring.c:400:5: error: ‘ret’ may be used uninitialised in this function Status in QEMU: New Bug description: Qemu git-cloned from mo. 13.01.14 (ca. 13:00 GMT), Version 1.7.50 #git clone git://git.qemu-project.org/qemu.git # cd qemu; git submodule update --init dtc #./configure --disable-xen --enable-kvm ...No Errors... #CC=ccache gcc make -j8 GEN qemu.1 Signing optionrom/kvmvapic.bin GEN qemu-img.1 CCqapi-types.o hw/virtio/dataplane/vring.c: In function ‘vring_pop’: hw/virtio/dataplane/vring.c:400:5: error: ‘ret’ may be used uninitialised in this function [-Werror=uninitialized] cc1: all warnings being treated as errors make: *** [hw/virtio/dataplane/vring.o] Error 1 make: *** Waiting for unfinished jobs File hw/virtio/dataplane/vring.c: === out: assert(ret 0); Line: 400 if (ret == -EFAULT) { vring-broken = true; } if (elem) { vring_free_element(elem); } *p_elem = NULL; return ret; } === Thx. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1268596/+subscriptions
Re: [Qemu-devel] chroot jailing...
immersive.ex...@gmail.com writes: Thanks! So it sounds like you're saying selinux is the only meaningful thing to try? Or do people ever bother to place qemu in chroot jails?? I seem to have gotten the impression that people use qemu-static to do this, but it appears to be more for offering secured access of a guest folder to the host OS; The qemu-static + chroot approach is mainly to avoid doing complex path manipulation between host/guest file-systems AFAICT. not so much for security... snip -- Alex Bennée
Re: [Qemu-devel] [PATCH] Docs: Introduce multiport serial support in qemupciserial.inf
Il 13/01/2014 16:03, Michael S. Tsirkin ha scritto: so it seems better to be consistent. in any case, we must check subsystem ids, the spec is very explicit on this point. This is not a virtio device. Paolo oh I didn't realize that - thought it's virtio serial we are talking about. In that case I agree with Gerd. Ok, so we all agree. Miki, can you do v2 with the same ID (vendor/product/CC)? Thanks, Paolo
Re: [Qemu-devel] [PATCH] Docs: Introduce multiport serial support in qemupciserial.inf
On Mon, Jan 13, 2014 at 03:56:49PM +0100, Paolo Bonzini wrote: Il 13/01/2014 15:48, Michael S. Tsirkin ha scritto: if (pci_dev-revision != VIRTIO_PCI_ABI_VERSION) { printk(KERN_ERR virtio_pci: expected ABI version %d, got %d\n, VIRTIO_PCI_ABI_VERSION, pci_dev-revision); return -ENODEV; } so it seems better to be consistent. in any case, we must check subsystem ids, the spec is very explicit on this point. This is not a virtio device. Paolo oh I didn't realize that - thought it's virtio serial we are talking about. In that case I agree with Gerd.
Re: [Qemu-devel] [PATCH 4/5] net: add offloadings support to netmap backend
2014/1/13 Stefan Hajnoczi stefa...@gmail.com On Fri, Dec 13, 2013 at 01:05:02PM +0100, Vincenzo Maffione wrote: +static void netmap_using_vnet_hdr(NetClientState *nc, bool enable) +{ +} I was trying to figure out whether it's okay for this function to be a nop. I've come to the conclusion that it's okay: If the netdev supports vnet_hdr then we enable vnet_hdr. If not, it will not enable it. Other NICs never enable vnet_hdr even if the netdev supports it. This interface is basically useless because set_vnet_hdr_len() is also needed and provides the same information, i.e. that we are transitioning from vnet_hdr off - on. The bool argument is misleading since we never use this function to disable vnet_hdr. It's impossible to transition on - off. I suggest removing using_vnet_hdr() and instead relying solely on set_vnet_hdr_len(). Do this as the first patch in the series before introducing the function pointers, that way all your following patches become simpler. Completely agree. As usual, I didn't want to change too much the existing code. This means that I have to remove the tap_using_vnet_hdr() calls from virtio-net and vmxnet3 NICs before this patches, haven't I? +static void netmap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, + int ecn, int ufo) +{ +} This interface is necessary for toggling offload features at runtime, e.g. because ethtool was used inside the guest. Offloads can impact performance and sometimes expose bugs. Therefore users may wish to disable certain offloads. Please consider supporting set_offload()! Yes, we are considering to do that, but at the moment there is no such a support. +static void netmap_set_vnet_hdr_len(NetClientState *nc, int len) +{ +NetmapState *s = DO_UPCAST(NetmapState, nc, nc); +int err; +struct nmreq req; + +/* Issue a NETMAP_BDG_OFFSET command to change the netmap adapter + offset of 'me-ifname'. */ +memset(req, 0, sizeof(req)); +pstrcpy(req.nr_name, sizeof(req.nr_name), s-me.ifname); +req.nr_version = NETMAP_API; +req.nr_cmd = NETMAP_BDG_OFFSET; +req.nr_arg1 = len; +err = ioctl(s-me.fd, NIOCREGIF, req); +if (err) { +error_report(Unable to execute NETMAP_BDG_OFFSET on %s: %s, + s-me.ifname, strerror(errno)); +} else { +/* Keep track of the current length, may be usefule in the future. */ s/usefule/useful/ -- Vincenzo Maffione
Re: [Qemu-devel] 回复: Re: [PATCH] linux-user: sync syscall numbers upto 3.13
On 13 January 2014 15:14, 管雪涛 g...@pku.edu.cn wrote: The syscall numbers in unicore32 are correct because we have two ABIs for 32 bits. In qemu, it's old ABI, while in kernel, it's new ABI. However, for now, old ABI is widely used for unicore32's applications. I don't think upstream QEMU should be supporting an ABI which isn't used by upstream Linux. If you didn't get it upstream into the kernel we should never have accepted it into QEMU to start with, really. thanks -- PMM
[Qemu-devel] Question about drive mirror
Hi,everyone. I tested the capability of drive mirror, I found the IO is low. Then I read the code, The code mirror_run() will call mirror_iteration() to read the size of buffer data from source storage, when the read callback ,and then in mirror_read_complete () write the data to the target storage, It is serial. Now, I hope when it is writing the data to target storage ,we can send the request of reading data from source storage. Because of using coroutine to do it ,there is some troubles to achieve it. why not use Multi-thread? Some one can give me some idea? Thanks. zhang min
Re: [Qemu-devel] [PATCH v2 01/10] target-arm: A64: Add SIMD ld/st multiple
On 01/13/2014 06:13 AM, Peter Maydell wrote: From: Alex Bennée alex.ben...@linaro.org This adds support support for the SIMD load/store multiple category of instructions. This also brings in a couple of helper functions for manipulating sections of the SIMD registers: * do_vec_get - fetch value from a slice of a vector register * do_vec_set - set a slice of a vector register which use vec_reg_offset for consistent processing of offsets in an endian aware manner. There are also additional helpers: * do_vec_ld - load value into SIMD * do_vec_st - store value from SIMD which load or store a slice of a vector register to memory. These don't zero extend like the fp variants. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- public v1-v2 changes: removed stray double-spacing fixed incorrect handling of rn==sp, cleaned up tcg_rn code --- target-arm/translate-a64.c | 250 - 1 file changed, 248 insertions(+), 2 deletions(-) Reviewed-by: Richard Henderson r...@twiddle.net r~
Re: [Qemu-devel] [PATCH v2 02/10] target-arm: A64: Add SIMD ld/st single
On 01/13/2014 06:13 AM, Peter Maydell wrote: Implement the SIMD ld/st single structure instructions. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- public v1-v2 changes: * same tcg_rn cleanup/fix as ld/st multiple --- target-arm/translate-a64.c | 144 - 1 file changed, 142 insertions(+), 2 deletions(-) Reviewed-by: Richard Henderson r...@twiddle.net r~
Re: [Qemu-devel] [PATCH v2 03/10] target-arm: A64: Add decode skeleton for SIMD data processing insns
On 01/13/2014 06:13 AM, Peter Maydell wrote: From: Alex Bennée alex.ben...@linaro.org Add decode skeleton and function placeholders for all the SIMD data processing instructions. Due to the complexity of this part of the table the normal extract and switch approach gets very messy very quickly, so we use a simple data-driven pattern-and-mask approach. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- v1-v2: * made data_proc_simd table const * fixed errors in insn diagram comments * fixed coding style for fn pointer call --- target-arm/translate-a64.c | 306 - 1 file changed, 305 insertions(+), 1 deletion(-) Reviewed-by: Richard Henderson r...@twiddle.net r~
Re: [Qemu-devel] [PATCH v2 04/10] target-arm: A64: Add SIMD EXT
On 01/13/2014 06:13 AM, Peter Maydell wrote: +if (!is_q) { +read_vec_element(s, tcg_resl, rn, 0, MO_64); +if (pos != 0) { +read_vec_element(s, tcg_resh, rm, 0, MO_64); +read_vec_element(s, tcg_resl, rn, 0, MO_64); Duplicate resl read. Otherwise, Reviewed-by: Richard Henderson r...@twiddle.net r~
[Qemu-devel] [PATCH v15 1/9] rules.mak: fix $(obj) to a real relative path
From: Fam Zheng f...@redhat.com Makefile.target includes rule.mak and unnested common-obj-y, then prefix them with '../', this will ignore object specific QEMU_CFLAGS in subdir Makefile.objs: $(obj)/curl.o: QEMU_CFLAGS += $(CURL_CFLAGS) Because $(obj) here is './block', instead of '../block'. This doesn't hurt compiling because we basically build all .o from top Makefile, before entering Makefile.target, but it will affact arriving per-object libs support. The starting point of $(obj) is passed in as argument of unnest-vars, as well as nested variables, so that different Makefiles can pass in a right value. Signed-off-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- Makefile| 14 ++ Makefile.objs | 17 + Makefile.target | 17 + configure |1 + rules.mak | 14 +- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index bdff4e4..423ace5 100644 --- a/Makefile +++ b/Makefile @@ -122,6 +122,16 @@ defconfig: ifneq ($(wildcard config-host.mak),) include $(SRC_PATH)/Makefile.objs +endif + +dummy := $(call unnest-vars,, \ +stub-obj-y \ +util-obj-y \ +qga-obj-y \ +block-obj-y \ +common-obj-y) + +ifneq ($(wildcard config-host.mak),) include $(SRC_PATH)/tests/Makefile endif ifeq ($(CONFIG_SMARTCARD_NSS),y) @@ -130,6 +140,10 @@ endif all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all +vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) + +vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) + config-host.h: config-host.h-timestamp config-host.h-timestamp: config-host.mak qemu-options.def: $(SRC_PATH)/qemu-options.hx diff --git a/Makefile.objs b/Makefile.objs index 2b6c1fe..91235a6 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -41,7 +41,7 @@ libcacard-y += libcacard/vcardt.o # single QEMU executable should support all CPUs and machines. ifeq ($(CONFIG_SOFTMMU),y) -common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/ +common-obj-y = blockdev.o blockdev-nbd.o block/ common-obj-y += net/ common-obj-y += readline.o common-obj-y += qdev-monitor.o device-hotplug.o @@ -110,18 +110,3 @@ version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo # by libqemuutil.a. These should be moved to a separate .json schema. qga-obj-y = qga/ qapi-types.o qapi-visit.o qga-vss-dll-obj-y = qga/ - -vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) - -vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) - -QEMU_CFLAGS+=$(GLIB_CFLAGS) - -nested-vars += \ - stub-obj-y \ - util-obj-y \ - qga-obj-y \ - qga-vss-dll-obj-y \ - block-obj-y \ - common-obj-y -dummy := $(call unnest-vars) diff --git a/Makefile.target b/Makefile.target index af6ac7e..9a6e7dd 100644 --- a/Makefile.target +++ b/Makefile.target @@ -139,13 +139,22 @@ endif # CONFIG_SOFTMMU # Workaround for http://gcc.gnu.org/PR55489, see configure. %/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS) -nested-vars += obj-y +dummy := $(call unnest-vars,,obj-y) -# This resolves all nested paths, so it must come last +# we are making another call to unnest-vars with different vars, protect obj-y, +# it can be overriden in subdir Makefile.objs +obj-y-save := $(obj-y) + +block-obj-y := +common-obj-y := include $(SRC_PATH)/Makefile.objs +dummy := $(call unnest-vars,..,block-obj-y common-obj-y) + +# Now restore obj-y +obj-y := $(obj-y-save) -all-obj-y = $(obj-y) -all-obj-y += $(addprefix ../, $(common-obj-y)) +all-obj-y = $(obj-y) $(common-obj-y) +all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) ifndef CONFIG_HAIKU LIBS+=-lm diff --git a/configure b/configure index 3782a6a..4990648 100755 --- a/configure +++ b/configure @@ -2345,6 +2345,7 @@ fi if $pkg_config --atleast-version=$glib_req_ver gthread-2.0; then glib_cflags=`$pkg_config --cflags gthread-2.0` glib_libs=`$pkg_config --libs gthread-2.0` +CFLAGS=$glib_cflags $CFLAGS LIBS=$glib_libs $LIBS libs_qga=$glib_libs $libs_qga else diff --git a/rules.mak b/rules.mak index 49edb9b..7d27602 100644 --- a/rules.mak +++ b/rules.mak @@ -138,9 +138,6 @@ clean: clean-timestamp # magic to descend into other directories -obj := . -old-nested-dirs := - define push-var $(eval save-$2-$1 = $(value $1)) $(eval $1 :=) @@ -154,9 +151,11 @@ endef define unnest-dir $(foreach var,$(nested-vars),$(call push-var,$(var),$1/)) -$(eval obj := $(obj)/$1) +$(eval obj-parent-$1 := $(obj)) +$(eval obj := $(if $(obj),$(obj)/$1,$1)) $(eval include $(SRC_PATH)/$1/Makefile.objs) -$(eval obj := $(patsubst %/$1,%,$(obj))) +$(eval obj := $(obj-parent-$1)) +$(eval obj-parent-$1 := ) $(foreach var,$(nested-vars),$(call pop-var,$(var),$1/)) endef @@ -171,7 +170,12 @@ $(if $(nested-dirs), endef define unnest-vars +$(eval obj := $1) +$(eval nested-vars := $2) +$(eval old-nested-dirs := ) $(call unnest-vars-1) +$(if $1,$(foreach v,$(nested-vars),$(eval \ + $v := $(addprefix $1/,$($v)
[Qemu-devel] [PATCH v15 5/9] build-sys: introduce common-obj-m and block-obj-m for DSO
From: Fam Zheng f...@redhat.com Add necessary rules and flags for shared object generation. $(common-obj-m) will include $(block-obj-m), like $(common-obj-y) does for $(block-obj-y). The new rules introduced here are: 0) For all %.so compiling: QEMU_CFLAGS += -fPIC 1) %.o in $(common-obj-m) is compiled to %.o, then linked to %.so. 2) %.mo in $(common-obj-m) is the placeholder for %.so for pattern matching in Makefile. It's linked to -shared with all its dependencies (multiple *.o) as input. Which means the list of depended objects must be specified in each sub-Makefile.objs: foo.mo-objs := bar.o baz.o qux.o in the same style with foo.o-cflags and foo.o-libs. The objects here will be prefixed with $(obj)/ if it's a subdirectory Makefile.objs. Also introduce --enable-modules in configure, the option will enable support of shared object build. Otherwise objects are static linked to executables. Signed-off-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- Makefile|9 +++-- Makefile.objs |2 ++ Makefile.target |6 +- configure | 14 ++ rules.mak | 54 +- 5 files changed, 73 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 423ace5..9de66cb 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,9 @@ dummy := $(call unnest-vars,, \ util-obj-y \ qga-obj-y \ block-obj-y \ -common-obj-y) +block-obj-m \ +common-obj-y \ +common-obj-m) ifneq ($(wildcard config-host.mak),) include $(SRC_PATH)/tests/Makefile @@ -138,7 +140,7 @@ ifeq ($(CONFIG_SMARTCARD_NSS),y) include $(SRC_PATH)/libcacard/Makefile endif -all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all +all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) @@ -256,6 +258,9 @@ clean: rm -f qemu-options.def find . -name '*.[oda]' -type f -exec rm -f {} + find . -name '*.l[oa]' -type f -exec rm -f {} + + find . -name '*.so' -type f -exec rm -f {} + + find . -name '*.mo' -type f -exec rm -f {} + + find . -name '*.dll' -type f -exec rm -f {} + rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ rm -f fsdev/*.pod rm -rf .libs */.libs diff --git a/Makefile.objs b/Makefile.objs index 91235a6..072d2e5 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -19,6 +19,8 @@ block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o block-obj-y += qemu-coroutine-sleep.o block-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o +block-obj-m = block/ + ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy) # Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add. # only pull in the actual virtio-9p device if we also enabled virtio. diff --git a/Makefile.target b/Makefile.target index 9a6e7dd..3945260 100644 --- a/Makefile.target +++ b/Makefile.target @@ -148,7 +148,11 @@ obj-y-save := $(obj-y) block-obj-y := common-obj-y := include $(SRC_PATH)/Makefile.objs -dummy := $(call unnest-vars,..,block-obj-y common-obj-y) +dummy := $(call unnest-vars,.., \ + block-obj-y \ + block-obj-m \ + common-obj-y \ + common-obj-m) # Now restore obj-y obj-y := $(obj-y-save) diff --git a/configure b/configure index 99434e6..6b46c66 100755 --- a/configure +++ b/configure @@ -205,6 +205,9 @@ mingw32=no gcov=no gcov_tool=gcov EXESUF= +DSOSUF=.so +LDFLAGS_SHARED=-shared +modules=no prefix=/usr/local mandir=\${prefix}/share/man datadir=\${prefix}/share @@ -513,6 +516,7 @@ OpenBSD) Darwin) bsd=yes darwin=yes + LDFLAGS_SHARED=-bundle if [ $cpu = x86_64 ] ; then QEMU_CFLAGS=-arch x86_64 $QEMU_CFLAGS LDFLAGS=-arch x86_64 $LDFLAGS @@ -606,6 +610,7 @@ fi if test $mingw32 = yes ; then EXESUF=.exe + DSOSUF=.dll QEMU_CFLAGS=-DWIN32_LEAN_AND_MEAN -DWINVER=0x501 $QEMU_CFLAGS # enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) QEMU_CFLAGS=-D__USE_MINGW_ANSI_STDIO=1 $QEMU_CFLAGS @@ -672,6 +677,8 @@ for opt do ;; --disable-debug-info) ;; + --enable-modules) modules=yes + ;; --cpu=*) ;; --target-list=*) target_list=$optarg @@ -1124,6 +1131,7 @@ Advanced options (experts only): --sysconfdir=PATHinstall config in PATH$confsuffix --localstatedir=PATH install local state in PATH (set at runtime on win32) --with-confsuffix=SUFFIX suffix for QEMU data inside datadir and sysconfdir [$confsuffix] + --enable-modules enable modules support --enable-debug-tcg enable TCG debugging --disable-debug-tcg disable TCG debugging (default) --enable-debug-info enable debugging information (default) @@ -3736,6 +3744,7 @@ echo python$python if test $slirp = yes ; then
[Qemu-devel] [PATCH v15 2/9] rules.mak: allow per object cflags and libs
From: Fam Zheng f...@redhat.com Adds extract-libs in LINK to expand any per object libs, the syntax to define such a libs options is like: foo.o-libs := $(CURL_LIBS) in block/Makefile.objs. Similarly, foo.o-cflags := $(FOO_CFLAGS) is also supported. foo.o must be listed in a nested var (e.g. common-obj-y) to make the option variables effective. Signed-off-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- rules.mak | 19 --- 1 files changed, 16 insertions(+), 3 deletions(-) diff --git a/rules.mak b/rules.mak index 7d27602..9398268 100644 --- a/rules.mak +++ b/rules.mak @@ -21,15 +21,17 @@ QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d # Same as -I$(SRC_PATH) -I., but for the nested source/object directories QEMU_INCLUDES += -I$(D) -I$(@D) +extract-libs = $(strip $(foreach o,$1,$($o-libs))) + %.o: %.c - $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $, CC$(TARGET_DIR)$@) + $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o $@ $, CC$(TARGET_DIR)$@) %.o: %.rc $(call quiet-command,$(WINDRES) -I. -o $@ $, RC$(TARGET_DIR)$@) ifeq ($(LIBTOOL),) LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \ $(sort $(filter %.o, $1)) $(filter-out %.o, $1) $(version-obj-y) \ - $(LIBS), LINK $(TARGET_DIR)$@) + $(call extract-libs,$^) $(LIBS), LINK $(TARGET_DIR)$@) else LIBTOOL += $(if $(V),,--quiet) %.lo: %.c @@ -45,7 +47,7 @@ LINK = $(call quiet-command,\ $(sort $(filter %.o, $1)) $(filter-out %.o, $1) \ $(if $(filter %.lo %.la,$^),$(version-lobj-y),$(version-obj-y)) \ $(if $(filter %.lo %.la,$^),$(LIBTOOLFLAGS)) \ - $(LIBS),$(if $(filter %.lo %.la,$^),lt LINK , LINK )$(TARGET_DIR)$@) + $(call extract-libs,$^) $(LIBS),$(if $(filter %.lo %.la,$^),lt LINK , LINK )$(TARGET_DIR)$@) endif %.asm: %.S @@ -149,11 +151,22 @@ $(eval $1 = $(value save-$2-$1) $$(subdir-$2-$1)) $(eval save-$2-$1 :=) endef +define fix-obj-vars +$(foreach v,$($1), \ + $(if $($v-cflags), \ + $(eval $2$v-cflags := $($v-cflags)) \ + $(eval $v-cflags := )) \ + $(if $($v-libs), \ + $(eval $2$v-libs := $($v-libs)) \ + $(eval $v-libs := ))) +endef + define unnest-dir $(foreach var,$(nested-vars),$(call push-var,$(var),$1/)) $(eval obj-parent-$1 := $(obj)) $(eval obj := $(if $(obj),$(obj)/$1,$1)) $(eval include $(SRC_PATH)/$1/Makefile.objs) +$(foreach v,$(nested-vars),$(call fix-obj-vars,$v,$(if $(obj),$(obj)/))) $(eval obj := $(obj-parent-$1)) $(eval obj-parent-$1 := ) $(foreach var,$(nested-vars),$(call pop-var,$(var),$1/)) -- 1.7.1
[Qemu-devel] [PATCH v15 3/9] block: use per-object cflags and libs
From: Fam Zheng f...@redhat.com No longer adds flags and libs for them to global variables, instead create config-host.mak variables like FOO_CFLAGS and FOO_LIBS, which is used as per object cflags and libs. This removes unwanted dependencies from libcacard. Signed-off-by: Fam Zheng f...@redhat.com [Split from Fam's patch to enable modules. - Paolo] Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- block/Makefile.objs | 13 - configure | 25 ++--- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/block/Makefile.objs b/block/Makefile.objs index 4e8c91e..a1db63f 100644 --- a/block/Makefile.objs +++ b/block/Makefile.objs @@ -23,4 +23,15 @@ common-obj-y += commit.o common-obj-y += mirror.o common-obj-y += backup.o -$(obj)/curl.o: QEMU_CFLAGS+=$(CURL_CFLAGS) +iscsi.o-cflags := $(LIBISCSI_CFLAGS) +iscsi.o-libs := $(LIBISCSI_LIBS) +curl.o-cflags := $(CURL_CFLAGS) +curl.o-libs:= $(CURL_LIBS) +rbd.o-cflags := $(RBD_CFLAGS) +rbd.o-libs := $(RBD_LIBS) +gluster.o-cflags := $(GLUSTERFS_CFLAGS) +gluster.o-libs := $(GLUSTERFS_LIBS) +ssh.o-cflags := $(LIBSSH2_CFLAGS) +ssh.o-libs := $(LIBSSH2_LIBS) +qcow.o-libs:= -lz +linux-aio.o-libs := -laio diff --git a/configure b/configure index 4990648..9d71867 100755 --- a/configure +++ b/configure @@ -2303,8 +2303,6 @@ EOF curl_libs=`$curlconfig --libs 2/dev/null` if compile_prog $curl_cflags $curl_libs ; then curl=yes -libs_tools=$curl_libs $libs_tools -libs_softmmu=$curl_libs $libs_softmmu else if test $curl = yes ; then feature_not_found curl @@ -2460,8 +2458,6 @@ EOF rbd_libs=-lrbd -lrados if compile_prog $rbd_libs ; then rbd=yes -libs_tools=$rbd_libs $libs_tools -libs_softmmu=$rbd_libs $libs_softmmu else if test $rbd = yes ; then feature_not_found rados block device @@ -2478,9 +2474,6 @@ if test $libssh2 != no ; then libssh2_cflags=`$pkg_config libssh2 --cflags` libssh2_libs=`$pkg_config libssh2 --libs` libssh2=yes -libs_tools=$libssh2_libs $libs_tools -libs_softmmu=$libssh2_libs $libs_softmmu -QEMU_CFLAGS=$QEMU_CFLAGS $libssh2_cflags else if test $libssh2 = yes ; then error_exit libssh2 = $min_libssh2_version required for --enable-libssh2 @@ -2526,8 +2519,6 @@ int main(void) { io_setup(0, NULL); io_set_eventfd(NULL, 0); eventfd(0, 0); retu EOF if compile_prog -laio ; then linux_aio=yes -libs_softmmu=$libs_softmmu -laio -libs_tools=$libs_tools -laio else if test $linux_aio = yes ; then feature_not_found linux AIO @@ -2696,9 +2687,6 @@ if test $glusterfs != no ; then glusterfs=yes glusterfs_cflags=`$pkg_config --cflags glusterfs-api` glusterfs_libs=`$pkg_config --libs glusterfs-api` -CFLAGS=$CFLAGS $glusterfs_cflags -libs_tools=$glusterfs_libs $libs_tools -libs_softmmu=$glusterfs_libs $libs_softmmu if $pkg_config --atleast-version=5 glusterfs-api; then glusterfs_discard=yes fi @@ -3066,11 +3054,9 @@ EOF libiscsi=yes libiscsi_cflags=$($pkg_config --cflags libiscsi) libiscsi_libs=$($pkg_config --libs libiscsi) -CFLAGS=$CFLAGS $libiscsi_cflags -LIBS=$LIBS $libiscsi_libs elif compile_prog -liscsi ; then libiscsi=yes -LIBS=$LIBS -liscsi +libiscsi_libs=-liscsi else if test $libiscsi = yes ; then feature_not_found libiscsi @@ -4068,6 +4054,7 @@ fi if test $curl = yes ; then echo CONFIG_CURL=y $config_host_mak echo CURL_CFLAGS=$curl_cflags $config_host_mak + echo CURL_LIBS=$curl_libs $config_host_mak fi if test $brlapi = yes ; then echo CONFIG_BRLAPI=y $config_host_mak @@ -4160,6 +4147,8 @@ if test $libiscsi = yes ; then if test $libiscsi_version = 1.4.0; then echo CONFIG_LIBISCSI_1_4=y $config_host_mak fi + echo LIBISCSI_CFLAGS=$libiscsi_cflags $config_host_mak + echo LIBISCSI_LIBS=$libiscsi_libs $config_host_mak fi if test $seccomp = yes; then @@ -4181,6 +4170,8 @@ if test $qom_cast_debug = yes ; then fi if test $rbd = yes ; then echo CONFIG_RBD=y $config_host_mak + echo RBD_CFLAGS=$rbd_cflags $config_host_mak + echo RBD_LIBS=$rbd_libs $config_host_mak fi echo CONFIG_COROUTINE_BACKEND=$coroutine $config_host_mak @@ -4224,6 +4215,8 @@ fi if test $glusterfs = yes ; then echo CONFIG_GLUSTERFS=y $config_host_mak + echo GLUSTERFS_CFLAGS=$glusterfs_cflags $config_host_mak + echo GLUSTERFS_LIBS=$glusterfs_libs $config_host_mak fi if test $glusterfs_discard = yes ; then @@ -4232,6 +4225,8 @@ fi if test $libssh2 = yes ; then echo CONFIG_LIBSSH2=y $config_host_mak + echo LIBSSH2_CFLAGS=$libssh2_cflags $config_host_mak + echo LIBSSH2_LIBS=$libssh2_libs $config_host_mak fi if test $virtio_blk_data_plane = yes ; then -- 1.7.1
[Qemu-devel] [PATCH v15 6/9] module: implement module loading
From: Fam Zheng f...@redhat.com This patch adds loading, stamp checking and initialization of modules. The init function of dynamic module is no longer directly called as __attribute__((constructor)) in static linked version, it is called only after passed the checking of presense of stamp symbol: qemu_stamp_$(date +%s$$$RANDOM) With this, modules built from a different tree/version/configure will not be loaded. The module loading code requires gmodule-2.0. Signed-off-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- Makefile |3 + configure | 31 +- include/qemu/module.h | 12 + rules.mak |7 ++- scripts/create_config | 14 ++ util/module.c | 107 - 6 files changed, 158 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 9de66cb..670ce44 100644 --- a/Makefile +++ b/Makefile @@ -203,6 +203,9 @@ Makefile: $(version-obj-y) $(version-lobj-y) libqemustub.a: $(stub-obj-y) libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o +block-modules = $(foreach o,$(block-obj-m),$(basename $(subst /,-,$o)),) NULL +util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)' + ## qemu-img.o: qemu-img-cmds.h diff --git a/configure b/configure index 6b46c66..c382044 100755 --- a/configure +++ b/configure @@ -677,7 +677,8 @@ for opt do ;; --disable-debug-info) ;; - --enable-modules) modules=yes + --enable-modules) + modules=yes ;; --cpu=*) ;; @@ -1130,7 +1131,7 @@ Advanced options (experts only): --libdir=PATHinstall libraries in PATH --sysconfdir=PATHinstall config in PATH$confsuffix --localstatedir=PATH install local state in PATH (set at runtime on win32) - --with-confsuffix=SUFFIX suffix for QEMU data inside datadir and sysconfdir [$confsuffix] + --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix] --enable-modules enable modules support --enable-debug-tcg enable TCG debugging --disable-debug-tcg disable TCG debugging (default) @@ -2346,15 +2347,19 @@ if test $mingw32 = yes; then else glib_req_ver=2.12 fi -if $pkg_config --atleast-version=$glib_req_ver gthread-2.0; then -glib_cflags=`$pkg_config --cflags gthread-2.0` -glib_libs=`$pkg_config --libs gthread-2.0` -CFLAGS=$glib_cflags $CFLAGS -LIBS=$glib_libs $LIBS -libs_qga=$glib_libs $libs_qga -else -error_exit glib-$glib_req_ver required to compile QEMU -fi + +for i in gthread-2.0 gmodule-2.0; do +if $pkg_config --atleast-version=$glib_req_ver $i; then +glib_cflags=`$pkg_config --cflags $i` +glib_libs=`$pkg_config --libs $i` +CFLAGS=$glib_cflags $CFLAGS +LIBS=$glib_libs $LIBS +libs_qga=$glib_libs $libs_qga +else +error_exit glib-$glib_req_ver required to compile QEMU +fi +done + ## # pixman support probe @@ -3628,6 +3633,7 @@ if test $mingw32 = yes ; then fi qemu_confdir=$sysconfdir$confsuffix +moddir=$libdir$confsuffix qemu_datadir=$datadir$confsuffix qemu_localedir=$datadir/locale @@ -3718,6 +3724,7 @@ echo Install prefix$prefix echo BIOS directory`eval echo $qemu_datadir` echo binary directory `eval echo $bindir` echo library directory `eval echo $libdir` +echo module directory `eval echo $moddir` echo libexec directory `eval echo $libexecdir` echo include directory `eval echo $includedir` echo config directory `eval echo $sysconfdir` @@ -3849,6 +3856,7 @@ echo all: $config_host_mak echo prefix=$prefix $config_host_mak echo bindir=$bindir $config_host_mak echo libdir=$libdir $config_host_mak +echo moddir=$moddir $config_host_mak echo libexecdir=$libexecdir $config_host_mak echo includedir=$includedir $config_host_mak echo mandir=$mandir $config_host_mak @@ -3867,6 +3875,7 @@ echo libs_softmmu=$libs_softmmu $config_host_mak echo ARCH=$ARCH $config_host_mak +echo CONFIG_STAMP=`date +%s`_$$_$RANDOM $config_host_mak if test $modules = yes; then echo CONFIG_MODULES=y $config_host_mak fi diff --git a/include/qemu/module.h b/include/qemu/module.h index c4ccd57..47b7f1d 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -14,11 +14,22 @@ #ifndef QEMU_MODULE_H #define QEMU_MODULE_H +#ifdef BUILD_DSO +void DSO_STAMP_FUN(void); +/* For error message, this function is an identification of qemu module */ +void qemu_module_dummy(void); + +#define module_init(function, type) \ +static void __attribute__((constructor)) do_qemu_init_ ## function(void) { \ +register_dso_module_init(function, type); \ +} +#else /* This should not be used directly. Use block_init etc. instead. */ #define module_init(function,
[Qemu-devel] [PATCH v15 8/9] .gitignore: ignore module related files (dll, so, mo)
From: Fam Zheng f...@redhat.com Signed-off-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- .gitignore |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/.gitignore b/.gitignore index 1c9d63d..7702b0c 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,9 @@ fsdev/virtfs-proxy-helper.pod *.cp *.dvi *.exe +*.dll +*.so +*.mo *.fn *.ky *.log -- 1.7.1
[Qemu-devel] [PATCH v15 4/9] darwin: do not use -mdynamic-no-pic
While -mdynamic-no-pic can speed up the code somewhat, it is only used on the legacy PowerPC Mac OS X, and I am not sure if anyone is still testing that. Disabling PIC can cause problems when enabling modules, so do not do that. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- configure |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 9d71867..99434e6 100755 --- a/configure +++ b/configure @@ -516,8 +516,6 @@ Darwin) if [ $cpu = x86_64 ] ; then QEMU_CFLAGS=-arch x86_64 $QEMU_CFLAGS LDFLAGS=-arch x86_64 $LDFLAGS - else -QEMU_CFLAGS=-mdynamic-no-pic $QEMU_CFLAGS fi cocoa=yes audio_drv_list=coreaudio -- 1.7.1
[Qemu-devel] [PATCH v15 0/9] Shared library module support
This is based on Fam's patches from October. Very few changes apart from rebasing: * I split his patch 8 in two parts. There is benefit in using per-object cflags and libs even before the module-loading machinery gets in. * I added a new patch darwin: do not use -mdynamic-no-pic. CCing Alex Graf for it. * applied the small change I had requested a small change in patch 2 I'm not sending a pull request yet because of these two changes, but I'll be sending one in a few days. Fam Zheng (8): rules.mak: fix $(obj) to a real relative path rules.mak: allow per object cflags and libs block: use per-object cflags and libs build-sys: introduce common-obj-m and block-obj-m for DSO module: implement module loading Makefile: install modules with make install .gitignore: ignore module related files (dll, so, mo) block: convert block drivers linked with libs to modules Paolo Bonzini (1): darwin: do not use -mdynamic-no-pic .gitignore|3 + Makefile | 30 +- Makefile.objs | 19 +--- Makefile.target | 21 -- block/Makefile.objs | 13 +- configure | 79 ++-- include/qemu/module.h | 12 + rules.mak | 80 ++-- scripts/create_config | 14 ++ util/module.c | 107 - 10 files changed, 310 insertions(+), 68 deletions(-)
[Qemu-devel] [PATCH v15 7/9] Makefile: install modules with make install
From: Fam Zheng f...@redhat.com Install all the modules to ${MODDIR}. Signed-off-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- Makefile |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/Makefile b/Makefile index 670ce44..a91f119 100644 --- a/Makefile +++ b/Makefile @@ -371,6 +371,12 @@ install-datadir install-localstatedir ifneq ($(TOOLS),) $(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) $(DESTDIR)$(bindir) endif +ifneq ($(CONFIG_MODULES),) + $(INSTALL_DIR) $(DESTDIR)$(moddir) + for s in $(patsubst %.mo,%$(DSOSUF),$(modules-m)); do \ + $(INSTALL_PROG) $(STRIP_OPT) $$s $(DESTDIR)$(moddir)/$${s//\//-}; \ + done +endif ifneq ($(HELPERS-y),) $(INSTALL_DIR) $(DESTDIR)$(libexecdir) $(INSTALL_PROG) $(STRIP_OPT) $(HELPERS-y) $(DESTDIR)$(libexecdir) -- 1.7.1
Re: [Qemu-devel] chroot jailing...
That's what I thought; just had to be sure. Thanks all... On 01/13/2014 09:38 AM, Alex Bennée wrote: immersive.ex...@gmail.com writes: Thanks! So it sounds like you're saying selinux is the only meaningful thing to try? Or do people ever bother to place qemu in chroot jails?? I seem to have gotten the impression that people use qemu-static to do this, but it appears to be more for offering secured access of a guest folder to the host OS; The qemu-static + chroot approach is mainly to avoid doing complex path manipulation between host/guest file-systems AFAICT. not so much for security... snip
[Qemu-devel] [PATCH v15 9/9] block: convert block drivers linked with libs to modules
From: Fam Zheng f...@redhat.com The converted block drivers are: curl iscsi rbd ssh glusterfs Signed-off-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- configure | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure b/configure index c382044..1f0c5b8 100755 --- a/configure +++ b/configure @@ -4071,7 +4071,7 @@ if test $bswap_h = yes ; then echo CONFIG_MACHINE_BSWAP_H=y $config_host_mak fi if test $curl = yes ; then - echo CONFIG_CURL=y $config_host_mak + echo CONFIG_CURL=m $config_host_mak echo CURL_CFLAGS=$curl_cflags $config_host_mak echo CURL_LIBS=$curl_libs $config_host_mak fi @@ -4162,7 +4162,7 @@ if test $glx = yes ; then fi if test $libiscsi = yes ; then - echo CONFIG_LIBISCSI=y $config_host_mak + echo CONFIG_LIBISCSI=m $config_host_mak if test $libiscsi_version = 1.4.0; then echo CONFIG_LIBISCSI_1_4=y $config_host_mak fi @@ -4188,7 +4188,7 @@ if test $qom_cast_debug = yes ; then echo CONFIG_QOM_CAST_DEBUG=y $config_host_mak fi if test $rbd = yes ; then - echo CONFIG_RBD=y $config_host_mak + echo CONFIG_RBD=m $config_host_mak echo RBD_CFLAGS=$rbd_cflags $config_host_mak echo RBD_LIBS=$rbd_libs $config_host_mak fi @@ -4233,7 +4233,7 @@ if test $getauxval = yes ; then fi if test $glusterfs = yes ; then - echo CONFIG_GLUSTERFS=y $config_host_mak + echo CONFIG_GLUSTERFS=m $config_host_mak echo GLUSTERFS_CFLAGS=$glusterfs_cflags $config_host_mak echo GLUSTERFS_LIBS=$glusterfs_libs $config_host_mak fi @@ -4243,7 +4243,7 @@ if test $glusterfs_discard = yes ; then fi if test $libssh2 = yes ; then - echo CONFIG_LIBSSH2=y $config_host_mak + echo CONFIG_LIBSSH2=m $config_host_mak echo LIBSSH2_CFLAGS=$libssh2_cflags $config_host_mak echo LIBSSH2_LIBS=$libssh2_libs $config_host_mak fi -- 1.7.1
[Qemu-devel] [PATCH 0/3] qga: vss-win32: Fix interference with other VSS requesters
Current functionarity of qemu-ga VSS provider is limited to implement filesystems freeze, and doesn't support the creation of shadow copies within the guest. However, when no other hardware snapshot provider is installed, VSS may choose qemu-ga VSS provider to create shadow copies and fail with VSS_E_UNEXPECTED_PROVIDER_ERROR. Similar issue occurs when the requester deletes shadow copies. This patchset fix this issue by telling VSS that the volume is not supported by qemu-ga VSS provider when it is kicked by other requesters. It also fixes wrong error handling around OpenEvent/CreateEvent WinAPI, which returns NULL instead of INVALID_HANDLE_VALUE on errors. https://bugzilla.redhat.com/show_bug.cgi?id=1036341 --- Tomoki Sekiyama (3): qga: vss-win32: Use NULL as an invalid pointer for OpenEvent and CreateEvent qga: vss-win32: Fix interference with snapshot creation by other VSS requesters qga: vss-win32: Fix interference with snapshot deletion by other VSS request qga/vss-win32/provider.cpp | 21 ++--- qga/vss-win32/requester.cpp | 70 --- 2 files changed, 49 insertions(+), 42 deletions(-) -- Tomoki Sekiyama
[Qemu-devel] [PATCH 2/3] qga: vss-win32: Fix interference with snapshot creation by other VSS requesters
When a VSS requester such as vshadow.exe or diskshadow.exe requests to create disk snapshots, Windows may choose qemu-ga VSS provider if it is only provider registered on the system. However, because it provides only a function to freeze the filesystem, the snapshotting fails. This patch adds a check into CQGAVssProvider::IsVolumeSupported() to reject the request from other VSS requesters, so that the other provider is chosen. The check of requester is done by confirming event channels between qemu-ga's requester and provider established. To ensure that the events are initialized when CQGAVssProvider::IsVolumeSupported() is called, it moves the initialization earlier. Signed-off-by: Tomoki Sekiyama tomoki.sekiy...@hds.com --- qga/vss-win32/provider.cpp | 11 - qga/vss-win32/requester.cpp | 52 ++- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/qga/vss-win32/provider.cpp b/qga/vss-win32/provider.cpp index c3030d8..b233646 100644 --- a/qga/vss-win32/provider.cpp +++ b/qga/vss-win32/provider.cpp @@ -291,8 +291,17 @@ STDMETHODIMP CQGAVssProvider::BeginPrepareSnapshot( STDMETHODIMP CQGAVssProvider::IsVolumeSupported( VSS_PWSZ pwszVolumeName, BOOL *pbSupportedByThisProvider) { -*pbSupportedByThisProvider = TRUE; +HANDLE hEventFrozen; + +/* Check if a requester is qemu-ga by whether an event is created */ +hEventFrozen = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_FROZEN); +if (!hEventFrozen) { +*pbSupportedByThisProvider = FALSE; +return S_OK; +} +CloseHandle(hEventFrozen); +*pbSupportedByThisProvider = TRUE; return S_OK; } diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp index 0a55447..922e74d 100644 --- a/qga/vss-win32/requester.cpp +++ b/qga/vss-win32/requester.cpp @@ -252,6 +252,32 @@ void requester_freeze(int *num_vols, ErrorSet *errset) CoInitialize(NULL); +/* Allow unrestricted access to events */ +InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); +SetSecurityDescriptorDacl(sd, TRUE, NULL, FALSE); +sa.nLength = sizeof(sa); +sa.lpSecurityDescriptor = sd; +sa.bInheritHandle = FALSE; + +vss_ctx.hEventFrozen = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_FROZEN); +if (!vss_ctx.hEventFrozen) { +err_set(errset, GetLastError(), failed to create event %s, +EVENT_NAME_FROZEN); +goto out; +} +vss_ctx.hEventThaw = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_THAW); +if (!vss_ctx.hEventThaw) { +err_set(errset, GetLastError(), failed to create event %s, +EVENT_NAME_THAW); +goto out; +} +vss_ctx.hEventTimeout = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_TIMEOUT); +if (!vss_ctx.hEventTimeout) { +err_set(errset, GetLastError(), failed to create event %s, +EVENT_NAME_TIMEOUT); +goto out; +} + assert(pCreateVssBackupComponents != NULL); hr = pCreateVssBackupComponents(vss_ctx.pVssbc); if (FAILED(hr)) { @@ -362,32 +388,6 @@ void requester_freeze(int *num_vols, ErrorSet *errset) goto out; } -/* Allow unrestricted access to events */ -InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); -SetSecurityDescriptorDacl(sd, TRUE, NULL, FALSE); -sa.nLength = sizeof(sa); -sa.lpSecurityDescriptor = sd; -sa.bInheritHandle = FALSE; - -vss_ctx.hEventFrozen = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_FROZEN); -if (!vss_ctx.hEventFrozen) { -err_set(errset, GetLastError(), failed to create event %s, -EVENT_NAME_FROZEN); -goto out; -} -vss_ctx.hEventThaw = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_THAW); -if (!vss_ctx.hEventThaw) { -err_set(errset, GetLastError(), failed to create event %s, -EVENT_NAME_THAW); -goto out; -} -vss_ctx.hEventTimeout = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_TIMEOUT); -if (!vss_ctx.hEventTimeout) { -err_set(errset, GetLastError(), failed to create event %s, -EVENT_NAME_TIMEOUT); -goto out; -} - /* * Start VSS quiescing operations. * CQGAVssProvider::CommitSnapshots will kick vss_ctx.hEventFrozen
[Qemu-devel] [PATCH 1/3] qga: vss-win32: Use NULL as an invalid pointer for OpenEvent and CreateEvent
OpenEvent and CreateEvent WinAPI return NULL when failed to open/create events handles, instead of INVALID_HANDLE_VALUE (although their return types are HANDLE). This replaces INVALID_HANDLE_VALUE related to event handles with NULL. Signed-off-by: Tomoki Sekiyama tomoki.sekiy...@hds.com --- qga/vss-win32/provider.cpp |6 +++--- qga/vss-win32/requester.cpp | 24 ++-- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/qga/vss-win32/provider.cpp b/qga/vss-win32/provider.cpp index bf42b5e..c3030d8 100644 --- a/qga/vss-win32/provider.cpp +++ b/qga/vss-win32/provider.cpp @@ -342,18 +342,18 @@ STDMETHODIMP CQGAVssProvider::CommitSnapshots(VSS_ID SnapshotSetId) HANDLE hEventFrozen, hEventThaw, hEventTimeout; hEventFrozen = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_FROZEN); -if (hEventFrozen == INVALID_HANDLE_VALUE) { +if (!hEventFrozen) { return E_FAIL; } hEventThaw = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_THAW); -if (hEventThaw == INVALID_HANDLE_VALUE) { +if (!hEventThaw) { CloseHandle(hEventFrozen); return E_FAIL; } hEventTimeout = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_TIMEOUT); -if (hEventTimeout == INVALID_HANDLE_VALUE) { +if (!hEventTimeout) { CloseHandle(hEventFrozen); CloseHandle(hEventThaw); return E_FAIL; diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp index 1e8dd3d..0a55447 100644 --- a/qga/vss-win32/requester.cpp +++ b/qga/vss-win32/requester.cpp @@ -50,10 +50,6 @@ static struct QGAVSSContext { STDAPI requester_init(void) { -vss_ctx.hEventFrozen = INVALID_HANDLE_VALUE; -vss_ctx.hEventThaw = INVALID_HANDLE_VALUE; -vss_ctx.hEventTimeout = INVALID_HANDLE_VALUE; - COMInitializer initializer; /* to call CoInitializeSecurity */ HRESULT hr = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, @@ -94,17 +90,17 @@ STDAPI requester_init(void) static void requester_cleanup(void) { -if (vss_ctx.hEventFrozen != INVALID_HANDLE_VALUE) { +if (vss_ctx.hEventFrozen) { CloseHandle(vss_ctx.hEventFrozen); -vss_ctx.hEventFrozen = INVALID_HANDLE_VALUE; +vss_ctx.hEventFrozen = NULL; } -if (vss_ctx.hEventThaw != INVALID_HANDLE_VALUE) { +if (vss_ctx.hEventThaw) { CloseHandle(vss_ctx.hEventThaw); -vss_ctx.hEventThaw = INVALID_HANDLE_VALUE; +vss_ctx.hEventThaw = NULL; } -if (vss_ctx.hEventTimeout != INVALID_HANDLE_VALUE) { +if (vss_ctx.hEventTimeout) { CloseHandle(vss_ctx.hEventTimeout); -vss_ctx.hEventTimeout = INVALID_HANDLE_VALUE; +vss_ctx.hEventTimeout = NULL; } if (vss_ctx.pAsyncSnapshot) { vss_ctx.pAsyncSnapshot-Release(); @@ -374,19 +370,19 @@ void requester_freeze(int *num_vols, ErrorSet *errset) sa.bInheritHandle = FALSE; vss_ctx.hEventFrozen = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_FROZEN); -if (vss_ctx.hEventFrozen == INVALID_HANDLE_VALUE) { +if (!vss_ctx.hEventFrozen) { err_set(errset, GetLastError(), failed to create event %s, EVENT_NAME_FROZEN); goto out; } vss_ctx.hEventThaw = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_THAW); -if (vss_ctx.hEventThaw == INVALID_HANDLE_VALUE) { +if (!vss_ctx.hEventThaw) { err_set(errset, GetLastError(), failed to create event %s, EVENT_NAME_THAW); goto out; } vss_ctx.hEventTimeout = CreateEvent(sa, TRUE, FALSE, EVENT_NAME_TIMEOUT); -if (vss_ctx.hEventTimeout == INVALID_HANDLE_VALUE) { +if (!vss_ctx.hEventTimeout) { err_set(errset, GetLastError(), failed to create event %s, EVENT_NAME_TIMEOUT); goto out; @@ -443,7 +439,7 @@ void requester_thaw(int *num_vols, ErrorSet *errset) { COMPointerIVssAsync pAsync; -if (vss_ctx.hEventThaw == INVALID_HANDLE_VALUE) { +if (!vss_ctx.hEventThaw) { /* * In this case, DoSnapshotSet is aborted or not started, * and no volumes must be frozen. We return without an error.
[Qemu-devel] [PATCH 3/3] qga: vss-win32: Fix interference with snapshot deletion by other VSS request
When a VSS requester such as vshadow.exe or diskshadow.exe requests to delete snapshots, qemu-ga VSS provider's DeleteSnapshots() is also called and returns E_NOTIMPL, that makes the deletion fail. To avoid this issue, return S_OK and set values that represent no snapshots are deleted by qemu-ga VSS provider. Signed-off-by: Tomoki Sekiyama tomoki.sekiy...@hds.com --- qga/vss-win32/provider.cpp |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qga/vss-win32/provider.cpp b/qga/vss-win32/provider.cpp index b233646..d5129f8 100644 --- a/qga/vss-win32/provider.cpp +++ b/qga/vss-win32/provider.cpp @@ -278,7 +278,9 @@ STDMETHODIMP CQGAVssProvider::DeleteSnapshots( VSS_ID SourceObjectId, VSS_OBJECT_TYPE eSourceObjectType, BOOL bForceDelete, LONG *plDeletedSnapshots, VSS_ID *pNondeletedSnapshotID) { -return E_NOTIMPL; +*plDeletedSnapshots = 0; +*pNondeletedSnapshotID = SourceObjectId; +return S_OK; } STDMETHODIMP CQGAVssProvider::BeginPrepareSnapshot(
[Qemu-devel] [PULL 00/49] migration queue
HI Anthony This is the patches in the migration queue. Please pull. v2: - Drop align ram on multiple of 64 bits, more investigation required - fix ftruncate error code (tested of Fedora20 and see the problem) Please pull, Juan. [v1] This includes: - Eduardo refactorings tests - Matthew rate limit fix - Zhanghaoyu CANCELLING fixes - My bitmap changes Integration work was done by Orit. Happy Christmas, Juan. The following changes since commit dd089c0a1e928fb80ba8a37983c1b0e9232d1c8b: Merge remote-tracking branch 'pmaydell/tags/pull-cocoa-20140112' into staging (2014-01-12 17:50:52 -0800) are available in the git repository at: git://github.com/juanquintela/qemu.git tags/migration/20140113 for you to fetch changes up to aa8dc044772ba156cbcf2174b5673cfa11f566a7: migration: synchronize memory bitmap 64bits at a time (2014-01-13 14:04:55 +0100) migration.next for 20140113 Eduardo Habkost (9): qemu-file: Make a few functions non-static migration: Move QEMU_VM_* defines to migration/migration.h savevm: Convert all tabs to spaces savevm.c: Coding style fixes savevm.c: Coding style fix vmstate: Move VMState code to vmstate.c qemu-file: Move QEMUFile code to qemu-file.c savevm: Small comment about why timer QEMUFile/VMState code is in savevm.c tests: Some unit tests for vmstate.c Juan Quintela (37): bitmap: use long as index memory: cpu_physical_memory_set_dirty_flags() result is never used memory: cpu_physical_memory_set_dirty_range() return void exec: use accessor function to know if memory is dirty memory: create function to set a single dirty bit exec: create function to get a single dirty bit memory: make cpu_physical_memory_is_dirty return bool memory: all users of cpu_physical_memory_get_dirty used only one flag memory: set single dirty flags when possible memory: cpu_physical_memory_set_dirty_range() always dirty all flags memory: cpu_physical_memory_mask_dirty_range() always clears a single flag memory: use bit 2 for migration memory: make sure that client is always inside range memory: only resize dirty bitmap when memory size increases memory: cpu_physical_memory_clear_dirty_flag() result is never used bitmap: Add bitmap_zero_extend operation memory: split dirty bitmap into three memory: unfold cpu_physical_memory_clear_dirty_flag() in its only user memory: unfold cpu_physical_memory_set_dirty() in its only user memory: unfold cpu_physical_memory_set_dirty_flag() memory: make cpu_physical_memory_get_dirty() the main function memory: cpu_physical_memory_get_dirty() is used as returning a bool memory: s/mask/clear/ cpu_physical_memory_mask_dirty_range memory: use find_next_bit() to find dirty bits memory: cpu_physical_memory_set_dirty_range() now uses bitmap operations memory: cpu_physical_memory_clear_dirty_range() now uses bitmap operations memory: s/dirty/clean/ in cpu_physical_memory_is_dirty() memory: make cpu_physical_memory_reset_dirty() take a length parameter memory: cpu_physical_memory_set_dirty_tracking() should return void memory: split cpu_physical_memory_* functions to its own include memory: unfold memory_region_test_and_clear() kvm: use directly cpu_physical_memory_* api for tracking dirty pages kvm: refactor start address calculation memory: move bitmap synchronization to its own function memory: syncronize kvm bitmap using bitmaps operations ram: split function that synchronizes a range migration: synchronize memory bitmap 64bits at a time Matthew Garrett (1): migration: Fix rate limit Zhanghaoyu (A) (2): avoid a bogus COMPLETED-CANCELLED transition introduce MIG_STATE_CANCELLING state Makefile.objs |2 + arch_init.c| 52 +- cputlb.c | 11 +- exec.c | 76 +- include/exec/cpu-all.h |3 +- include/exec/memory-internal.h | 90 --- include/exec/memory.h | 12 +- include/exec/ram_addr.h| 147 include/migration/migration.h | 11 + include/migration/qemu-file.h |4 + include/qemu/bitmap.h | 86 ++- include/qemu/bitops.h | 14 +- kvm-all.c | 28 +- memory.c | 17 +- migration.c| 33 +- qemu-file.c| 826 + savevm.c | 1590 ++-- tests/.gitignore |1 + tests/Makefile |4 + tests/test-vmstate.c | 357 + util/bitmap.c | 60 +- vmstate.c
[Qemu-devel] [PATCH 01/49] avoid a bogus COMPLETED-CANCELLED transition
From: Zhanghaoyu (A) haoyu.zh...@huawei.com Avoid a bogus COMPLETED-CANCELLED transition. There is a period of time from the timing of setting COMPLETED state to that of migration thread exits, so during which it's problematic in COMPLETED-CANCELLED transition. Signed-off-by: Zeng Junliang zengjunli...@huawei.com Signed-off-by: Zhang Haoyu haoyu.zh...@huawei.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Juan Quintela quint...@redhat.com --- migration.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/migration.c b/migration.c index 2b1ab20..fd73b97 100644 --- a/migration.c +++ b/migration.c @@ -326,9 +326,16 @@ void migrate_fd_error(MigrationState *s) static void migrate_fd_cancel(MigrationState *s) { +int old_state ; DPRINTF(cancelling migration\n); -migrate_set_state(s, s-state, MIG_STATE_CANCELLED); +do { +old_state = s-state; +if (old_state != MIG_STATE_SETUP old_state != MIG_STATE_ACTIVE) { +break; +} +migrate_set_state(s, old_state, MIG_STATE_CANCELLED); +} while (s-state != MIG_STATE_CANCELLED); } void add_migration_state_change_notifier(Notifier *notify) -- 1.8.4.2
[Qemu-devel] [PATCH 03/49] migration: Fix rate limit
From: Matthew Garrett matthew.garr...@nebula.com The migration thread appears to want to allow writeout to occur at full speed rather than being rate limited during completion of state saving, but sets the limit to INT_MAX when xfer_limit is INT64_MAX. This causes problems if there's more than 2GB of state left to save at this point. It probably ought to just be INT64_MAX instead. Signed-off-by: Matthew Garrett matthew.garr...@nebula.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Juan Quintela quint...@redhat.com --- migration.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migration.c b/migration.c index 4ee341b..e5f6b98 100644 --- a/migration.c +++ b/migration.c @@ -596,7 +596,7 @@ static void *migration_thread(void *opaque) ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); if (ret = 0) { -qemu_file_set_rate_limit(s-file, INT_MAX); +qemu_file_set_rate_limit(s-file, INT64_MAX); qemu_savevm_state_complete(s-file); } qemu_mutex_unlock_iothread(); -- 1.8.4.2