From 723250d674a1e9ff601e98b8700f8d631e7b9855 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Wed, 14 Feb 2018 17:36:33 +0100 Subject: [PATCH 01/34] g364fb: fix DirtyBitmapSnapshot leak Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- hw/display/g364fb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index 819f8be05d..3d75394e77 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -207,6 +207,7 @@ done: if (xmax || ymax) { dpy_gfx_update(s->con, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1); } + g_free(snap); } static void g364fb_draw_blank(G364State *s) From d07aa197c5a1556449361a0cbb5108e2e7b1adb7 Mon Sep 17 00:00:00 2001 From: Thomas Huth <thuth@redhat.com> Date: Mon, 19 Feb 2018 21:23:40 +0100 Subject: [PATCH 02/34] Remove the deprecated -tdf option It's been marked as deprecated since a very long time already, and the parameter is not doing anything useful anymore except for printing a warning, so it's now time to finally get rid of this option. Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <1519071820-4062-1-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- qemu-doc.texi | 7 ------- vl.c | 3 --- 2 files changed, 10 deletions(-) diff --git a/qemu-doc.texi b/qemu-doc.texi index 4fcc85acc7..76ca83feae 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2606,13 +2606,6 @@ which is the default. @section System emulator command line arguments -@subsection -tdf (since 1.3.0) - -The ``-tdf'' argument is ignored. The behaviour implemented -by this argument is now the default when using the KVM PIT, -but can be requested explicitly using -``-global kvm-pit.lost_tick_policy=slew''. - @subsection -no-kvm-pit-reinjection (since 1.3.0) The ``-no-kvm-pit-reinjection'' argument is now a diff --git a/vl.c b/vl.c index 6120b889ed..a92f60c8b7 100644 --- a/vl.c +++ b/vl.c @@ -3842,9 +3842,6 @@ int main(int argc, char **argv, char **envp) exit(1); } break; - case QEMU_OPTION_tdf: - warn_report("ignoring deprecated option"); - break; case QEMU_OPTION_name: opts = qemu_opts_parse_noisily(qemu_find_opts("name"), optarg, true); From 1454509726719e0933c800fad00d6999752688ea Mon Sep 17 00:00:00 2001 From: Thomas Huth <thuth@redhat.com> Date: Tue, 20 Feb 2018 11:42:37 +0100 Subject: [PATCH 03/34] scsi: Remove automatic creation of SCSI controllers with -drive if=scsi Automatic creation of SCSI controllers for "-drive if=scsi" for x86 machines was quite a bad idea (see description of commit f778a82f0c179 for details). This is marked as deprecated since QEMU v2.9.0, and as far as I know, nobody complained that this is still urgently required anymore. Time to remove this now. Suggested-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <1519123357-13225-1-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- hw/i386/pc.c | 17 --------------- hw/i386/pc_piix.c | 4 ---- hw/i386/pc_q35.c | 3 --- hw/scsi/lsi53c895a.c | 2 +- hw/scsi/scsi-bus.c | 49 +----------------------------------------- hw/scsi/spapr_vscsi.c | 3 +-- include/hw/scsi/scsi.h | 2 +- qemu-doc.texi | 5 ----- tests/qemu-iotests/051 | 4 ---- vl.c | 9 -------- 10 files changed, 4 insertions(+), 94 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 94cfd40ef2..35fcb6efdf 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1636,23 +1636,6 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus) rom_reset_order_override(); } -void pc_pci_device_init(PCIBus *pci_bus) -{ - int max_bus; - int bus; - - /* Note: if=scsi is deprecated with PC machine types */ - max_bus = drive_get_max_bus(IF_SCSI); - for (bus = 0; bus <= max_bus; bus++) { - pci_create_simple(pci_bus, -1, "lsi53c895a"); - /* - * By not creating frontends here, we make - * scsi_legacy_handle_cmdline() create them, and warn that - * this usage is deprecated. - */ - } -} - void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name) { DeviceState *dev; diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 456dc9e9f0..8658bcba63 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -295,10 +295,6 @@ static void pc_init1(MachineState *machine, PC_MACHINE_ACPI_DEVICE_PROP, &error_abort); } - if (pcmc->pci_enabled) { - pc_pci_device_init(pci_bus); - } - if (pcms->acpi_nvdimm_state.is_enabled) { nvdimm_init_acpi_state(&pcms->acpi_nvdimm_state, system_io, pcms->fw_cfg, OBJECT(pcms)); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index aba7541a82..0c0bc48137 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -273,9 +273,6 @@ static void pc_q35_init(MachineState *machine) /* the rest devices to which pci devfn is automatically assigned */ pc_vga_init(isa_bus, host_bus); pc_nic_init(isa_bus, host_bus); - if (pcmc->pci_enabled) { - pc_pci_device_init(host_bus); - } if (pcms->acpi_nvdimm_state.is_enabled) { nvdimm_init_acpi_state(&pcms->acpi_nvdimm_state, system_io, diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 191505df5b..f3d4c4d230 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -2277,5 +2277,5 @@ void lsi53c895a_create(PCIBus *bus) { LSIState *s = LSI53C895A(pci_create_simple(bus, -1, "lsi53c895a")); - scsi_bus_legacy_handle_cmdline(&s->bus, false); + scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index b7bafbed6e..1eaeffc830 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -271,7 +271,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, return SCSI_DEVICE(dev); } -void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated) +void scsi_bus_legacy_handle_cmdline(SCSIBus *bus) { Location loc; DriveInfo *dinfo; @@ -284,59 +284,12 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated) continue; } qemu_opts_loc_restore(dinfo->opts); - if (deprecated) { - /* Handling -drive not claimed by machine initialization */ - if (blk_get_attached_dev(blk_by_legacy_dinfo(dinfo))) { - continue; /* claimed */ - } - if (!dinfo->is_default) { - warn_report("bus=%d,unit=%d is deprecated with this" - " machine type", - bus->busnr, unit); - } - } scsi_bus_legacy_add_drive(bus, blk_by_legacy_dinfo(dinfo), unit, false, -1, false, NULL, &error_fatal); } loc_pop(&loc); } -static bool is_scsi_hba_with_legacy_magic(Object *obj) -{ - static const char *magic[] = { - "am53c974", "dc390", "esp", "lsi53c810", "lsi53c895a", - "megasas", "megasas-gen2", "mptsas1068", "spapr-vscsi", - "virtio-scsi-device", - NULL - }; - const char *typename = object_get_typename(obj); - int i; - - for (i = 0; magic[i]; i++) - if (!strcmp(typename, magic[i])) { - return true; - } - - return false; -} - -static int scsi_legacy_handle_cmdline_cb(Object *obj, void *opaque) -{ - SCSIBus *bus = (SCSIBus *)object_dynamic_cast(obj, TYPE_SCSI_BUS); - - if (bus && is_scsi_hba_with_legacy_magic(OBJECT(bus->qbus.parent))) { - scsi_bus_legacy_handle_cmdline(bus, true); - } - - return 0; -} - -void scsi_legacy_handle_cmdline(void) -{ - object_child_foreach_recursive(object_get_root(), - scsi_legacy_handle_cmdline_cb, NULL); -} - static int32_t scsi_invalid_field(SCSIRequest *req, uint8_t *buf) { scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD)); diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 360db53ac8..a9e49c7cb5 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -1215,8 +1215,7 @@ void spapr_vscsi_create(VIOsPAPRBus *bus) dev = qdev_create(&bus->bus, "spapr-vscsi"); qdev_init_nofail(dev); - scsi_bus_legacy_handle_cmdline(&VIO_SPAPR_VSCSI_DEVICE(dev)->bus, - false); + scsi_bus_legacy_handle_cmdline(&VIO_SPAPR_VSCSI_DEVICE(dev)->bus); } static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off) diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 802a647cdc..7ecaddac9d 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -153,7 +153,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, int unit, bool removable, int bootindex, bool share_rw, const char *serial, Error **errp); -void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated); +void scsi_bus_legacy_handle_cmdline(SCSIBus *bus); void scsi_legacy_handle_cmdline(void); SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, diff --git a/qemu-doc.texi b/qemu-doc.texi index 76ca83feae..fb6fac528a 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2680,11 +2680,6 @@ The ``-net vlan=NN'' argument is partially replaced with the new ``-netdev'' argument. The remaining use cases will no longer be directly supported in QEMU. -@subsection -drive if=scsi (since 2.9.0) - -The ``-drive if=scsi'' argument is replaced by the the -``-device BUS-TYPE'' argument combined with ``-drive if=none''. - @subsection -drive cyls=...,heads=...,secs=...,trans=... (since 2.10.0) The drive geometry arguments are replaced by the the geometry arguments diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index 0c3be16489..f617e25e24 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -157,9 +157,7 @@ case "$QEMU_DEFAULT_MACHINE" in pc) run_qemu -drive if=floppy run_qemu -drive if=ide,media=cdrom - run_qemu -drive if=scsi,media=cdrom run_qemu -drive if=ide - run_qemu -drive if=scsi ;; *) ;; @@ -188,9 +186,7 @@ case "$QEMU_DEFAULT_MACHINE" in pc) run_qemu -drive file="$TEST_IMG",if=floppy,readonly=on run_qemu -drive file="$TEST_IMG",if=ide,media=cdrom,readonly=on - run_qemu -drive file="$TEST_IMG",if=scsi,media=cdrom,readonly=on run_qemu -drive file="$TEST_IMG",if=ide,readonly=on - run_qemu -drive file="$TEST_IMG",if=scsi,readonly=on ;; *) ;; diff --git a/vl.c b/vl.c index a92f60c8b7..6e4f1a2de2 100644 --- a/vl.c +++ b/vl.c @@ -4621,15 +4621,6 @@ int main(int argc, char **argv, char **envp) rom_reset_order_override(); - /* - * Create frontends for -drive if=scsi leftovers. - * Normally, frontends for -drive get created by machine - * initialization for onboard SCSI HBAs. However, we create a few - * more ever since SCSI qdevification, but this is pretty much an - * implementation accident, and deprecated. - */ - scsi_legacy_handle_cmdline(); - /* Did we create any drives that we failed to create a device for? */ drive_check_orphaned(); From a342173ab78fd8b126f27a7a5dbfb097a32f0ed7 Mon Sep 17 00:00:00 2001 From: David Hildenbrand <david@redhat.com> Date: Fri, 9 Feb 2018 20:52:37 +0100 Subject: [PATCH 04/34] cpus: properly inititalize CPU > 1 under single-threaded TCG All but the first CPU are currently not fully inititalized (e.g. cpu->created is never set). Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20180209195239.16048-2-david@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- cpus.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpus.c b/cpus.c index 4f5f88edba..970390b8a9 100644 --- a/cpus.c +++ b/cpus.c @@ -1863,6 +1863,9 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) /* For non-MTTCG cases we share the thread */ cpu->thread = single_tcg_cpu_thread; cpu->halt_cond = single_tcg_halt_cond; + cpu->thread_id = first_cpu->thread_id; + cpu->can_do_io = 1; + cpu->created = true; } } From 81e963116882eed4ebf7cf3df5c2e1abaab3a288 Mon Sep 17 00:00:00 2001 From: David Hildenbrand <david@redhat.com> Date: Fri, 9 Feb 2018 20:52:38 +0100 Subject: [PATCH 05/34] cpus: wait for CPU creation at central place We can now also wait for the CPU creation for single-threaded TCG, so we can move the waiting bits further out. Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20180209195239.16048-3-david@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- cpus.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/cpus.c b/cpus.c index 970390b8a9..bcfc0a4bf4 100644 --- a/cpus.c +++ b/cpus.c @@ -1856,9 +1856,6 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) #ifdef _WIN32 cpu->hThread = qemu_thread_get_handle(cpu->thread); #endif - while (!cpu->created) { - qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); - } } else { /* For non-MTTCG cases we share the thread */ cpu->thread = single_tcg_cpu_thread; @@ -1884,9 +1881,6 @@ static void qemu_hax_start_vcpu(CPUState *cpu) #ifdef _WIN32 cpu->hThread = qemu_thread_get_handle(cpu->thread); #endif - while (!cpu->created) { - qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); - } } static void qemu_kvm_start_vcpu(CPUState *cpu) @@ -1900,9 +1894,6 @@ static void qemu_kvm_start_vcpu(CPUState *cpu) cpu->cpu_index); qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); - while (!cpu->created) { - qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); - } } static void qemu_hvf_start_vcpu(CPUState *cpu) @@ -1921,9 +1912,6 @@ static void qemu_hvf_start_vcpu(CPUState *cpu) cpu->cpu_index); qemu_thread_create(cpu->thread, thread_name, qemu_hvf_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); - while (!cpu->created) { - qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); - } } static void qemu_whpx_start_vcpu(CPUState *cpu) @@ -1940,9 +1928,6 @@ static void qemu_whpx_start_vcpu(CPUState *cpu) #ifdef _WIN32 cpu->hThread = qemu_thread_get_handle(cpu->thread); #endif - while (!cpu->created) { - qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); - } } static void qemu_dummy_start_vcpu(CPUState *cpu) @@ -1956,9 +1941,6 @@ static void qemu_dummy_start_vcpu(CPUState *cpu) cpu->cpu_index); qemu_thread_create(cpu->thread, thread_name, qemu_dummy_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); - while (!cpu->created) { - qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); - } } void qemu_init_vcpu(CPUState *cpu) @@ -1988,6 +1970,10 @@ void qemu_init_vcpu(CPUState *cpu) } else { qemu_dummy_start_vcpu(cpu); } + + while (!cpu->created) { + qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); + } } void cpu_stop_current(void) From 5a9c973b6cda88acb08d62a696a72d9e2be5807b Mon Sep 17 00:00:00 2001 From: David Hildenbrand <david@redhat.com> Date: Fri, 9 Feb 2018 20:52:39 +0100 Subject: [PATCH 06/34] cpus: CPU threads are always created initially for one CPU only It can never happen for single-threaded TCG that we have more than one CPU in the list, while the first one has not been marked as "created". Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20180209195239.16048-4-david@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- cpus.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cpus.c b/cpus.c index bcfc0a4bf4..9bcff7d63c 100644 --- a/cpus.c +++ b/cpus.c @@ -1383,11 +1383,9 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_mutex_lock_iothread(); qemu_thread_get_self(cpu->thread); - CPU_FOREACH(cpu) { - cpu->thread_id = qemu_get_thread_id(); - cpu->created = true; - cpu->can_do_io = 1; - } + cpu->thread_id = qemu_get_thread_id(); + cpu->created = true; + cpu->can_do_io = 1; qemu_cond_signal(&qemu_cpu_cond); /* wait for initial kick-off after machine start */ From f29d4450428fe07e9d6b0655cef2e59bfa0b2ea5 Mon Sep 17 00:00:00 2001 From: Thomas Huth <thuth@redhat.com> Date: Tue, 20 Feb 2018 16:01:32 +0100 Subject: [PATCH 07/34] Document --rtc-td-hack, --localtime and --startdate as deprecated These options have been marked in a comment in qemu-options.hx as deprecated in 2009 already (see commit 1ed2fc1fa35fadc0d6), but we never informed the users about these deprecations. Let's catch up on that omission now. Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <1519138892-12836-1-git-send-email-thuth@redhat.com> [Fix messages. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- qemu-doc.texi | 16 +++++++++++----- vl.c | 5 +++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/qemu-doc.texi b/qemu-doc.texi index fb6fac528a..589519a900 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2723,12 +2723,18 @@ filesystem test suite. Also it requires the CAP_DAC_READ_SEARCH capability, which is not the recommended way to run QEMU. This backend should not be used and it will be removed with no replacement. -@subsection -no-frame (since 2.12.0) +@subsection -rtc-td-hack (since 2.12.0) -The ``-no-frame'' argument works with SDL 1.2 only. SDL 2.0 lacks -support for frameless windows, and the other user interfaces never -implemented this in the first place. So this will be removed together -with SDL 1.2 support. +The @code{-rtc-td-hack} option has been replaced by +@code{-rtc driftfix=slew}. + +@subsection -localtime (since 2.12.0) + +The @code{-localtime} option has been replaced by @code{-rtc base=localtime}. + +@subsection -startdate (since 2.12.0) + +The @code{-startdate} option has been replaced by @code{-rtc base=@var{date}}. @section qemu-img command line arguments diff --git a/vl.c b/vl.c index 6e4f1a2de2..e648bed0e1 100644 --- a/vl.c +++ b/vl.c @@ -3406,6 +3406,8 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_localtime: rtc_utc = 0; + warn_report("This option is deprecated, " + "use '-rtc base=localtime' instead."); break; case QEMU_OPTION_vga: vga_model = optarg; @@ -3665,6 +3667,8 @@ int main(int argc, char **argv, char **envp) }; qdev_prop_register_global(&slew_lost_ticks); + warn_report("This option is deprecated, " + "use '-rtc driftfix=slew' instead."); break; } case QEMU_OPTION_acpitable: @@ -3866,6 +3870,7 @@ int main(int argc, char **argv, char **envp) */ break; case QEMU_OPTION_startdate: + warn_report("This option is deprecated, use '-rtc base=' instead."); configure_rtc_date_offset(optarg, 1); break; case QEMU_OPTION_rtc: From 35f63767dc77d85bebff6c6565aceaf74023776a Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy <aik@ozlabs.ru> Date: Fri, 2 Mar 2018 00:09:38 +1100 Subject: [PATCH 08/34] qmp: Merge ObjectPropertyInfo and DevicePropertyInfo ObjectPropertyInfo is more generic and only missing @description. This adds a description to ObjectPropertyInfo and removes DevicePropertyInfo so the resulting ObjectPropertyInfo can be used elsewhere. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Message-Id: <20180301130939.15875-2-aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- qapi/misc.json | 23 +++++------------------ qdev-monitor.c | 6 +++--- qmp.c | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/qapi/misc.json b/qapi/misc.json index a1702c9060..fb9f41d0ce 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1285,10 +1285,12 @@ # 3) A link type in the form 'link<subtype>' where subtype is a qdev # device type name. Link properties form the device model graph. # +# @description: if specified, the description of the property. +# # Since: 1.2 ## { 'struct': 'ObjectPropertyInfo', - 'data': { 'name': 'str', 'type': 'str' } } + 'data': { 'name': 'str', 'type': 'str', '*description': 'str' } } ## # @qom-list: @@ -1443,21 +1445,6 @@ 'data': { '*implements': 'str', '*abstract': 'bool' }, 'returns': [ 'ObjectTypeInfo' ] } -## -# @DevicePropertyInfo: -# -# Information about device properties. -# -# @name: the name of the property -# @type: the typename of the property -# @description: if specified, the description of the property. -# (since 2.2) -# -# Since: 1.2 -## -{ 'struct': 'DevicePropertyInfo', - 'data': { 'name': 'str', 'type': 'str', '*description': 'str' } } - ## # @device-list-properties: # @@ -1465,13 +1452,13 @@ # # @typename: the type name of a device # -# Returns: a list of DevicePropertyInfo describing a devices properties +# Returns: a list of ObjectPropertyInfo describing a devices properties # # Since: 1.2 ## { 'command': 'device-list-properties', 'data': { 'typename': 'str'}, - 'returns': [ 'DevicePropertyInfo' ] } + 'returns': [ 'ObjectPropertyInfo' ] } ## # @xen-set-global-dirty-log: diff --git a/qdev-monitor.c b/qdev-monitor.c index b8f6bc3f7e..b7e3291f8b 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -258,8 +258,8 @@ int qdev_device_help(QemuOpts *opts) { Error *local_err = NULL; const char *driver; - DevicePropertyInfoList *prop_list; - DevicePropertyInfoList *prop; + ObjectPropertyInfoList *prop_list; + ObjectPropertyInfoList *prop; driver = qemu_opt_get(opts, "driver"); if (driver && is_help_option(driver)) { @@ -295,7 +295,7 @@ int qdev_device_help(QemuOpts *opts) } } - qapi_free_DevicePropertyInfoList(prop_list); + qapi_free_ObjectPropertyInfoList(prop_list); return 1; error: diff --git a/qmp.c b/qmp.c index ba82e1df9f..66332c38d9 100644 --- a/qmp.c +++ b/qmp.c @@ -465,12 +465,12 @@ ObjectTypeInfoList *qmp_qom_list_types(bool has_implements, * * The caller must free the return value. */ -static DevicePropertyInfo *make_device_property_info(ObjectClass *klass, - const char *name, - const char *default_type, - const char *description) +static ObjectPropertyInfo *make_device_property_info(ObjectClass *klass, + const char *name, + const char *default_type, + const char *description) { - DevicePropertyInfo *info; + ObjectPropertyInfo *info; Property *prop; do { @@ -510,14 +510,14 @@ static DevicePropertyInfo *make_device_property_info(ObjectClass *klass, return info; } -DevicePropertyInfoList *qmp_device_list_properties(const char *typename, - Error **errp) +ObjectPropertyInfoList *qmp_device_list_properties(const char *typename, + Error **errp) { ObjectClass *klass; Object *obj; ObjectProperty *prop; ObjectPropertyIterator iter; - DevicePropertyInfoList *prop_list = NULL; + ObjectPropertyInfoList *prop_list = NULL; klass = object_class_by_name(typename); if (klass == NULL) { @@ -542,8 +542,8 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, object_property_iter_init(&iter, obj); while ((prop = object_property_iter_next(&iter))) { - DevicePropertyInfo *info; - DevicePropertyInfoList *entry; + ObjectPropertyInfo *info; + ObjectPropertyInfoList *entry; /* Skip Object and DeviceState properties */ if (strcmp(prop->name, "type") == 0 || From 961c47bb8bacc9ae21c0760fa6e2594156299dd7 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy <aik@ozlabs.ru> Date: Fri, 2 Mar 2018 00:09:39 +1100 Subject: [PATCH 09/34] qmp: Add qom-list-properties to list QOM object properties There is already 'device-list-properties' which does most of the job, however it does not handle everything returned by qom-list-types such as machines as they inherit directly from TYPE_OBJECT and not TYPE_DEVICE. It does not handle abstract classes either. This adds a new qom-list-properties command which prints properties of a specific class and its instance. It is pretty much a simplified copy of the device-list-properties handler. Since it creates an object instance, device properties should appear in the output as they are copied to QOM properties at the instance_init hook. This adds a object_class_property_iter_init() helper to allow class properties enumeration uses it in the new QMP command to allow properties listing for abstract classes. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Message-Id: <20180301130939.15875-3-aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- include/qom/object.h | 16 +++++++++++++++ qapi/misc.json | 15 ++++++++++++++ qmp.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ qom/object.c | 7 +++++++ 4 files changed, 87 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index 30db296af4..4f07090db0 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1016,6 +1016,22 @@ typedef struct ObjectPropertyIterator { void object_property_iter_init(ObjectPropertyIterator *iter, Object *obj); +/** + * object_class_property_iter_init: + * @klass: the class + * + * Initializes an iterator for traversing all properties + * registered against an object class and all parent classes. + * + * It is forbidden to modify the property list while iterating, + * whether removing or adding properties. + * + * This can be used on abstract classes as it does not create a temporary + * instance. + */ +void object_class_property_iter_init(ObjectPropertyIterator *iter, + ObjectClass *klass); + /** * object_property_iter_next: * @iter: the iterator instance diff --git a/qapi/misc.json b/qapi/misc.json index fb9f41d0ce..bd04469a4b 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1460,6 +1460,21 @@ 'data': { 'typename': 'str'}, 'returns': [ 'ObjectPropertyInfo' ] } +## +# @qom-list-properties: +# +# List properties associated with a QOM object. +# +# @typename: the type name of an object +# +# Returns: a list of ObjectPropertyInfo describing object properties +# +# Since: 2.12 +## +{ 'command': 'qom-list-properties', + 'data': { 'typename': 'str'}, + 'returns': [ 'ObjectPropertyInfo' ] } + ## # @xen-set-global-dirty-log: # diff --git a/qmp.c b/qmp.c index 66332c38d9..8c7d1cc479 100644 --- a/qmp.c +++ b/qmp.c @@ -578,6 +578,55 @@ ObjectPropertyInfoList *qmp_device_list_properties(const char *typename, return prop_list; } +ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename, + Error **errp) +{ + ObjectClass *klass; + Object *obj = NULL; + ObjectProperty *prop; + ObjectPropertyIterator iter; + ObjectPropertyInfoList *prop_list = NULL; + + klass = object_class_by_name(typename); + if (klass == NULL) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, + "Class '%s' not found", typename); + return NULL; + } + + klass = object_class_dynamic_cast(klass, TYPE_OBJECT); + if (klass == NULL) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_OBJECT); + return NULL; + } + + if (object_class_is_abstract(klass)) { + object_class_property_iter_init(&iter, klass); + } else { + obj = object_new(typename); + object_property_iter_init(&iter, obj); + } + while ((prop = object_property_iter_next(&iter))) { + ObjectPropertyInfo *info; + ObjectPropertyInfoList *entry; + + info = g_malloc0(sizeof(*info)); + info->name = g_strdup(prop->name); + info->type = g_strdup(prop->type); + info->has_description = !!prop->description; + info->description = g_strdup(prop->description); + + entry = g_malloc0(sizeof(*entry)); + entry->value = info; + entry->next = prop_list; + prop_list = entry; + } + + object_unref(obj); + + return prop_list; +} + CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) { return arch_query_cpu_definitions(errp); diff --git a/qom/object.c b/qom/object.c index f70a75c308..755ad03819 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1037,6 +1037,13 @@ ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter) return val; } +void object_class_property_iter_init(ObjectPropertyIterator *iter, + ObjectClass *klass) +{ + g_hash_table_iter_init(&iter->iter, klass->properties); + iter->nextclass = klass; +} + ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name, Error **errp) { From b9f44da2f2cdc1a1a1be5aed0c46bd7fcc69cf4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com> Date: Thu, 15 Feb 2018 22:25:47 +0100 Subject: [PATCH 10/34] build-sys: fix -fsanitize=address check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 218bb57dd79d6843e0592c30a82ea8c1fddc74a5, the -fsanitize=address check fails with: config-temp/qemu-conf.c:3:20: error: integer overflow in expression [-Werror=overflow] return INT32_MIN / -1; Interestingly, UBSAN check doesn't produce a compile time warning. Use a test that doesn't have compile time warnings, and make it specific to UBSAN check. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180215212552.26997-2-marcandre.lureau@redhat.com> Reviewed-by: Emilio G. Cota <cota@braap.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- configure | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/configure b/configure index 27d3f66bd5..7ff00f8e81 100755 --- a/configure +++ b/configure @@ -5316,25 +5316,27 @@ fi ########################################## # checks for sanitizers -# we could use a simple skeleton for flags checks, but this also -# detect the static linking issue of ubsan, see also: -# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285 -cat > $TMPC << EOF -#include <stdint.h> -int main(void) { - return INT32_MIN / -1; -} -EOF - have_asan=no have_ubsan=no have_asan_iface_h=no have_asan_iface_fiber=no if test "$sanitizers" = "yes" ; then + write_c_skeleton if compile_prog "$CPU_CFLAGS -Werror -fsanitize=address" ""; then have_asan=yes fi + + # we could use a simple skeleton for flags checks, but this also + # detect the static linking issue of ubsan, see also: + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285 + cat > $TMPC << EOF +#include <stdlib.h> +int main(void) { + void *tmp = malloc(10); + return *(int *)(tmp + 2); +} +EOF if compile_prog "$CPU_CFLAGS -Werror -fsanitize=undefined" ""; then have_ubsan=yes fi From 80818e9ecbc6f7463ea47d0aae8d4a43ea030304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com> Date: Thu, 15 Feb 2018 22:25:48 +0100 Subject: [PATCH 11/34] lockable: workaround GCC link issue with ASAN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current GCC has an optimization bug when compiling with ASAN. See also GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84307 Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180215212552.26997-3-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- include/qemu/lockable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h index b6ed6c89ec..84ea794bcf 100644 --- a/include/qemu/lockable.h +++ b/include/qemu/lockable.h @@ -28,7 +28,7 @@ struct QemuLockable { * to QEMU_MAKE_LOCKABLE. For optimized builds, we can rely on dead-code elimination * from the compiler, and give the errors already at link time. */ -#ifdef __OPTIMIZE__ +#if defined(__OPTIMIZE__) && !defined(__SANITIZE_ADDRESS__) void unknown_lock_type(void *); #else static inline void unknown_lock_type(void *unused) From 0fd76bc51b55d262147f976445c921b3ef9b75e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com> Date: Thu, 15 Feb 2018 22:25:51 +0100 Subject: [PATCH 12/34] ahci-test: fix opts leak of skip tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following ASAN report: Direct leak of 128 byte(s) in 8 object(s) allocated from: #0 0x7fefce311850 in malloc (/lib64/libasan.so.4+0xde850) #1 0x7fefcdd5ef0c in g_malloc ../glib/gmem.c:94 #2 0x559b976faff0 in create_ahci_io_test /home/elmarco/src/qemu/tests/ahci-test.c:1810 Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180215212552.26997-6-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- tests/ahci-test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ahci-test.c b/tests/ahci-test.c index 2342fe3099..fb3cd84d07 100644 --- a/tests/ahci-test.c +++ b/tests/ahci-test.c @@ -1823,6 +1823,7 @@ static void create_ahci_io_test(enum IOMode type, enum AddrMode addr, if ((addr == ADDR_MODE_LBA48) && (offset == OFFSET_HIGH) && (mb_to_sectors(test_image_size_mb) <= 0xFFFFFFF)) { g_test_message("%s: skipped; test image too small", name); + g_free(opts); g_free(name); return; } From 26b97f2664a06f637b0a52b259723195683f2525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com> Date: Thu, 15 Feb 2018 22:25:52 +0100 Subject: [PATCH 13/34] sdhci-test: fix leaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following ASAN reports: ==20125==ERROR: LeakSanitizer: detected memory leaks Direct leak of 24 byte(s) in 1 object(s) allocated from: #0 0x7f0faea03a38 in __interceptor_calloc (/lib64/libasan.so.4+0xdea38) #1 0x7f0fae450f75 in g_malloc0 ../glib/gmem.c:124 #2 0x562fffd526fc in machine_start /home/elmarco/src/qemu/tests/sdhci-test.c:180 Indirect leak of 152 byte(s) in 1 object(s) allocated from: #0 0x7f0faea03850 in malloc (/lib64/libasan.so.4+0xde850) #1 0x7f0fae450f0c in g_malloc ../glib/gmem.c:94 #2 0x562fffd5d21d in qpci_init_pc /home/elmarco/src/qemu/tests/libqos/pci-pc.c:122 Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180215212552.26997-7-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- tests/sdhci-test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/sdhci-test.c b/tests/sdhci-test.c index 6b3a5328e0..1d825eb010 100644 --- a/tests/sdhci-test.c +++ b/tests/sdhci-test.c @@ -209,8 +209,10 @@ static QSDHCI *machine_start(const struct sdhci_t *test) static void machine_stop(QSDHCI *s) { + qpci_free_pc(s->pci.bus); g_free(s->pci.dev); qtest_quit(global_qtest); + g_free(s); } static void test_machine(const void *data) From 8b2ec54ff39c319dcb12e430d9e69d081395b964 Mon Sep 17 00:00:00 2001 From: Peter Xu <peterx@redhat.com> Date: Thu, 1 Mar 2018 16:44:24 +0800 Subject: [PATCH 14/34] chardev: fix leak in tcp_chr_telnet_init_io() Need to free TCPChardevTelnetInit when session established. Since at it, switch to use G_SOURCE_* macros. Reviewed-by: Daniel P. Berrange <berrange@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20180301084438.13594-2-peterx@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- chardev/char-socket.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 22f65971a1..8401aaed1a 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -592,19 +592,23 @@ static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc, ret = 0; } else { tcp_chr_disconnect(init->chr); - return FALSE; + goto end; } } init->buflen -= ret; if (init->buflen == 0) { tcp_chr_connect(init->chr); - return FALSE; + goto end; } memmove(init->buf, init->buf + ret, init->buflen); - return TRUE; + return G_SOURCE_CONTINUE; + +end: + g_free(init); + return G_SOURCE_REMOVE; } static void tcp_chr_telnet_init(Chardev *chr) From 80d2b933f9fe3e53d4f76a45a1bc1a0175669468 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Mon, 5 Mar 2018 09:18:26 +0100 Subject: [PATCH 15/34] openpic_kvm: drop address_space_to_flatview call The MemoryListener is registered on address_space_memory, there is not much to assert. This currently works because the callback is invoked only once when the listener is registered, but section->fv is the _new_ FlatView, not the old one on later calls and that would break. This confines address_space_to_flatview to exec.c and memory.c. Acked-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- hw/intc/openpic_kvm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c index f1a59e5a85..928bc04a4e 100644 --- a/hw/intc/openpic_kvm.c +++ b/hw/intc/openpic_kvm.c @@ -125,10 +125,6 @@ static void kvm_openpic_region_add(MemoryListener *listener, uint64_t reg_base; int ret; - if (section->fv != address_space_to_flatview(&address_space_memory)) { - abort(); - } - /* Ignore events on regions that are not us */ if (section->mr != &opp->mem) { return; From 785a507ec78bbda1c346f3d3593e5a58b62e73ef Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Mon, 5 Mar 2018 00:31:20 +0100 Subject: [PATCH 16/34] memory: inline some performance-sensitive accessors These accessors are called from inlined functions, and the call sequence is much more expensive than just inlining the access. Move the struct declaration to memory-internal.h so that exec.c and memory.c can both use an inline function. Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- include/exec/memory-internal.h | 13 +++++++++---- include/exec/memory.h | 22 +++++++++++++++++++++- memory.c | 30 ------------------------------ 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 4162474fd5..6a5ee42d36 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -21,7 +21,15 @@ #define MEMORY_INTERNAL_H #ifndef CONFIG_USER_ONLY -typedef struct AddressSpaceDispatch AddressSpaceDispatch; +static inline AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv) +{ + return fv->dispatch; +} + +static inline AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as) +{ + return flatview_to_dispatch(address_space_to_flatview(as)); +} extern const MemoryRegionOps unassigned_mem_ops; @@ -31,9 +39,6 @@ bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section); AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv); void address_space_dispatch_compact(AddressSpaceDispatch *d); - -AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as); -AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv); void address_space_dispatch_free(AddressSpaceDispatch *d); void mtree_print_dispatch(fprintf_function mon, void *f, diff --git a/include/exec/memory.h b/include/exec/memory.h index 15e81113ba..4b65b566cb 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -326,7 +326,27 @@ struct AddressSpace { QTAILQ_ENTRY(AddressSpace) address_spaces_link; }; -FlatView *address_space_to_flatview(AddressSpace *as); +typedef struct AddressSpaceDispatch AddressSpaceDispatch; +typedef struct FlatRange FlatRange; + +/* Flattened global view of current active memory hierarchy. Kept in sorted + * order. + */ +struct FlatView { + struct rcu_head rcu; + unsigned ref; + FlatRange *ranges; + unsigned nr; + unsigned nr_allocated; + struct AddressSpaceDispatch *dispatch; + MemoryRegion *root; +}; + +static inline FlatView *address_space_to_flatview(AddressSpace *as) +{ + return atomic_rcu_read(&as->current_map); +} + /** * MemoryRegionSection: describes a fragment of a #MemoryRegion diff --git a/memory.c b/memory.c index 6515131ac2..e70b64b8b9 100644 --- a/memory.c +++ b/memory.c @@ -210,8 +210,6 @@ static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a, && !memory_region_ioeventfd_before(b, a); } -typedef struct FlatRange FlatRange; - /* Range of memory in the global map. Addresses are absolute. */ struct FlatRange { MemoryRegion *mr; @@ -222,19 +220,6 @@ struct FlatRange { bool readonly; }; -/* Flattened global view of current active memory hierarchy. Kept in sorted - * order. - */ -struct FlatView { - struct rcu_head rcu; - unsigned ref; - FlatRange *ranges; - unsigned nr; - unsigned nr_allocated; - struct AddressSpaceDispatch *dispatch; - MemoryRegion *root; -}; - typedef struct AddressSpaceOps AddressSpaceOps; #define FOR_EACH_FLAT_RANGE(var, view) \ @@ -322,21 +307,6 @@ static void flatview_unref(FlatView *view) } } -FlatView *address_space_to_flatview(AddressSpace *as) -{ - return atomic_rcu_read(&as->current_map); -} - -AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv) -{ - return fv->dispatch; -} - -AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as) -{ - return flatview_to_dispatch(address_space_to_flatview(as)); -} - static bool can_merge(FlatRange *r1, FlatRange *r2) { return int128_eq(addrrange_end(r1->addr), r2->addr.start) From 4c6ebbb364aa6f42c5d8e83e932e967eb83f0e44 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Mon, 5 Mar 2018 09:23:56 +0100 Subject: [PATCH 17/34] address_space_write: address_space_to_flatview needs RCU lock address_space_write is calling address_space_to_flatview but it can be called outside the RCU lock. To fix it, push the rcu_read_lock/unlock pair up from flatview_write to address_space_write. Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- exec.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/exec.c b/exec.c index 4d8addb263..ec91162177 100644 --- a/exec.c +++ b/exec.c @@ -3078,6 +3078,7 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, return result; } +/* Called from RCU critical section. */ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, const uint8_t *buf, int len) { @@ -3086,25 +3087,14 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, MemoryRegion *mr; MemTxResult result = MEMTX_OK; - if (len > 0) { - rcu_read_lock(); - l = len; - mr = flatview_translate(fv, addr, &addr1, &l, true); - result = flatview_write_continue(fv, addr, attrs, buf, len, - addr1, l, mr); - rcu_read_unlock(); - } + l = len; + mr = flatview_translate(fv, addr, &addr1, &l, true); + result = flatview_write_continue(fv, addr, attrs, buf, len, + addr1, l, mr); return result; } -MemTxResult address_space_write(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, - const uint8_t *buf, int len) -{ - return flatview_write(address_space_to_flatview(as), addr, attrs, buf, len); -} - /* Called within RCU critical section. */ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, MemTxAttrs attrs, uint8_t *buf, @@ -3213,6 +3203,23 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, addr, attrs, buf, len, is_write); } +MemTxResult address_space_write(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs, + const uint8_t *buf, int len) +{ + MemTxResult result = MEMTX_OK; + FlatView *fv; + + if (len > 0) { + rcu_read_lock(); + fv = address_space_to_flatview(as); + result = flatview_write(fv, addr, attrs, buf, len); + rcu_read_unlock(); + } + + return result; +} + void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf, int len, int is_write) { From b2a44fcad74f1cc7a6786d38eba7db12ab2352ba Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Mon, 5 Mar 2018 00:19:49 +0100 Subject: [PATCH 18/34] address_space_read: address_space_to_flatview needs RCU lock address_space_read is calling address_space_to_flatview but it can be called outside the RCU lock. To fix it, push the rcu_read_lock/unlock pair up from flatview_read_full to address_space_read's constant size fast path and address_space_read_full. Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- exec.c | 38 +++++++++++++++++++++++++------------- include/exec/memory.h | 25 ++++++++++--------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/exec.c b/exec.c index ec91162177..e4552ee228 100644 --- a/exec.c +++ b/exec.c @@ -2616,6 +2616,8 @@ static const MemoryRegionOps watch_mem_ops = { }, }; +static MemTxResult flatview_read(FlatView *fv, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, int len); static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, const uint8_t *buf, int len); static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len, @@ -3165,24 +3167,18 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, return result; } -MemTxResult flatview_read_full(FlatView *fv, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, int len) +/* Called from RCU critical section. */ +static MemTxResult flatview_read(FlatView *fv, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, int len) { hwaddr l; hwaddr addr1; MemoryRegion *mr; - MemTxResult result = MEMTX_OK; - if (len > 0) { - rcu_read_lock(); - l = len; - mr = flatview_translate(fv, addr, &addr1, &l, false); - result = flatview_read_continue(fv, addr, attrs, buf, len, - addr1, l, mr); - rcu_read_unlock(); - } - - return result; + l = len; + mr = flatview_translate(fv, addr, &addr1, &l, false); + return flatview_read_continue(fv, addr, attrs, buf, len, + addr1, l, mr); } static MemTxResult flatview_rw(FlatView *fv, hwaddr addr, MemTxAttrs attrs, @@ -3203,6 +3199,22 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, addr, attrs, buf, len, is_write); } +MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, int len) +{ + MemTxResult result = MEMTX_OK; + FlatView *fv; + + if (len > 0) { + rcu_read_lock(); + fv = address_space_to_flatview(as); + result = flatview_read(fv, addr, attrs, buf, len); + rcu_read_unlock(); + } + + return result; +} + MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, const uint8_t *buf, int len) diff --git a/include/exec/memory.h b/include/exec/memory.h index 4b65b566cb..31eae0a640 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1917,13 +1917,12 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, /* Internal functions, part of the implementation of address_space_read. */ +MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, int len); MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, MemTxAttrs attrs, uint8_t *buf, int len, hwaddr addr1, hwaddr l, MemoryRegion *mr); - -MemTxResult flatview_read_full(FlatView *fv, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, int len); void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr); static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) @@ -1942,25 +1941,28 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) * * Return a MemTxResult indicating whether the operation succeeded * or failed (eg unassigned memory, device rejected the transaction, - * IOMMU fault). + * IOMMU fault). Called within RCU critical section. * - * @fv: #FlatView to be accessed + * @as: #AddressSpace to be accessed * @addr: address within that address space * @attrs: memory transaction attributes * @buf: buffer with the data transferred */ static inline __attribute__((__always_inline__)) -MemTxResult flatview_read(FlatView *fv, hwaddr addr, MemTxAttrs attrs, - uint8_t *buf, int len) +MemTxResult address_space_read(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs, uint8_t *buf, + int len) { MemTxResult result = MEMTX_OK; hwaddr l, addr1; void *ptr; MemoryRegion *mr; + FlatView *fv; if (__builtin_constant_p(len)) { if (len) { rcu_read_lock(); + fv = address_space_to_flatview(as); l = len; mr = flatview_translate(fv, addr, &addr1, &l, false); if (len == l && memory_access_is_direct(mr, false)) { @@ -1973,18 +1975,11 @@ MemTxResult flatview_read(FlatView *fv, hwaddr addr, MemTxAttrs attrs, rcu_read_unlock(); } } else { - result = flatview_read_full(fv, addr, attrs, buf, len); + result = address_space_read_full(as, addr, attrs, buf, len); } return result; } -static inline MemTxResult address_space_read(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, - int len) -{ - return flatview_read(address_space_to_flatview(as), addr, attrs, buf, len); -} - /** * address_space_read_cached: read from a cached RAM region * From 11e732a5ed46903f997985bed4c3767ca28a7eb6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Mon, 5 Mar 2018 00:23:26 +0100 Subject: [PATCH 19/34] address_space_access_valid: address_space_to_flatview needs RCU lock address_space_access_valid is calling address_space_to_flatview but it can be called outside the RCU lock. To fix it, push the rcu_read_lock/unlock pair up from flatview_access_valid to address_space_access_valid. Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- exec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index e4552ee228..62ed49ddd5 100644 --- a/exec.c +++ b/exec.c @@ -3395,7 +3395,6 @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len, MemoryRegion *mr; hwaddr l, xlat; - rcu_read_lock(); while (len > 0) { l = len; mr = flatview_translate(fv, addr, &xlat, &l, is_write); @@ -3410,15 +3409,20 @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len, len -= l; addr += l; } - rcu_read_unlock(); return true; } bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write) { - return flatview_access_valid(address_space_to_flatview(as), - addr, len, is_write); + FlatView *fv; + bool result; + + rcu_read_lock(); + fv = address_space_to_flatview(as); + result = flatview_access_valid(fv, addr, len, is_write); + rcu_read_unlock(); + return result; } static hwaddr From ad0c60fa572d4050255b698ecdb67294dd4c0125 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Mon, 5 Mar 2018 00:23:26 +0100 Subject: [PATCH 20/34] address_space_map: address_space_to_flatview needs RCU lock address_space_map is calling address_space_to_flatview but it can be called outside the RCU lock. The function itself is calling rcu_read_lock/rcu_read_unlock, just in the wrong place, so the fix is easy. Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- exec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exec.c b/exec.c index 62ed49ddd5..bffb959a1f 100644 --- a/exec.c +++ b/exec.c @@ -3468,7 +3468,7 @@ void *address_space_map(AddressSpace *as, hwaddr l, xlat; MemoryRegion *mr; void *ptr; - FlatView *fv = address_space_to_flatview(as); + FlatView *fv; if (len == 0) { return NULL; @@ -3476,6 +3476,7 @@ void *address_space_map(AddressSpace *as, l = len; rcu_read_lock(); + fv = address_space_to_flatview(as); mr = flatview_translate(fv, addr, &xlat, &l, is_write); if (!memory_access_is_direct(mr, is_write)) { From db84fd973eba3f1e121416dcab73a4e8a60f2526 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Mon, 5 Mar 2018 09:29:04 +0100 Subject: [PATCH 21/34] address_space_rw: address_space_to_flatview needs RCU lock address_space_rw is calling address_space_to_flatview but it can be called outside the RCU lock. To fix it, transform flatview_rw into address_space_rw, since flatview_rw is otherwise unused. Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- exec.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/exec.c b/exec.c index bffb959a1f..604f03c535 100644 --- a/exec.c +++ b/exec.c @@ -3181,24 +3181,6 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr, addr1, l, mr); } -static MemTxResult flatview_rw(FlatView *fv, hwaddr addr, MemTxAttrs attrs, - uint8_t *buf, int len, bool is_write) -{ - if (is_write) { - return flatview_write(fv, addr, attrs, (uint8_t *)buf, len); - } else { - return flatview_read(fv, addr, attrs, (uint8_t *)buf, len); - } -} - -MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, - int len, bool is_write) -{ - return flatview_rw(address_space_to_flatview(as), - addr, attrs, buf, len, is_write); -} - MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, uint8_t *buf, int len) { @@ -3232,6 +3214,16 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, return result; } +MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, + uint8_t *buf, int len, bool is_write) +{ + if (is_write) { + return address_space_write(as, addr, attrs, buf, len); + } else { + return address_space_read_full(as, addr, attrs, buf, len); + } +} + void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf, int len, int is_write) { From fb8446d94ec7a3dc0c3a7e7da672406476f075ac Mon Sep 17 00:00:00 2001 From: Julia Suvorova <jusual@mail.ru> Date: Fri, 2 Mar 2018 13:43:19 +0300 Subject: [PATCH 22/34] checkpatch: add a warning for basename/dirname g_path_get_* do the same as g_strdup(basename/dirname(...)) but without modifying the argument. Signed-off-by: Julia Suvorova <jusual@mail.ru> Message-Id: <1519987399-19160-1-git-send-email-jusual@mail.ru> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 1b4b812e28..a88af61ed4 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2584,6 +2584,11 @@ sub process { ERROR("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); } +# recommend g_path_get_* over g_strdup(basename/dirname(...)) + if ($line =~ /\bg_strdup\s*\(\s*(basename|dirname)\s*\(/) { + WARN("consider using g_path_get_$1() in preference to g_strdup($1())\n" . $herecurr); + } + # recommend qemu_strto* over strto* for numeric conversions if ($line =~ /\b(strto[^kd].*?)\s*\(/) { ERROR("consider using qemu_$1 in preference to $1\n" . $herecurr); From 2b9aef6fcd96ba7ed8c1ee723e391901852d344c Mon Sep 17 00:00:00 2001 From: Su Hang <suhang16@mails.ucas.ac.cn> Date: Tue, 6 Mar 2018 15:04:50 +0800 Subject: [PATCH 23/34] checkpatch: add check for `while` and `for` Adding check for `while` and `for` statements, which condition has more than one line. The former checkpatch.pl can check `if` statement, which condition has more than one line, whether block misses brace round, like this: ''' if (cond1 || cond2) statement; ''' But it doesn't do the same check for `for` and `while` statements. Using `(?:...)` instead of `(...)` in regex pattern catch. Because `(?:...)` is faster and avoids unwanted side-effect. Suggested-by: Stefan Hajnoczi <stefanha@redhat.com> Suggested-by: Eric Blake <eblake@redhat.com> Suggested-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Su Hang <suhang16@mails.ucas.ac.cn> Message-Id: <1520319890-19761-1-git-send-email-suhang16@mails.ucas.ac.cn> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- scripts/checkpatch.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index a88af61ed4..d1fe79bcc4 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2352,8 +2352,9 @@ sub process { } } -# check for missing bracing round if etc - if ($line =~ /(^.*)\bif\b/ && $line !~ /\#\s*if/) { +# check for missing bracing around if etc + if ($line =~ /(^.*)\b(?:if|while|for)\b/ && + $line !~ /\#\s*if/) { my ($level, $endln, @chunks) = ctx_statement_full($linenr, $realcnt, 1); if ($dbg_adv_apw) { From 48e56d503e18bd1e8a75463fd7cc1580bf7e7650 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Tue, 6 Mar 2018 11:32:44 +0100 Subject: [PATCH 24/34] Revert "build-sys: compile with -Og or -O1 when --enable-debug" This reverts commit 906548689e37ab6cca1e93b3f8d9327a4e17e8af. Even with -Og, the debug experience is noticeably worse because gdb shows a lot more "<optimised out>" variables and function arguments. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- configure | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/configure b/configure index 7ff00f8e81..ebbda236bb 100755 --- a/configure +++ b/configure @@ -5368,19 +5368,8 @@ if test "$gcov" = "yes" ; then LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS" elif test "$fortify_source" = "yes" ; then CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS" -elif test "$debug" = "yes"; then - if compile_prog "-Og" ""; then - CFLAGS="-Og $CFLAGS" - elif compile_prog "-O1" ""; then - CFLAGS="-O1 $CFLAGS" - fi - # Workaround GCC false-positive Wuninitialized bugs with Og or O1: - # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639 - if cc_has_warning_flag "-Wno-maybe-uninitialized"; then - CFLAGS="-Wno-maybe-uninitialized $CFLAGS" - fi -else - CFLAGS="-O2 $CFLAGS" +elif test "$debug" = "no"; then + CFLAGS="-O2 $CFLAGS" fi if test "$have_asan" = "yes"; then From 53537bb18ca68471a1c738eed93cce646fd97194 Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM) via Qemu-devel" <qemu-devel@nongnu.org> Date: Mon, 26 Feb 2018 09:13:29 -0800 Subject: [PATCH 25/34] Fixing WHPX casing to match SDK Fixes an issue where the SDK that was releases had a different casing for the *.h and *.lib files causing a build break if linked directly from Windows Kits. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com> Message-Id: <1519665216-1078-2-git-send-email-juterry@microsoft.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> --- configure | 10 +++++----- target/i386/whpx-all.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/configure b/configure index ebbda236bb..6f3921c02a 100755 --- a/configure +++ b/configure @@ -2486,20 +2486,20 @@ fi if test "$whpx" != "no" ; then cat > $TMPC << EOF #include <windows.h> -#include <winhvplatform.h> -#include <winhvemulation.h> +#include <WinHvPlatform.h> +#include <WinHvEmulation.h> int main(void) { WHV_CAPABILITY whpx_cap; WHvGetCapability(WHvCapabilityCodeFeatures, &whpx_cap, sizeof(whpx_cap)); return 0; } EOF - if compile_prog "" "-lwinhvplatform -lwinhvemulation" ; then - libs_softmmu="$libs_softmmu -lwinhvplatform -lwinhvemulation" + if compile_prog "" "-lWinHvPlatform -lWinHvEmulation" ; then + libs_softmmu="$libs_softmmu -lWinHvPlatform -lWinHvEmulation" whpx="yes" else if test "$whpx" = "yes"; then - feature_not_found "winhvplatform" "winhvemulation is not installed" + feature_not_found "WinHvPlatform" "WinHvEmulation is not installed" fi whpx="no" fi diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 0015b27509..eeee43e187 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -26,8 +26,8 @@ #include "qapi/error.h" #include "migration/blocker.h" -#include <winhvplatform.h> -#include <winhvemulation.h> +#include <WinHvPlatform.h> +#include <WinHvEmulation.h> struct whpx_state { uint64_t mem_quota; From 914e2ab364c9b2b593a1a83ad08a81d494f7629d Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM) via Qemu-devel" <qemu-devel@nongnu.org> Date: Mon, 26 Feb 2018 09:13:30 -0800 Subject: [PATCH 26/34] Resolves WHPX breaking changes in SDK 17095 1. Fixes the changes required to the WHvTryMmioEmulation, WHvTryIoEmulation, and WHvEmulatorCreateEmulator based on the new VpContext forwarding. 2. Removes the WHvRunVpExitReasonAlerted case. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com> Message-Id: <1519665216-1078-3-git-send-email-juterry@microsoft.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> --- target/i386/whpx-all.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index eeee43e187..969c2f5f93 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -613,6 +613,7 @@ static HRESULT CALLBACK whpx_emu_translate_callback( } static const WHV_EMULATOR_CALLBACKS whpx_emu_callbacks = { + .Size = sizeof(WHV_EMULATOR_CALLBACKS), .WHvEmulatorIoPortCallback = whpx_emu_ioport_callback, .WHvEmulatorMemoryCallback = whpx_emu_memio_callback, .WHvEmulatorGetVirtualProcessorRegisters = whpx_emu_getreg_callback, @@ -626,7 +627,9 @@ static int whpx_handle_mmio(CPUState *cpu, WHV_MEMORY_ACCESS_CONTEXT *ctx) struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu); WHV_EMULATOR_STATUS emu_status; - hr = WHvEmulatorTryMmioEmulation(vcpu->emulator, cpu, ctx, &emu_status); + hr = WHvEmulatorTryMmioEmulation(vcpu->emulator, cpu, + &vcpu->exit_ctx.VpContext, ctx, + &emu_status); if (FAILED(hr)) { __debugbreak(); error_report("WHPX: Failed to parse MMIO access, hr=%08lx", hr); @@ -649,7 +652,9 @@ static int whpx_handle_portio(CPUState *cpu, struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu); WHV_EMULATOR_STATUS emu_status; - hr = WHvEmulatorTryIoEmulation(vcpu->emulator, cpu, ctx, &emu_status); + hr = WHvEmulatorTryIoEmulation(vcpu->emulator, cpu, + &vcpu->exit_ctx.VpContext, ctx, + &emu_status); if (FAILED(hr)) { __debugbreak(); error_report("WHPX: Failed to parse PortIO access, hr=%08lx", hr); @@ -905,18 +910,8 @@ static int whpx_vcpu_run(CPUState *cpu) whpx_vcpu_kick(cpu); } - for (;;) { - hr = WHvRunVirtualProcessor(whpx->partition, cpu->cpu_index, - &vcpu->exit_ctx, whpx->exit_ctx_size); - - if (SUCCEEDED(hr) && (vcpu->exit_ctx.ExitReason == - WHvRunVpExitReasonAlerted)) { - WHvCancelRunVirtualProcessor(whpx->partition, cpu->cpu_index, - 0); - } else { - break; - } - } + hr = WHvRunVirtualProcessor(whpx->partition, cpu->cpu_index, + &vcpu->exit_ctx, whpx->exit_ctx_size); if (FAILED(hr)) { error_report("WHPX: Failed to exec a virtual processor," @@ -956,7 +951,6 @@ static int whpx_vcpu_run(CPUState *cpu) case WHvRunVpExitReasonX64MsrAccess: case WHvRunVpExitReasonX64Cpuid: case WHvRunVpExitReasonException: - case WHvRunVpExitReasonAlerted: default: error_report("WHPX: Unexpected VP exit code %d", vcpu->exit_ctx.ExitReason); @@ -1068,7 +1062,7 @@ int whpx_init_vcpu(CPUState *cpu) return -ENOMEM; } - hr = WHvEmulatorCreateEmulator(whpx_emu_callbacks, &vcpu->emulator); + hr = WHvEmulatorCreateEmulator(&whpx_emu_callbacks, &vcpu->emulator); if (FAILED(hr)) { error_report("WHPX: Failed to setup instruction completion support," " hr=%08lx", hr); From 0ab2e74d792ece3e957b414cbe27e32f14f23a14 Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM) via Qemu-devel" <qemu-devel@nongnu.org> Date: Mon, 26 Feb 2018 09:13:31 -0800 Subject: [PATCH 27/34] Remove unnecessary WHPX __debugbreak(); Minor code cleanup. The calls to __debugbreak() are not required and should no longer be used to prevent unnecessary breaks. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com> Message-Id: <1519665216-1078-4-git-send-email-juterry@microsoft.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> --- target/i386/whpx-all.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 969c2f5f93..14ea732ec6 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -364,7 +364,6 @@ static void whpx_set_registers(CPUState *cpu) if (FAILED(hr)) { error_report("WHPX: Failed to set virtual processor context, hr=%08lx", hr); - __debugbreak(); } return; @@ -391,7 +390,6 @@ static void whpx_get_registers(CPUState *cpu) if (FAILED(hr)) { error_report("WHPX: Failed to get virtual processor context, hr=%08lx", hr); - __debugbreak(); } /* Indexes for first 16 registers match between HV and QEMU definitions */ @@ -554,7 +552,6 @@ static HRESULT CALLBACK whpx_emu_getreg_callback( if (FAILED(hr)) { error_report("WHPX: Failed to get virtual processor registers," " hr=%08lx", hr); - __debugbreak(); } return hr; @@ -576,7 +573,6 @@ static HRESULT CALLBACK whpx_emu_setreg_callback( if (FAILED(hr)) { error_report("WHPX: Failed to set virtual processor registers," " hr=%08lx", hr); - __debugbreak(); } /* @@ -604,7 +600,6 @@ static HRESULT CALLBACK whpx_emu_translate_callback( Gva, TranslateFlags, &res, Gpa); if (FAILED(hr)) { error_report("WHPX: Failed to translate GVA, hr=%08lx", hr); - __debugbreak(); } else { *TranslationResult = res.ResultCode; } @@ -631,13 +626,11 @@ static int whpx_handle_mmio(CPUState *cpu, WHV_MEMORY_ACCESS_CONTEXT *ctx) &vcpu->exit_ctx.VpContext, ctx, &emu_status); if (FAILED(hr)) { - __debugbreak(); error_report("WHPX: Failed to parse MMIO access, hr=%08lx", hr); return -1; } if (!emu_status.EmulationSuccessful) { - __debugbreak(); error_report("WHPX: Failed to emulate MMIO access"); return -1; } @@ -656,13 +649,11 @@ static int whpx_handle_portio(CPUState *cpu, &vcpu->exit_ctx.VpContext, ctx, &emu_status); if (FAILED(hr)) { - __debugbreak(); error_report("WHPX: Failed to parse PortIO access, hr=%08lx", hr); return -1; } if (!emu_status.EmulationSuccessful) { - __debugbreak(); error_report("WHPX: Failed to emulate PortMMIO access"); return -1; } @@ -716,7 +707,6 @@ static void whpx_vcpu_pre_run(CPUState *cpu) if (cpu->interrupt_request & CPU_INTERRUPT_SMI) { qemu_mutex_lock_iothread(); cpu->interrupt_request &= ~CPU_INTERRUPT_SMI; - __debugbreak(); qemu_mutex_unlock_iothread(); } } @@ -785,7 +775,6 @@ static void whpx_vcpu_pre_run(CPUState *cpu) if (FAILED(hr)) { error_report("WHPX: Failed to set interrupt state registers," " hr=%08lx", hr); - __debugbreak(); } } @@ -812,7 +801,6 @@ static void whpx_vcpu_post_run(CPUState *cpu) if (FAILED(hr)) { error_report("WHPX: Failed to get interrupt state regusters," " hr=%08lx", hr); - __debugbreak(); vcpu->interruptable = false; return; } From b27350e1b992eca3fa4b3fea4065b1b3897ec57f Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM) via Qemu-devel" <qemu-devel@nongnu.org> Date: Mon, 26 Feb 2018 09:13:32 -0800 Subject: [PATCH 28/34] Fix WHPX additional lock acquisition The code already is holding the qemu_mutex for the IO thread. We do not need to additionally take the lock again in this case. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com> Message-Id: <1519665216-1078-5-git-send-email-juterry@microsoft.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> --- target/i386/whpx-all.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 14ea732ec6..74a8f4d599 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -705,9 +705,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu) new_int.InterruptionVector = 2; } if (cpu->interrupt_request & CPU_INTERRUPT_SMI) { - qemu_mutex_lock_iothread(); cpu->interrupt_request &= ~CPU_INTERRUPT_SMI; - qemu_mutex_unlock_iothread(); } } From f875f04c2c322357e2e3fbd90ce5613b5be403a9 Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM) via Qemu-devel" <qemu-devel@nongnu.org> Date: Mon, 26 Feb 2018 09:13:33 -0800 Subject: [PATCH 29/34] Fix WHPX typo in 'mmio' Renames the usage of 'memio' to 'mmio' in the emulator callbacks. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com> Message-Id: <1519665216-1078-6-git-send-email-juterry@microsoft.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> --- target/i386/whpx-all.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 74a8f4d599..7e58d5f68c 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -527,7 +527,7 @@ static HRESULT CALLBACK whpx_emu_ioport_callback( return S_OK; } -static HRESULT CALLBACK whpx_emu_memio_callback( +static HRESULT CALLBACK whpx_emu_mmio_callback( void *ctx, WHV_EMULATOR_MEMORY_ACCESS_INFO *ma) { @@ -610,7 +610,7 @@ static HRESULT CALLBACK whpx_emu_translate_callback( static const WHV_EMULATOR_CALLBACKS whpx_emu_callbacks = { .Size = sizeof(WHV_EMULATOR_CALLBACKS), .WHvEmulatorIoPortCallback = whpx_emu_ioport_callback, - .WHvEmulatorMemoryCallback = whpx_emu_memio_callback, + .WHvEmulatorMemoryCallback = whpx_emu_mmio_callback, .WHvEmulatorGetVirtualProcessorRegisters = whpx_emu_getreg_callback, .WHvEmulatorSetVirtualProcessorRegisters = whpx_emu_setreg_callback, .WHvEmulatorTranslateGvaPage = whpx_emu_translate_callback, From 2bf3e74de4e5e33eb477e9ebe1839f9594173773 Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM) via Qemu-devel" <qemu-devel@nongnu.org> Date: Mon, 26 Feb 2018 09:13:34 -0800 Subject: [PATCH 30/34] Fix WHPX issue leaking tpr values Fixes an issue where if the tpr is assigned to the array but not a different value from what is already expected on the vp the code will skip incrementing the reg_count. In this case its possible that we set an invalid memory section of the next call for DeliverabilityNotifications that was not expected. The fix is to use a local variable to store the temporary tpr and only update the array if the local tpr value is different than the vp context. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com> Message-Id: <1519665216-1078-7-git-send-email-juterry@microsoft.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> --- target/i386/whpx-all.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 7e58d5f68c..47a6935288 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -687,6 +687,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu) struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr); X86CPU *x86_cpu = X86_CPU(cpu); int irq; + uint8_t tpr; WHV_X64_PENDING_INTERRUPTION_REGISTER new_int = {0}; UINT32 reg_count = 0; WHV_REGISTER_VALUE reg_values[3] = {0}; @@ -746,9 +747,10 @@ static void whpx_vcpu_pre_run(CPUState *cpu) } /* Sync the TPR to the CR8 if was modified during the intercept */ - reg_values[reg_count].Reg64 = cpu_get_apic_tpr(x86_cpu->apic_state); - if (reg_values[reg_count].Reg64 != vcpu->tpr) { - vcpu->tpr = reg_values[reg_count].Reg64; + tpr = cpu_get_apic_tpr(x86_cpu->apic_state); + if (tpr != vcpu->tpr) { + vcpu->tpr = tpr; + reg_values[reg_count].Reg64 = tpr; cpu->exit_request = 1; reg_names[reg_count] = WHvX64RegisterCr8; reg_count += 1; From e2940978fc86b2bf2016e115c56c01f850092bfb Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM) via Qemu-devel" <qemu-devel@nongnu.org> Date: Mon, 26 Feb 2018 09:13:35 -0800 Subject: [PATCH 31/34] WHXP Removes the use of WHvGetExitContextSize The use of WHvGetExitContextSize will break ABI compatibility if the platform changes the context size while a qemu compiled executable does not recompile. To avoid this we now use sizeof and let the platform determine which version of the struction was passed for ABI compatibility. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com> Message-Id: <1519665216-1078-8-git-send-email-juterry@microsoft.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> --- target/i386/whpx-all.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 47a6935288..24387bebad 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -32,7 +32,6 @@ struct whpx_state { uint64_t mem_quota; WHV_PARTITION_HANDLE partition; - uint32_t exit_ctx_size; }; static const WHV_REGISTER_NAME whpx_register_names[] = { @@ -899,7 +898,7 @@ static int whpx_vcpu_run(CPUState *cpu) } hr = WHvRunVirtualProcessor(whpx->partition, cpu->cpu_index, - &vcpu->exit_ctx, whpx->exit_ctx_size); + &vcpu->exit_ctx, sizeof(vcpu->exit_ctx)); if (FAILED(hr)) { error_report("WHPX: Failed to exec a virtual processor," @@ -1042,8 +1041,7 @@ int whpx_init_vcpu(CPUState *cpu) } } - vcpu = g_malloc0(FIELD_OFFSET(struct whpx_vcpu, exit_ctx) + - whpx->exit_ctx_size); + vcpu = g_malloc0(sizeof(struct whpx_vcpu)); if (!vcpu) { error_report("WHPX: Failed to allocte VCPU context."); @@ -1300,9 +1298,6 @@ static int whpx_accel_init(MachineState *ms) goto error; } - whpx->exit_ctx_size = WHvGetRunExitContextSize(); - assert(whpx->exit_ctx_size); - whpx_memory_init(); cpu_interrupt_handler = whpx_handle_interrupt; From eb1fe944a89457981407f5335f11bae104a32e57 Mon Sep 17 00:00:00 2001 From: "Justin Terry (VM) via Qemu-devel" <qemu-devel@nongnu.org> Date: Mon, 26 Feb 2018 09:13:36 -0800 Subject: [PATCH 32/34] WHPX improve interrupt notification registration Improves the usage of the InterruptNotification registration by skipping the additional call to WHvSetVirtualProcessorRegisters if we have already registered for the window exit. Signed-off-by: Justin Terry (VM) <juterry@microsoft.com> Message-Id: <1519665216-1078-9-git-send-email-juterry@microsoft.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org> --- target/i386/whpx-all.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 24387bebad..940bbe590d 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -756,12 +756,11 @@ static void whpx_vcpu_pre_run(CPUState *cpu) } /* Update the state of the interrupt delivery notification */ - if (cpu->interrupt_request & CPU_INTERRUPT_HARD) { + if (!vcpu->window_registered && + cpu->interrupt_request & CPU_INTERRUPT_HARD) { reg_values[reg_count].DeliverabilityNotifications.InterruptNotification = 1; - if (vcpu->window_registered != 1) { - vcpu->window_registered = 1; - } + vcpu->window_registered = 1; reg_names[reg_count] = WHvX64RegisterDeliverabilityNotifications; reg_count += 1; } From 4060e671c33679198d777558bf7c3750610e0f3d Mon Sep 17 00:00:00 2001 From: Thomas Huth <thuth@redhat.com> Date: Wed, 28 Feb 2018 06:38:23 +0100 Subject: [PATCH 33/34] balloon: Fix documentation of the --balloon parameter and deprecate it There are two issues with the documentation of the --balloon parameter: First, "--balloon none" is simply doing nothing. Even if a machine had a balloon device by default, this option is not disabling anything, it is simply ignored. Thus let's simply drop this option from the documentation to avoid to confuse the users (but keep the code in vl.c for backward compatibility). Second, the documentation claims that "--balloon virtio" is the default mode, but this is not true anymore since commit 382f074371f7dc32a34. Since that commit, the option also has no real use case anymore, since you can simply use "--device virtio-balloon" nowadays instead. Thus to simplify our complex parameter zoo a little bit, let's deprecate the the parameter now and tell the user to use "--device virtio-balloon" instead. Fixes: 382f074371f7dc32a34c944c845b1698e83d8c36 Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <1519796303-13257-1-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- qemu-doc.texi | 5 +++++ qemu-options.hx | 11 ++++------- vl.c | 3 +++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/qemu-doc.texi b/qemu-doc.texi index 589519a900..39e38c87ec 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2707,6 +2707,11 @@ enabled via the ``-machine usb=on'' argument. The ``-nodefconfig`` argument is a synonym for ``-no-user-config``. +@subsection -balloon (since 2.12.0) + +The @option{--balloon virtio} argument has been superseded by +@option{--device virtio-balloon}. + @subsection -machine s390-squash-mcss=on|off (since 2.12.0) The ``s390-squash-mcss=on`` property has been obsoleted by allowing the diff --git a/qemu-options.hx b/qemu-options.hx index 2a22a62f74..6585058c6c 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -462,16 +462,13 @@ modprobe i810_audio clocking=48000 ETEXI DEF("balloon", HAS_ARG, QEMU_OPTION_balloon, - "-balloon none disable balloon device\n" "-balloon virtio[,addr=str]\n" - " enable virtio balloon device (default)\n", QEMU_ARCH_ALL) + " enable virtio balloon device (deprecated)\n", QEMU_ARCH_ALL) STEXI -@item -balloon none -@findex -balloon -Disable balloon device. @item -balloon virtio[,addr=@var{addr}] -Enable virtio balloon device (default), optionally with PCI address -@var{addr}. +@findex -balloon +Enable virtio balloon device, optionally with PCI address @var{addr}. This +option is deprecated, use @option{--device virtio-balloon} instead. ETEXI DEF("device", HAS_ARG, QEMU_OPTION_device, diff --git a/vl.c b/vl.c index e648bed0e1..dae986b352 100644 --- a/vl.c +++ b/vl.c @@ -2209,6 +2209,9 @@ static int balloon_parse(const char *arg) { QemuOpts *opts; + warn_report("This option is deprecated. " + "Use '--device virtio-balloon' to enable the balloon device."); + if (strcmp(arg, "none") == 0) { return 0; } From 3e015d815b3f28bfd874bf8a1697308ef9af2b4c Mon Sep 17 00:00:00 2001 From: Julia Suvorova <jusual@mail.ru> Date: Thu, 1 Mar 2018 10:08:06 +0300 Subject: [PATCH 34/34] use g_path_get_basename instead of basename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit basename(3) and dirname(3) modify their argument and may return pointers to statically allocated memory which may be overwritten by subsequent calls. g_path_get_basename and g_path_get_dirname have no such issues, and therefore more preferable. Signed-off-by: Julia Suvorova <jusual@mail.ru> Message-Id: <1519888086-4207-1-git-send-email-jusual@mail.ru> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- fsdev/virtfs-proxy-helper.c | 15 +++++++++------ hw/s390x/s390-ccw.c | 2 +- hw/vfio/pci.c | 2 +- hw/vfio/platform.c | 2 +- qemu-io.c | 2 +- qga/commands-posix.c | 4 ++-- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c index 8e48500dd5..6f132c5ff1 100644 --- a/fsdev/virtfs-proxy-helper.c +++ b/fsdev/virtfs-proxy-helper.c @@ -55,6 +55,7 @@ static struct option helper_opts[] = { static bool is_daemon; static bool get_version; /* IOC getversion IOCTL supported */ +static char *prog_name; static void GCC_FMT_ATTR(2, 3) do_log(int loglevel, const char *format, ...) { @@ -785,7 +786,7 @@ error: return -1; } -static void usage(char *prog) +static void usage(void) { fprintf(stderr, "usage: %s\n" " -p|--path <path> 9p path to export\n" @@ -795,7 +796,7 @@ static void usage(char *prog) " access to this socket\n" " \tNote: -s & -f can not be used together\n" " [-n|--nodaemon] Run as a normal program\n", - basename(prog)); + prog_name); } static int process_reply(int sock, int type, @@ -1045,6 +1046,8 @@ int main(int argc, char **argv) struct statfs st_fs; #endif + prog_name = g_path_get_basename(argv[0]); + is_daemon = true; sock = -1; own_u = own_g = -1; @@ -1077,7 +1080,7 @@ int main(int argc, char **argv) case '?': case 'h': default: - usage(argv[0]); + usage(); exit(EXIT_FAILURE); } } @@ -1085,13 +1088,13 @@ int main(int argc, char **argv) /* Parameter validation */ if ((sock_name == NULL && sock == -1) || rpath == NULL) { fprintf(stderr, "socket, socket descriptor or path not specified\n"); - usage(argv[0]); + usage(); return -1; } if (sock_name && sock != -1) { fprintf(stderr, "both named socket and socket descriptor specified\n"); - usage(argv[0]); + usage(); exit(EXIT_FAILURE); } @@ -1099,7 +1102,7 @@ int main(int argc, char **argv) fprintf(stderr, "owner uid:gid not specified, "); fprintf(stderr, "owner uid:gid specifies who can access the socket file\n"); - usage(argv[0]); + usage(); exit(EXIT_FAILURE); } diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c index 7fc1c603c0..214c940593 100644 --- a/hw/s390x/s390-ccw.c +++ b/hw/s390x/s390-ccw.c @@ -48,7 +48,7 @@ static void s390_ccw_get_dev_info(S390CCWDevice *cdev, return; } - cdev->mdevid = g_strdup(basename(dev_path)); + cdev->mdevid = g_path_get_basename(dev_path); tmp = basename(dirname(dev_path)); if (sscanf(tmp, "%2x.%1x.%4x", &cssid, &ssid, &devid) != 3) { diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 033cc8dea1..3ba3cbc146 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -2807,7 +2807,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) return; } - vdev->vbasedev.name = g_strdup(basename(vdev->vbasedev.sysfsdev)); + vdev->vbasedev.name = g_path_get_basename(vdev->vbasedev.sysfsdev); vdev->vbasedev.ops = &vfio_pci_ops; vdev->vbasedev.type = VFIO_DEVICE_TYPE_PCI; vdev->vbasedev.dev = &vdev->pdev.qdev; diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c index 0d4bc0aae8..5c921c27ba 100644 --- a/hw/vfio/platform.c +++ b/hw/vfio/platform.c @@ -561,7 +561,7 @@ static int vfio_base_device_init(VFIODevice *vbasedev, Error **errp) /* @sysfsdev takes precedence over @host */ if (vbasedev->sysfsdev) { g_free(vbasedev->name); - vbasedev->name = g_strdup(basename(vbasedev->sysfsdev)); + vbasedev->name = g_path_get_basename(vbasedev->sysfsdev); } else { if (!vbasedev->name || strchr(vbasedev->name, '/')) { error_setg(errp, "wrong host device name"); diff --git a/qemu-io.c b/qemu-io.c index 2c00ea068e..160fb2a89f 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -504,7 +504,7 @@ int main(int argc, char **argv) #endif module_call_init(MODULE_INIT_TRACE); - progname = basename(argv[0]); + progname = g_path_get_basename(argv[0]); qemu_init_exec_dir(argv[0]); qcrypto_init(&error_fatal); diff --git a/qga/commands-posix.c b/qga/commands-posix.c index ac17d0d6cf..0dc219dbcf 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -808,7 +808,7 @@ static char *get_pci_driver(char const *syspath, int pathlen, Error **errp) len = readlink(dpath, buf, sizeof(buf) - 1); if (len != -1) { buf[len] = 0; - driver = g_strdup(basename(buf)); + driver = g_path_get_basename(buf); } g_free(dpath); g_free(path); @@ -1053,7 +1053,7 @@ static void build_guest_fsinfo_for_device(char const *devpath, } if (!fs->name) { - fs->name = g_strdup(basename(syspath)); + fs->name = g_path_get_basename(syspath); } g_debug(" parse sysfs path '%s'", syspath);