[Qemu-devel] [Bug 1379340] Re: qemu-kvm guest panic for AMD smp trusty guests
** No longer affects: qemu -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1379340 Title: qemu-kvm guest panic for AMD smp trusty guests Status in “qemu” package in Ubuntu: New Bug description: Just upgraded OpenStack compute hosts in our public cloud (using qemu- kvm via libvirt) from Precise to Trusty (14.04.1), now on kernel 3.13.0-36-generic with qemu-kvm 2.0.0+dfsg-2ubuntu1.5. Following the upgrade, whenever we try to start an smp/multicore Trusty guest (existing or new), we run into this panic [1] inside the guest just towards the end of boot. This happens consistently for smp guests using the Trusty kernel (i.e., it also affects earlier Ubuntus using the HWE kernel from Trusty but not their native versions). I didn't have any other distro images to hand with 3.13.x kernels, but none of the others I tested were affected (in the 3.2 - 3.16 kernel range). There are scarce similar reports out there, but the one we did find pointed to a CPU feature as the trigger. We were running these hosts with libvirt cpu mode set to host-passthrough (so qemu starts with -cpu host), on AMD 6200 6300 Opteron hardware. Switching the guest domains to use cpu mode host-model instead works around the issue and is perfectly acceptable for most of our users. We have various other Intel compute hosts and they don't seem to be affected. (1) [ 11.256924] divide error: [#1] SMP [ 11.258133] Modules linked in: kvm_amd kvm crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd serio_raw lp parport psmouse floppy [ 11.260228] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.13.0-36-generic #63-Ubuntu [ 11.260228] Hardware name: OpenStack Foundation OpenStack Nova, BIOS Bochs 01/01/2011 [ 11.260228] task: 81c15480 ti: 81c0 task.ti: 81c0 [ 11.260228] RIP: 0010:[8104ed58] [8104ed58] kvm_unlock_kick+0xa8/0x100 [ 11.260228] RSP: 0018:88023fc03c98 EFLAGS: 00010046 [ 11.260228] RAX: 0005 RBX: RCX: 0001 [ 11.260228] RDX: 81eaf408 RSI: RDI: [ 11.260228] RBP: 88023fc03cb8 R08: 81eaf400 R09: [ 11.260228] R10: 880037612cc0 R11: ea0002eb0a00 R12: 8800374a33c0 [ 11.260228] R13: 0020 R14: 0001 R15: 0286 [ 11.260228] FS: 7f1e8b538740() GS:88023fc0() knlGS: [ 11.260228] CS: 0010 DS: ES: CR0: 8005003b [ 11.260228] CR2: 7f1e8ae09d50 CR3: 01c0e000 CR4: 000406f0 [ 11.260228] Stack: [ 11.260228] 0286 0001 0001 00c3 [ 11.260228] 88023fc03cc8 81717ed6 88023fc03ce0 8172641a [ 11.260228] 8800374a33c0 88023fc03d18 810aaeb0 88023295e000 [ 11.260228] Call Trace: [ 11.260228] IRQ [ 11.260228] [81717ed6] __ticket_unlock_slowpath+0x24/0x34 [ 11.260228] [8172641a] _raw_spin_unlock_irqrestore+0x3a/0x40 [ 11.260228] [810aaeb0] __wake_up_sync_key+0x50/0x60 [ 11.260228] [8160ca5a] sock_def_readable+0x3a/0x70 [ 11.260228] [816fda0a] packet_rcv+0x2fa/0x430 [ 11.260228] [816228b0] __netif_receive_skb_core+0x360/0x840 [ 11.260228] [81622da8] __netif_receive_skb+0x18/0x60 [ 11.260228] [81622e13] netif_receive_skb+0x23/0x90 [ 11.260228] [815288d4] virtnet_poll+0x4d4/0x850 [ 11.260228] [81623192] net_rx_action+0x152/0x250 [ 11.260228] [8106cbac] __do_softirq+0xec/0x2c0 [ 11.260228] [8106d0f5] irq_exit+0x105/0x110 [ 11.260228] [817312d6] do_IRQ+0x56/0xc0 [ 11.260228] [81726a6d] common_interrupt+0x6d/0x6d [ 11.260228] EOI [ 11.260228] [8104f596] ? native_safe_halt+0x6/0x10 [ 11.260228] [8101c62f] default_idle+0x1f/0xc0 [ 11.260228] [8101cef6] arch_cpu_idle+0x26/0x30 [ 11.260228] [810bed95] cpu_startup_entry+0xc5/0x290 [ 11.260228] [8170ca77] rest_init+0x77/0x80 [ 11.260228] [81d35f6b] start_kernel+0x433/0x43e [ 11.260228] [81d35941] ? repair_env_string+0x5c/0x5c [ 11.260228] [81d35120] ? early_idt_handlers+0x120/0x120 [ 11.260228] [81d355ee] x86_64_start_reservations+0x2a/0x2c [ 11.260228] [81d35733] x86_64_start_kernel+0x143/0x152 [ 11.260228] Code: 66 44 39 e8 75 bd 0f b6 35 f6 06 e6 00 40 84 f6 75 2a 83 05 06 07 e6 00 01 48 c7 c0 6a b0 00 00 31 db 0f b7 0c 01 b8 05 00 00 00 0f 01 c1 0f 1f 44 00 00 5b 41 5c 41 5d 41 5e 5d c3 89 f0 31 c9 [ 11.260228] RIP [8104ed58] kvm_unlock_kick+0xa8/0x100 [ 11.260228] RSP 88023fc03c98 [ 11.260228]
[Qemu-devel] [PATCH V8 0/3] Virtual Machine Generation ID
Hi, The patch grow to three parts now. Although it is still add a QEmu support for Microsoft's Virtual Machine Generation ID device. The first is a short device's description, then the ACPI tables changes and the actual device and the last patch updates the tests' ACPI tables. Your comment are welcomed. Thanks, Gal. V8 - Add a device's description file. - GUID is stored in fw cfg file and the guest writes the physical address to the device (reduces vmexits). V7 - Move the device's description back to the static SSDT table. - The GUID is store in a hard coded physical address and not in the ACPI table itself. - ACPI notification is triggered when the GUID is changed. V6 - include the pre-compiled ASL file - remove an empty line at end of files. V5 - Move device's description to SSDT table (dynamic). V4 - Fix a typo in error message string. - Move device's description from DSDT back to SSDT table. V3 - Remove -uuid command line parameter. - Move device's description from SSDT to DSDT table. - Add new vmgenid sysbus device. Gal Hammer (3): docs: vm generation id device's description i386: Add a Virtual Machine Generation ID device tests: update acpi tables after adding the vmgenid device default-configs/i386-softmmu.mak | 1 + default-configs/x86_64-softmmu.mak | 1 + docs/specs/vmgenid.txt | 27 hw/acpi/core.c | 8 +++ hw/acpi/ich9.c | 8 +++ hw/acpi/piix4.c | 8 +++ hw/i386/acpi-build.c | 26 +++ hw/i386/acpi-dsdt.dsl| 4 +- hw/i386/acpi-dsdt.hex.generated | 6 +- hw/i386/pc.c | 8 +++ hw/i386/q35-acpi-dsdt.dsl| 5 +- hw/i386/q35-acpi-dsdt.hex.generated | 8 +-- hw/i386/ssdt-misc.dsl| 43 hw/i386/ssdt-misc.hex.generated | 8 +-- hw/isa/lpc_ich9.c| 1 + hw/misc/Makefile.objs| 1 + hw/misc/vmgenid.c| 131 +++ include/hw/acpi/acpi.h | 2 + include/hw/acpi/acpi_dev_interface.h | 4 ++ include/hw/acpi/ich9.h | 2 + include/hw/i386/pc.h | 3 + include/hw/misc/vmgenid.h| 21 ++ tests/acpi-test-data/pc/DSDT | Bin 2807 - 2820 bytes tests/acpi-test-data/pc/SSDT | Bin 3065 - 3268 bytes tests/acpi-test-data/q35/DSDT| Bin 7397 - 7410 bytes tests/acpi-test-data/q35/SSDT| Bin 1346 - 1549 bytes 26 files changed, 313 insertions(+), 13 deletions(-) create mode 100644 docs/specs/vmgenid.txt create mode 100644 hw/misc/vmgenid.c create mode 100644 include/hw/misc/vmgenid.h -- 1.9.3
[Qemu-devel] [PATCH 1/3] docs: vm generation id device's description
Signed-off-by: Gal Hammer gham...@redhat.com --- docs/specs/vmgenid.txt | 27 +++ 1 file changed, 27 insertions(+) create mode 100644 docs/specs/vmgenid.txt diff --git a/docs/specs/vmgenid.txt b/docs/specs/vmgenid.txt new file mode 100644 index 000..9a09d11 --- /dev/null +++ b/docs/specs/vmgenid.txt @@ -0,0 +1,27 @@ +VIRTUAL MACHINE GENERATION ID += + +The VM generation ID (vmgenid) device is an emulated device which +expose a 128-bit, cryptographically random, integer value identifier. +This allows management applications (e.g. libvirt) to notify the guest +operating system when the virtual machine is executed with a different +configuration (e.g. snapshot execution or creation from a template). + +Specs is on the web at: http://go.microsoft.com/fwlink/?LinkId=260709 + +--- + +The vmgenid device is a sysbus device with the following ACPI ID: +QEMU0002. + +The device adds a vmgenid.uuid property, which can be modifed using +the -global command line argument or the QMP interface. + +The device uses a fixed memory resource: 0xfedf-0xfedf0003. The +guest is expected to write the physical address of the GUID's buffer +to that memory resource. This allows the device to modify the GUID if +requested by the management application. + +According to the specification, any change to the GUID executes an +ACPI notification. The vmgenid device triggers the GPE._E00 which +executes the ACPI Notify operation. -- 1.9.3
[Qemu-devel] [PATCH 2/3] i386: Add a Virtual Machine Generation ID device
Based on Microsoft's sepecifications (paper can be dowloaded from http://go.microsoft.com/fwlink/?LinkId=260709), add a device description to the SSDT ACPI table and its implementation. The GUID is set using a global vmgenid.uuid parameter. Signed-off-by: Gal Hammer gham...@redhat.com --- default-configs/i386-softmmu.mak | 1 + default-configs/x86_64-softmmu.mak | 1 + hw/acpi/core.c | 8 +++ hw/acpi/ich9.c | 8 +++ hw/acpi/piix4.c | 8 +++ hw/i386/acpi-build.c | 26 +++ hw/i386/acpi-dsdt.dsl| 4 +- hw/i386/acpi-dsdt.hex.generated | 6 +- hw/i386/pc.c | 8 +++ hw/i386/q35-acpi-dsdt.dsl| 5 +- hw/i386/q35-acpi-dsdt.hex.generated | 8 +-- hw/i386/ssdt-misc.dsl| 43 hw/i386/ssdt-misc.hex.generated | 8 +-- hw/isa/lpc_ich9.c| 1 + hw/misc/Makefile.objs| 1 + hw/misc/vmgenid.c| 131 +++ include/hw/acpi/acpi.h | 2 + include/hw/acpi/acpi_dev_interface.h | 4 ++ include/hw/acpi/ich9.h | 2 + include/hw/i386/pc.h | 3 + include/hw/misc/vmgenid.h| 21 ++ 21 files changed, 286 insertions(+), 13 deletions(-) create mode 100644 hw/misc/vmgenid.c create mode 100644 include/hw/misc/vmgenid.h diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 8e08841..bd33c75 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -45,3 +45,4 @@ CONFIG_IOAPIC=y CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y +CONFIG_VMGENID=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 66557ac..006fc7c 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -45,3 +45,4 @@ CONFIG_IOAPIC=y CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y +CONFIG_VMGENID=y diff --git a/hw/acpi/core.c b/hw/acpi/core.c index 51913d6..d4597c6 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -28,6 +28,8 @@ #include qapi-visit.h #include qapi-event.h +#define ACPI_VM_GENERATION_ID_CHANGED_STATUS 1 + struct acpi_table_header { uint16_t _length; /* our length, not actual part of the hdr */ /* allows easier parsing for fw_cfg clients */ @@ -683,3 +685,9 @@ void acpi_update_sci(ACPIREGS *regs, qemu_irq irq) (regs-pm1.evt.en ACPI_BITMASK_TIMER_ENABLE) !(pm1a_sts ACPI_BITMASK_TIMER_STATUS)); } + +void acpi_vm_generation_id_changed(ACPIREGS *acpi_regs, qemu_irq irq) +{ +acpi_regs-gpe.sts[0] |= ACPI_VM_GENERATION_ID_CHANGED_STATUS; +acpi_update_sci(acpi_regs, irq); +} diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index ea991a3..12a9387 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -307,3 +307,11 @@ void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) acpi_memory_ospm_status(s-pm.acpi_memory_hotplug, list); } + +void ich9_vm_generation_id_changed(AcpiDeviceIf *adev) +{ +ICH9LPCState *s = ICH9_LPC_DEVICE(adev); +ICH9LPCPMRegs *pm = s-pm; + +acpi_vm_generation_id_changed(pm-acpi_regs, pm-irq); +} diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 481a16c..41b6eb6 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -574,6 +574,13 @@ static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) acpi_memory_ospm_status(s-acpi_memory_hotplug, list); } +static void piix4_vm_generation_id_changed(AcpiDeviceIf *adev) +{ +PIIX4PMState *s = PIIX4_PM(adev); + +acpi_vm_generation_id_changed(s-ar, s-irq); +} + static Property piix4_pm_properties[] = { DEFINE_PROP_UINT32(smb_io_base, PIIX4PMState, smb_io_base, 0), DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), @@ -611,6 +618,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data) hc-plug = piix4_device_plug_cb; hc-unplug_request = piix4_device_unplug_request_cb; adevc-ospm_status = piix4_ospm_status; +adevc-vm_generation_id_changed = piix4_vm_generation_id_changed; } static const TypeInfo piix4_pm_info = { diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 4003b6b..0cfa598 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -250,6 +250,7 @@ static void acpi_get_pci_info(PcPciInfo *info) #define ACPI_BUILD_TABLE_FILE etc/acpi/tables #define ACPI_BUILD_RSDP_FILE etc/acpi/rsdp #define ACPI_BUILD_TPMLOG_FILE etc/tpm/log +#define ACPI_BUILD_VMGENID_FILE etc/vm-generation-id static void build_header(GArray *linker, GArray *table_data, @@ -1061,6 +1062,8 @@ build_ssdt(GArray *table_data, GArray *linker, { MachineState *machine = MACHINE(qdev_get_machine()); uint32_t nr_mem = machine-ram_slots; +uint32_t
[Qemu-devel] [PATCH 3/3] tests: update acpi tables after adding the vmgenid device
Signed-off-by: Gal Hammer gham...@redhat.com --- tests/acpi-test-data/pc/DSDT | Bin 2807 - 2820 bytes tests/acpi-test-data/pc/SSDT | Bin 3065 - 3268 bytes tests/acpi-test-data/q35/DSDT | Bin 7397 - 7410 bytes tests/acpi-test-data/q35/SSDT | Bin 1346 - 1549 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT index d37ec34454e6f3db5e91b777f94e03be67a5f583..8c86b1e39454f611ee25ababe0ef429956ba7562 100644 GIT binary patch delta 65 zcmew^+9Jl~66_Mf!p*?I=(mwef=knhFWx=Cl_TE6(}ma3Il$Avz`%?_L^$5nz{AG UMlU|tDL%~C-IJ?fvK`k0P4aI+5i9m delta 52 zcmZn`!34m66_N4or{5iv0)Z1ec5}Z@hbeD@VMCrwgy6bAYFTfq@x=2wS|5fdRv0 HZ?2sHWr7Ua diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT index eb2d8b698ce6a3a910a05244a3b6cf80bf818fb9..ab75f3f382a16ec4af3a8e73e8ed9cfdab2c4599 100644 GIT binary patch delta 228 zcmewengThIM^lR2oD1TW6(yfNXB|Eo|yPxr}*e5N1iZWcTbLZ4^J1~Kv;T0|Nsi z299`VAUDi6-aR!h-Z{TCuOzhyDCpwihani|?%0LmVqI!9O6#odL+c|Bs6$x{({i zWe)IbW{Ku7ZfZg$ij2~v6gAB#7Ts$x1kN5QRWGDcc0a7R;5g#1l2;nCzV4Ix4 su!LbD%Mvbr5gA7pmmrP;Att5-uDKk28IHLjs!-AB?+687^iaq0EU}9OaK4? delta 24 fcmXi`BR)LIM^lRCpQBFWA{d`NXE^2Ow+gkWu^yS diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT index 2d2bc4adaf54666fe7864e7f39203411b7c308f7..b45f6065ad6140bd987550cc22ff38b09243188f 100644 GIT binary patch delta 65 zcmaEA`N@*YCDk8lMDj`JFB^mNJ_DT=DJ!t{m|mo-VwOHhV1_ovfBEsm1_lgm UF?#XAPVrB?w(u?ljCLD0C3V0KL7v# delta 52 zcmexl`P7ojCDk8sSE=Hqv%F1OBop_u6XwVSB`iOPZwTC=KxOw0|PS#5w_A0|SQ1 HIWlbke7y}n diff --git a/tests/acpi-test-data/q35/SSDT b/tests/acpi-test-data/q35/SSDT index 778b79bf428b5d7602b7b80c9434e38c79718bb2..dffee695109a7d97e1d15994aae4207f47639389 100644 GIT binary patch delta 228 zcmX@a)yu;b9PARp%f`UKD7uj=lCj4Cni4FDL%T%ktfX8-IF8U!_$Q~(A788z`($W zfg|1-$PM$2cTdfWcg`=(D@iQ^3c9%XVF-q~dphzk06}zve?X8s1CV|H9~VnBR7c4 z9N-b@r~ouBC|FRCi?59nr1Jhh7H=R`$socX@9F2sPyjLmq)d6J~+e?!cSPhHaUS| r3By8`C0zUGL9}TK^z4_OiT%2)g1{83V4w35*O5;i9K41m_Ir2LU delta 24 fcmeCImEk9PAR}#LB?H=(mw8l5w*h(|u+DOr!=L -- 1.9.3
[Qemu-devel] exec.c:invalidate_and_set_dirty() only checks whether first page in its range is dirty...
I'm trying to track down a bug in ARM TCG where we: * boot a guest * run 'shutdown -r now' to trigger a reboot * on reboot, crash when running userspace because the contents of physical RAM have changed but the translated code from before the shutdown was never invalidated This is with a virtio-mmio block device as the disk. Debugging indicates that when the post-reboot guest reloads binaries from disk into ram we fail to invalidate the cached translations. For the specific case I looked at, we have a translation of code at ramaddr_t 0x806e000. The disk load pulls 0x16000 bytes of data off disk to address 0x806a000. Virtio correctly calls address_space_unmap(), which is supposed to be what marks the ram range as dirty. It in turn calls invalidate_and_set_clean(). However invalidate_and_set_clean() just does this: if (cpu_physical_memory_is_clean(addr)) { /* invalidate code */ tb_invalidate_phys_page_range(addr, addr + length, 0); /* set dirty bit */ cpu_physical_memory_set_dirty_range_nocode(addr, length); } So if the first page in the range (here 0x806a000) happens to be dirty then we won't do anything, even if later pages in the range do need to be invalidated. Also, we'll call tb_invalidate_phys_page_range() with a start/end which may be in different physical pages, which is forbidden by that function's API. I guess invalidate_and_set_clean() really needs to be fixed to loop through each page in the range; does anybody know how this is supposed to work (or why nobody's noticed this bug before :-)) ? thanks -- PMM
[Qemu-devel] [PATCH] exec: Handle multipage ranges in invalidate_and_set_dirty()
The code in invalidate_and_set_dirty() needs to handle addr/length combinations which cross guest physical page boundaries. This can happen, for example, when disk I/O reads large blocks into guest RAM which previously held code that we have cached translations for. Unfortunately we were only checking the clean/dirty status of the first page in the range, and then were calling a tb_invalidate function which only handles ranges that don't cross page boundaries. Fix the function to deal with multipage ranges. The symptoms of this bug were that guest code would misbehave (eg segfault), in particular after a guest reboot but potentially any time the guest reused a page of its physical RAM for new code. Cc: qemu-sta...@nongnu.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- This seems pretty nasty, and I have no idea why it hasn't been wreaking more havoc than this before. I'm not entirely sure why we invalidate TBs if any of the dirty bits is set rather than only if the code bit is set, but I left that logic as it is. Review appreciated -- it would be nice to get this into rc2 if we can, I think. exec.c | 6 ++ include/exec/ram_addr.h | 25 + 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index 759055d..f0e2bd3 100644 --- a/exec.c +++ b/exec.c @@ -2066,10 +2066,8 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, static void invalidate_and_set_dirty(hwaddr addr, hwaddr length) { -if (cpu_physical_memory_is_clean(addr)) { -/* invalidate code */ -tb_invalidate_phys_page_range(addr, addr + length, 0); -/* set dirty bit */ +if (cpu_physical_memory_range_includes_clean(addr, length)) { +tb_invalidate_phys_range(addr, addr + length, 0); cpu_physical_memory_set_dirty_range_nocode(addr, length); } xen_modified_memory(addr, length); diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index cf1d4c7..8fc75cd 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -49,6 +49,21 @@ static inline bool cpu_physical_memory_get_dirty(ram_addr_t start, return next end; } +static inline bool cpu_physical_memory_get_clean(ram_addr_t start, + ram_addr_t length, + unsigned client) +{ +unsigned long end, page, next; + +assert(client DIRTY_MEMORY_NUM); + +end = TARGET_PAGE_ALIGN(start + length) TARGET_PAGE_BITS; +page = start TARGET_PAGE_BITS; +next = find_next_zero_bit(ram_list.dirty_memory[client], end, page); + +return next end; +} + static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, unsigned client) { @@ -64,6 +79,16 @@ static inline bool cpu_physical_memory_is_clean(ram_addr_t addr) return !(vga code migration); } +static inline bool cpu_physical_memory_range_includes_clean(ram_addr_t start, +ram_addr_t length) +{ +bool vga = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_VGA); +bool code = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_CODE); +bool migration = +cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_MIGRATION); +return vga || code || migration; +} + static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, unsigned client) { -- 1.9.1
Re: [Qemu-devel] [PATCH V8 0/3] Virtual Machine Generation ID
On Sun, Nov 16, 2014 at 12:15:56PM +0200, Gal Hammer wrote: Hi, The patch grow to three parts now. Although it is still add a QEmu support for Microsoft's Virtual Machine Generation ID device. The first is a short device's description, then the ACPI tables changes and the actual device and the last patch updates the tests' ACPI tables. Your comment are welcomed. Thanks, Gal. Looks good, but how about a unit test? Should be easy: give device a physical address, read back memory to see that it's been written to. V8 - Add a device's description file. - GUID is stored in fw cfg file and the guest writes the physical address to the device (reduces vmexits). V7 - Move the device's description back to the static SSDT table. - The GUID is store in a hard coded physical address and not in the ACPI table itself. - ACPI notification is triggered when the GUID is changed. V6 - include the pre-compiled ASL file - remove an empty line at end of files. V5 - Move device's description to SSDT table (dynamic). V4 - Fix a typo in error message string. - Move device's description from DSDT back to SSDT table. V3 - Remove -uuid command line parameter. - Move device's description from SSDT to DSDT table. - Add new vmgenid sysbus device. Gal Hammer (3): docs: vm generation id device's description i386: Add a Virtual Machine Generation ID device tests: update acpi tables after adding the vmgenid device default-configs/i386-softmmu.mak | 1 + default-configs/x86_64-softmmu.mak | 1 + docs/specs/vmgenid.txt | 27 hw/acpi/core.c | 8 +++ hw/acpi/ich9.c | 8 +++ hw/acpi/piix4.c | 8 +++ hw/i386/acpi-build.c | 26 +++ hw/i386/acpi-dsdt.dsl| 4 +- hw/i386/acpi-dsdt.hex.generated | 6 +- hw/i386/pc.c | 8 +++ hw/i386/q35-acpi-dsdt.dsl| 5 +- hw/i386/q35-acpi-dsdt.hex.generated | 8 +-- hw/i386/ssdt-misc.dsl| 43 hw/i386/ssdt-misc.hex.generated | 8 +-- hw/isa/lpc_ich9.c| 1 + hw/misc/Makefile.objs| 1 + hw/misc/vmgenid.c| 131 +++ include/hw/acpi/acpi.h | 2 + include/hw/acpi/acpi_dev_interface.h | 4 ++ include/hw/acpi/ich9.h | 2 + include/hw/i386/pc.h | 3 + include/hw/misc/vmgenid.h| 21 ++ tests/acpi-test-data/pc/DSDT | Bin 2807 - 2820 bytes tests/acpi-test-data/pc/SSDT | Bin 3065 - 3268 bytes tests/acpi-test-data/q35/DSDT| Bin 7397 - 7410 bytes tests/acpi-test-data/q35/SSDT| Bin 1346 - 1549 bytes 26 files changed, 313 insertions(+), 13 deletions(-) create mode 100644 docs/specs/vmgenid.txt create mode 100644 hw/misc/vmgenid.c create mode 100644 include/hw/misc/vmgenid.h -- 1.9.3
Re: [Qemu-devel] [PATCH] vmdk: Leave bdi intact if -ENOTSUP in vmdk_get_info
On Fri, 11/14 09:29, Stefan Hajnoczi wrote: On Fri, Nov 14, 2014 at 12:09:21PM +0800, Fam Zheng wrote: When extent types don't match, we return -ENOTSUP. In this case, be polite to the caller and don't modify bdi. Signed-off-by: Fam Zheng f...@redhat.com --- block/vmdk.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) At this stage of the release process it would be very helpful to include some context for this patch: is it a pure cleanup or actually a bug fix that needs to go into QEMU 2.2? This one is more of a cleanup than bug fix: although there is a small logical change, it's only visible to user on abnormally structured VMDK (mixed extent type, etc.) that require manual editing image file, which is AFAIK not a valid use case and will not cause anything worse than an error. I sent the patch mostly for the function semantic purpose: don't change caller's data unless it's necessary to. Since you are a regular contributor and I therefore trust you, I have merged this patch. But please be clear in commit descriptions about whether or not a patch is a bug fix (how to reproduce the bug, if a previous commit's regression is being fixed, etc). OK. I'll remember next time. Thanks for pointing out. Fam
Re: [Qemu-devel] [RFC][PATCH 2/2] xen:i386:pc_piix: create isa bridge specific to IGD passthrough
On 2014/11/5 22:09, Michael S. Tsirkin wrote: On Wed, Nov 05, 2014 at 03:22:59PM +0800, Tiejun Chen wrote: Currently IGD drivers always need to access PCH by 1f.0, and PCH vendor/device id is used to identify the card. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/i386/pc_piix.c | 28 +++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index b559181..b19c7a9 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -50,7 +50,7 @@ #include cpu.h #include qemu/error-report.h #ifdef CONFIG_XEN -# include xen/hvm/hvm_info_table.h +#include xen/hvm/hvm_info_table.h #endif #define MAX_IDE_BUS 2 @@ -452,6 +452,31 @@ static void pc_init_isa(MachineState *machine) } #ifdef CONFIG_XEN +static void xen_igd_passthrough_isa_bridge_create(PCIBus *bus) +{ +struct PCIDevice *dev; +Error *local_err = NULL; +uint16_t device_id = 0x; + +/* Currently IGD drivers always need to access PCH by 1f.0. */ +dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0), +xen-igd-passthrough-isa-bridge); + +/* Identify PCH card with its own real vendor/device ids. + * Here that vendor id is always PCI_VENDOR_ID_INTEL. + */ +if (dev) { +device_id = object_property_get_int(OBJECT(dev), device-id, +local_err); +if (!local_err device_id != 0x) { +pci_config_set_device_id(dev-config, device_id); +return; +} +} + +fprintf(stderr, xen set xen-igd-passthrough-isa-bridge failed\n); +} + static void pc_xen_hvm_init(MachineState *machine) { PCIBus *bus; @@ -461,6 +486,7 @@ static void pc_xen_hvm_init(MachineState *machine) bus = pci_find_primary_bus(); if (bus != NULL) { pci_create_simple(bus, -1, xen-platform); +xen_igd_passthrough_isa_bridge_create(bus); } } #endif Can't we defer this step until the GPU is added? Sounds great but I can't figure out where we can to do this exactly. This way there won't be need to poke at host device directly, you could get all info from dev-config of the host device. As I understand We have two steps here: #1 At first I have to write something to check if we're registering 00:02.0 IGD, right? But where? While registering each pci device? #2 Then if that condition is matched, we register this ISA bridge on its associated bus. Thanks Tiejun Additionally the correct bridge would be initialized automatically. -- 1.9.1
[Qemu-devel] [RFC PATCH] spapr-pci: Enable huge BARs
At the moment sPAPR only supports 512MB window for MMIO BARs. However modern devices might want bigger 64bit BARs. This adds another 64bit MMIO window per PHB and advertises it via the PHB's ranges property in the device tree. The new window is 1TB long and starts from 1TB offset on a PCI address space. Older (3.12) kernels expect BARs to have the same offset on both bus and memory address spaces. Since we are getting now another MMIO region, we either have to add (0xA000. - 0x8000.) offset to its bus offset OR simply put MMIO range at the same offset as on the bus. This puts 32bit MMIO space at 0x8000. offset in RAM and IO space at 0xA000. (used to be vice versa). While we are here, let's increase PHB address spacing from 64GB to 16TB in order not to touch it again any time soon. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- I am not sure about 3.12 kernels, the info is from Ben. --- hw/ppc/spapr_pci.c | 18 ++ include/hw/pci-host/spapr.h | 15 ++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 21b95b3..8507464 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -495,6 +495,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) if ((sphb-buid != -1) || (sphb-dma_liobn != -1) || (sphb-mem_win_addr != -1) +|| (sphb-mem64_win_addr != -1) || (sphb-io_win_addr != -1)) { error_setg(errp, Either \index\ or other parameters must be specified for PAPR PHB, not both); @@ -507,6 +508,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) windows_base = SPAPR_PCI_WINDOW_BASE + sphb-index * SPAPR_PCI_WINDOW_SPACING; sphb-mem_win_addr = windows_base + SPAPR_PCI_MMIO_WIN_OFF; +sphb-mem64_win_addr = windows_base + SPAPR_PCI_MMIO64_WIN_OFF; sphb-io_win_addr = windows_base + SPAPR_PCI_IO_WIN_OFF; } @@ -550,6 +552,14 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(get_system_memory(), sphb-mem_win_addr, sphb-memwindow); +sprintf(namebuf, %s.mmio64-alias, sphb-dtbusname); +memory_region_init_alias(sphb-mem64window, OBJECT(sphb), + namebuf, sphb-memspace, + SPAPR_PCI_MEM64_WIN_BUS_OFFSET, + sphb-mem64_win_size); +memory_region_add_subregion(get_system_memory(), sphb-mem64_win_addr, +sphb-mem64window); + /* Initialize IO regions */ sprintf(namebuf, %s.io, sphb-dtbusname); memory_region_init(sphb-iospace, OBJECT(sphb), @@ -675,6 +685,9 @@ static Property spapr_phb_properties[] = { DEFINE_PROP_UINT64(mem_win_addr, sPAPRPHBState, mem_win_addr, -1), DEFINE_PROP_UINT64(mem_win_size, sPAPRPHBState, mem_win_size, SPAPR_PCI_MMIO_WIN_SIZE), +DEFINE_PROP_UINT64(mem64_win_addr, sPAPRPHBState, mem64_win_addr, -1), +DEFINE_PROP_UINT64(mem64_win_size, sPAPRPHBState, mem64_win_size, + SPAPR_PCI_MMIO64_WIN_SIZE), DEFINE_PROP_UINT64(io_win_addr, sPAPRPHBState, io_win_addr, -1), DEFINE_PROP_UINT64(io_win_size, sPAPRPHBState, io_win_size, SPAPR_PCI_IO_WIN_SIZE), @@ -878,6 +891,11 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, cpu_to_be64(phb-mem_win_addr), cpu_to_be64(memory_region_size(phb-memwindow)), }, +{ +cpu_to_be32(b_ss(3)), cpu_to_be64(SPAPR_PCI_MEM64_WIN_BUS_OFFSET), +cpu_to_be64(phb-mem64_win_addr), +cpu_to_be64(memory_region_size(phb-mem64window)), +}, }; uint64_t bus_reg[] = { cpu_to_be64(phb-buid), 0 }; uint32_t interrupt_map_mask[] = { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 4ea2a0d..4072f0d 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -70,7 +70,9 @@ struct sPAPRPHBState { MemoryRegion memspace, iospace; hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size; +hwaddr mem64_win_addr, mem64_win_size; MemoryRegion memwindow, iowindow, msiwindow; +MemoryRegion mem64window; uint32_t dma_liobn; AddressSpace iommu_as; @@ -96,16 +98,19 @@ struct sPAPRPHBVFIOState { #define SPAPR_PCI_BASE_BUID 0x8002000ULL -#define SPAPR_PCI_WINDOW_BASE0x100ULL -#define SPAPR_PCI_WINDOW_SPACING 0x10ULL -#define SPAPR_PCI_MMIO_WIN_OFF 0xA000 +#define SPAPR_PCI_WINDOW_BASE0x1000ULL +#define SPAPR_PCI_WINDOW_SPACING 0x1000ULL +#define SPAPR_PCI_MMIO_WIN_OFF 0x8000 #define SPAPR_PCI_MMIO_WIN_SIZE 0x2000 -#define SPAPR_PCI_IO_WIN_OFF 0x8000 +#define SPAPR_PCI_MMIO64_WIN_OFF 0x100ULL +#define
[Qemu-devel] [PATCH V2 2/3] spapr: Fix integer overflow during migration (TCG)
The n_valid and n_invalid fields are unsigned short integers but it is possible to have more than 65535 entries in a contiguous hunk, overflowing the field. This results in an incorrect HTAB being sent to the destination during migration. Signed-off-by: Samuel Mendoza-Jonas sam...@au1.ibm.com --- hw/ppc/spapr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index eb07343..10b7b00 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1045,7 +1045,7 @@ static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr, /* Consume valid HPTEs */ chunkstart = index; -while ((index htabslots) +while ((index htabslots) (index - chunkstart USHRT_MAX) HPTE_VALID(HPTE(spapr-htab, index))) { index++; CLEAN_HPTE(HPTE(spapr-htab, index)); @@ -1097,7 +1097,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, chunkstart = index; /* Consume valid dirty HPTEs */ -while ((index htabslots) +while ((index htabslots) (index - chunkstart USHRT_MAX) HPTE_DIRTY(HPTE(spapr-htab, index)) HPTE_VALID(HPTE(spapr-htab, index))) { CLEAN_HPTE(HPTE(spapr-htab, index)); @@ -1107,7 +1107,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, invalidstart = index; /* Consume invalid dirty HPTEs */ -while ((index htabslots) +while ((index htabslots) (index - invalidstart USHRT_MAX) HPTE_DIRTY(HPTE(spapr-htab, index)) !HPTE_VALID(HPTE(spapr-htab, index))) { CLEAN_HPTE(HPTE(spapr-htab, index)); -- 1.9.3
[Qemu-devel] [PATCH V2 0/3] spapr: Fix stale HTAB during live migration
If a spapr guest reboots during a live migration, the guest HTAB on the destination is not updated properly, usually resulting in a kernel panic. This is a (delayed!) follow up to my previous patch including a fix for TCG guests as well as KVM. Changes from V1: - Split out overflow fix into separate patch - Removed unnecessary locks (relevant operations occur under BQL) - TCG: Set HTAB dirty instead of resetting migration state - Minor style fixes Samuel Mendoza-Jonas (3): spapr: Fix stale HTAB during live migration (KVM) spapr: Fix integer overflow during migration (TCG) spapr: Fix stale HTAB during live migration (TCG) hw/ppc/spapr.c | 60 +++--- include/hw/ppc/spapr.h | 1 + 2 files changed, 53 insertions(+), 8 deletions(-) -- 1.9.3
[Qemu-devel] [PATCH V2 1/3] spapr: Fix stale HTAB during live migration (KVM)
If a guest reboots during a running migration, changes to the hash page table are not necessarily updated on the destination. Opening a new file descriptor to the HTAB forces the migration handler to resend the entire table. Signed-off-by: Samuel Mendoza-Jonas sam...@au1.ibm.com --- hw/ppc/spapr.c | 38 ++ include/hw/ppc/spapr.h | 1 + 2 files changed, 39 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0a2bfe6..eb07343 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -833,6 +833,11 @@ static void spapr_reset_htab(sPAPREnvironment *spapr) /* Kernel handles htab, we don't need to allocate one */ spapr-htab_shift = shift; kvmppc_kern_htab = true; + +/* Tell readers to update their file descriptor */ +if (spapr-htab_fd = 0) { +spapr-htab_fd_stale = true; +} } else { if (!spapr-htab) { /* Allocate an htab if we don't yet have one */ @@ -850,6 +855,28 @@ static void spapr_reset_htab(sPAPREnvironment *spapr) } } +/* + * A guest reset will cause spapr-htab_fd to become stale if being used. + * Reopen the file descriptor to make sure the whole HTAB is properly read. + */ +static int spapr_check_htab_fd(sPAPREnvironment *spapr) +{ +int rc = 0; + +if (spapr-htab_fd_stale) { +close(spapr-htab_fd); +spapr-htab_fd = kvmppc_get_htab_fd(false); +if (spapr-htab_fd 0) { +error_report(Unable to open fd for reading hash table from KVM: +%s, strerror(errno)); +rc = -1; +} +spapr-htab_fd_stale = false; +} + +return rc; +} + static void ppc_spapr_reset(void) { PowerPCCPU *first_ppc_cpu; @@ -985,6 +1012,7 @@ static int htab_save_setup(QEMUFile *f, void *opaque) assert(kvm_enabled()); spapr-htab_fd = kvmppc_get_htab_fd(false); +spapr-htab_fd_stale = false; if (spapr-htab_fd 0) { fprintf(stderr, Unable to open fd for reading hash table from KVM: %s\n, strerror(errno)); @@ -1137,6 +1165,11 @@ static int htab_save_iterate(QEMUFile *f, void *opaque) if (!spapr-htab) { assert(kvm_enabled()); +rc = spapr_check_htab_fd(spapr); +if (rc 0) { +return rc; +} + rc = kvmppc_save_htab(f, spapr-htab_fd, MAX_KVM_BUF_SIZE, MAX_ITERATION_NS); if (rc 0) { @@ -1168,6 +1201,11 @@ static int htab_save_complete(QEMUFile *f, void *opaque) assert(kvm_enabled()); +rc = spapr_check_htab_fd(spapr); +if (rc 0) { +return rc; +} + rc = kvmppc_save_htab(f, spapr-htab_fd, MAX_KVM_BUF_SIZE, -1); if (rc 0) { return rc; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 749daf4..716bff4 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -37,6 +37,7 @@ typedef struct sPAPREnvironment { int htab_save_index; bool htab_first_pass; int htab_fd; +bool htab_fd_stale; } sPAPREnvironment; #define H_SUCCESS 0 -- 1.9.3
[Qemu-devel] [PATCH V2 3/3] spapr: Fix stale HTAB during live migration (TCG)
If a TCG guest reboots during a running migration HTAB entries are not marked dirty, and the destination boots with an invalid HTAB. When a reboot occurs, explicitly mark the current HTAB dirty after clearing it. Signed-off-by: Samuel Mendoza-Jonas sam...@au1.ibm.com --- hw/ppc/spapr.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 10b7b00..c2efbcd 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -819,9 +819,16 @@ static void emulate_spapr_hypercall(PowerPCCPU *cpu) } } +#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2)) +#define HPTE_VALID(_hpte) (tswap64(*((uint64_t *)(_hpte))) HPTE64_V_VALID) +#define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) HPTE64_V_HPTE_DIRTY) +#define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) = tswap64(~HPTE64_V_HPTE_DIRTY)) +#define DIRTY_HPTE(_hpte) ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY)) + static void spapr_reset_htab(sPAPREnvironment *spapr) { long shift; +int index; /* allocate hash page table. For now we always make this 16mb, * later we should probably make it scale to the size of guest @@ -846,6 +853,10 @@ static void spapr_reset_htab(sPAPREnvironment *spapr) /* And clear it */ memset(spapr-htab, 0, HTAB_SIZE(spapr)); + +for (index = 0; index HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; index++) { +DIRTY_HPTE(HPTE(spapr-htab, index)); +} } /* Update the RMA size if necessary */ @@ -993,11 +1004,6 @@ static const VMStateDescription vmstate_spapr = { }, }; -#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2)) -#define HPTE_VALID(_hpte) (tswap64(*((uint64_t *)(_hpte))) HPTE64_V_VALID) -#define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) HPTE64_V_HPTE_DIRTY) -#define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) = tswap64(~HPTE64_V_HPTE_DIRTY)) - static int htab_save_setup(QEMUFile *f, void *opaque) { sPAPREnvironment *spapr = opaque; -- 1.9.3
[Qemu-devel] [PATCH Part1 0/5] Common unplug and unplug request cb for memory and CPU hot-unplug.
Memory and CPU hot unplug are both asynchronize procedures. When the unplug operation happens, unplug request cb is called first. And when ghest OS finished handling unplug, unplug cb will be called to do the real removal of device. They both need pc-machine, piix4 and ich9 unplug and unplug request cb. So this patch set introduces these commom functions as part1, and memory and CPU hot-unplug will come soon as part 2 and 3. Tang Chen (5): acpi, pc: Add hotunplug request cb for pc machine. acpi, ich9: Add hotunplug request cb for ich9. acpi, pc: Add unplug cb for pc machine. acpi, ich9: Add unplug cb for ich9. acpi, piix4: Add unplug cb for piix4. hw/acpi/ich9.c | 14 ++ hw/acpi/piix4.c| 8 hw/i386/pc.c | 16 hw/isa/lpc_ich9.c | 14 -- include/hw/acpi/ich9.h | 4 5 files changed, 54 insertions(+), 2 deletions(-) -- 1.8.4.2
[Qemu-devel] [PATCH Part1 1/5] acpi, pc: Add hotunplug request cb for pc machine.
Memory and CPU hot unplug are both asynchronize procedures. They both need unplug request cb when the unplug operation happens. This patch adds hotunplug request cb for pc machine, and memory and CPU hot unplug will base on it. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/i386/pc.c | 8 1 file changed, 8 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 1205db8..5c48435 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1647,6 +1647,13 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev, } } +static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, +DeviceState *dev, Error **errp) +{ +error_setg(errp, acpi: device unplug request for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} + static HotplugHandler *pc_get_hotpug_handler(MachineState *machine, DeviceState *dev) { @@ -1753,6 +1760,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) pcmc-get_hotplug_handler = mc-get_hotplug_handler; mc-get_hotplug_handler = pc_get_hotpug_handler; hc-plug = pc_machine_device_plug_cb; +hc-unplug_request = pc_machine_device_unplug_request_cb; } static const TypeInfo pc_machine_info = { -- 1.8.4.2
[Qemu-devel] [PATCH Part1 3/5] acpi, pc: Add unplug cb for pc machine.
Memory and CPU hot unplug are both asynchronize procedures. When the unplug operation happens, unplug request cb is called first. And when ghest OS finished handling unplug, unplug cb will be called to do the real removal of device. This patch adds hotunplug cb for pc machine, and memory and CPU hot unplug will base on it. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/i386/pc.c | 8 1 file changed, 8 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5c48435..d5073df 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1654,6 +1654,13 @@ static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, type: %s, object_get_typename(OBJECT(dev))); } +static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev, +DeviceState *dev, Error **errp) +{ +error_setg(errp, acpi: device unplug for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} + static HotplugHandler *pc_get_hotpug_handler(MachineState *machine, DeviceState *dev) { @@ -1761,6 +1768,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc-get_hotplug_handler = pc_get_hotpug_handler; hc-plug = pc_machine_device_plug_cb; hc-unplug_request = pc_machine_device_unplug_request_cb; +hc-unplug = pc_machine_device_unplug_cb; } static const TypeInfo pc_machine_info = { -- 1.8.4.2
[Qemu-devel] [PATCH Part1 5/5] acpi, piix4: Add unplug cb for piix4.
Memory and CPU hot unplug are both asynchronize procedures. When the unplug operation happens, unplug request cb is called first. And when ghest OS finished handling unplug, unplug cb will be called to do the real removal of device. This patch adds hotunplug cb for piix4, and memory and CPU hot unplug will base on it. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/piix4.c | 8 1 file changed, 8 insertions(+) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 78c0a6d..353f91a 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -369,6 +369,13 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, } } +static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ +error_setg(errp, acpi: device unplug for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} + static void piix4_update_bus_hotplug(PCIBus *pci_bus, void *opaque) { PIIX4PMState *s = opaque; @@ -606,6 +613,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data) dc-hotpluggable = false; hc-plug = piix4_device_plug_cb; hc-unplug_request = piix4_device_unplug_request_cb; +hc-unplug = piix4_device_unplug_cb; adevc-ospm_status = piix4_ospm_status; } -- 1.8.4.2
[Qemu-devel] [PATCH Part1 4/5] acpi, ich9: Add unplug cb for ich9.
Memory and CPU hot unplug are both asynchronize procedures. When the unplug operation happens, unplug request cb is called first. And when ghest OS finished handling unplug, unplug cb will be called to do the real removal of device. This patch adds hotunplug cb for ich9, and memory and CPU hot unplug will base on it. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/ich9.c | 7 +++ hw/isa/lpc_ich9.c | 9 + include/hw/acpi/ich9.h | 2 ++ 3 files changed, 18 insertions(+) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 5ce3aaf..c48d176 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -308,6 +308,13 @@ void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, type: %s, object_get_typename(OBJECT(dev))); } +void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, + Error **errp) +{ +error_setg(errp, acpi: device unplug for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} + void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) { ICH9LPCState *s = ICH9_LPC_DEVICE(adev); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index d00b223..16f5a0d 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -615,6 +615,14 @@ static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev, ich9_pm_device_unplug_request_cb(lpc-pm, dev, errp); } +static void ich9_device_unplug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ +ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + +ich9_pm_device_unplug_cb(lpc-pm, dev, errp); +} + static bool ich9_rst_cnt_needed(void *opaque) { ICH9LPCState *lpc = opaque; @@ -678,6 +686,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data) dc-cannot_instantiate_with_device_add_yet = true; hc-plug = ich9_device_plug_cb; hc-unplug_request = ich9_device_unplug_request_cb; +hc-unplug = ich9_device_unplug_cb; adevc-ospm_status = ich9_pm_ospm_status; } diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 86853c3..fc87dad 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -61,6 +61,8 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp); void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp); void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp); +void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, + Error **errp); void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); #endif /* HW_ACPI_ICH9_H */ -- 1.8.4.2
[Qemu-devel] [PATCH Part1 2/5] acpi, ich9: Add hotunplug request cb for ich9.
Memory and CPU hot unplug are both asynchronize procedures. They both need unplug request cb when the unplug operation happens. This patch adds hotunplug request cb for ich9, and memory and CPU hot unplug will base on it. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/ich9.c | 7 +++ hw/isa/lpc_ich9.c | 5 +++-- include/hw/acpi/ich9.h | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index ea991a3..5ce3aaf 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -301,6 +301,13 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) } } +void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, + Error **errp) +{ +error_setg(errp, acpi: device unplug request for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} + void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) { ICH9LPCState *s = ICH9_LPC_DEVICE(adev); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 530b074..d00b223 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -610,8 +610,9 @@ static void ich9_device_plug_cb(HotplugHandler *hotplug_dev, static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { -error_setg(errp, acpi: device unplug request for not supported device -type: %s, object_get_typename(OBJECT(dev))); +ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + +ich9_pm_device_unplug_request_cb(lpc-pm, dev, errp); } static bool ich9_rst_cnt_needed(void *opaque) diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index fe975e6..86853c3 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -59,6 +59,8 @@ extern const VMStateDescription vmstate_ich9_pm; void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp); void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp); +void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, + Error **errp); void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); #endif /* HW_ACPI_ICH9_H */ -- 1.8.4.2
[Qemu-devel] [PATCH Part2 02/13] acpi, mem-hotplug: Add acpi_memory_get_slot_status_descriptor() to get MemStatus.
Add a new API named acpi_memory_get_slot_status_descriptor() to obtain a single memory slot status. Doing this is because this procedure will be used by other functions in the next coming patches. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/memory_hotplug.c | 27 +++ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index c6580da..ef56bf6 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -163,29 +163,40 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner, memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, state-io); } -void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, - DeviceState *dev, Error **errp) +static MemStatus * +acpi_memory_get_slot_status_descriptor(MemHotplugState *mem_st, + DeviceState *dev, Error **errp) { -MemStatus *mdev; Error *local_err = NULL; int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, local_err); if (local_err) { error_propagate(errp, local_err); -return; +return NULL; } if (slot = mem_st-dev_count) { char *dev_path = object_get_canonical_path(OBJECT(dev)); -error_setg(errp, acpi_memory_plug_cb: +error_setg(errp, acpi_memory_get_slot_status_descriptor: device [%s] returned invalid memory slot[%d], -dev_path, slot); + dev_path, slot); g_free(dev_path); -return; +return NULL; } -mdev = mem_st-devs[slot]; +return mem_st-devs[slot]; +} + +void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, + DeviceState *dev, Error **errp) +{ +MemStatus *mdev; + +mdev = acpi_memory_get_slot_status_descriptor(mem_st, dev, errp); +if (!mdev) +return; + mdev-dimm = dev; mdev-is_enabled = true; mdev-is_inserting = true; -- 1.8.4.2
[Qemu-devel] [PATCH Part2 04/13] acpi, mem-hotplug: Add unplug request cb for memory device.
Memory hot unplug are both asynchronize procedures. When the unplug operation happens, unplug request cb is called first. And when ghest OS finished handling unplug, unplug cb will be called to do the real removal of device. This patch adds unplug request cb for memory device. Add a new bool member named is_removing to MemStatus indicating that the memory slot is being removed. Set it to true in acpi_memory_unplug_request_cb(), and send SCI to guest. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/memory_hotplug.c | 16 include/hw/acpi/memory_hotplug.h | 4 2 files changed, 20 insertions(+) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index 9839963..3d8e398 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -211,6 +211,22 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, acpi_memory_hotplug_sci(ar, irq); } +void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, + MemHotplugState *mem_st, + DeviceState *dev, Error **errp) +{ +MemStatus *mdev; + +mdev = acpi_memory_get_slot_status_descriptor(mem_st, dev, errp); +if (!mdev) +return; + +mdev-is_removing = true; + +/* Do ACPI magic */ +acpi_memory_hotplug_sci(ar, irq); +} + static const VMStateDescription vmstate_memhp_sts = { .name = memory hotplug device state, .version_id = 1, diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h index 7bbf8a0..c437a85 100644 --- a/include/hw/acpi/memory_hotplug.h +++ b/include/hw/acpi/memory_hotplug.h @@ -11,6 +11,7 @@ typedef struct MemStatus { DeviceState *dimm; bool is_enabled; bool is_inserting; +bool is_removing; uint32_t ost_event; uint32_t ost_status; } MemStatus; @@ -28,6 +29,9 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner, void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, DeviceState *dev, Error **errp); +void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, + MemHotplugState *mem_st, + DeviceState *dev, Error **errp); extern const VMStateDescription vmstate_memory_hotplug; #define VMSTATE_MEMORY_HOTPLUG(memhp, state) \ -- 1.8.4.2
[Qemu-devel] [PATCH Part2 00/13] QEmu memory hot unplug support.
Memory hot unplug are both asynchronize procedures. When the unplug operation happens, unplug request cb is called first. And when ghest OS finished handling unplug, unplug cb will be called to do the real removal of device. Hu Tao (2): acpi, piix4: Add memory hot unplug request support for piix4. pc, acpi bios: Add memory hot unplug interface. Tang Chen (11): acpi, mem-hotplug: Use PC_DIMM_SLOT_PROP in acpi_memory_plug_cb(). acpi, mem-hotplug: Add acpi_memory_get_slot_status_descriptor() to get MemStatus. acpi, mem-hotplug: Add acpi_memory_hotplug_sci() to rise sci for memory hotplug. acpi, mem-hotplug: Add unplug request cb for memory device. acpi, ich9: Add memory hot unplug request support for ich9. pc-dimm: Add memory hot unplug request support for pc-dimm. acpi, mem-hotplug: Add unplug cb for memory device. acpi, piix4: Add memory hot unplug support for piix4. acpi, ich9: Add memory hot unplug support for ich9. pc-dimm: Add memory hot unplug support for pc-dimm. acpi: Add hardware implementation for memory hot unplug. docs/specs/acpi_mem_hotplug.txt | 8 +++- hw/acpi/ich9.c | 20 +++-- hw/acpi/memory_hotplug.c | 97 +--- hw/acpi/piix4.c | 18 ++-- hw/core/qdev.c | 2 +- hw/i386/pc.c | 53 -- hw/i386/ssdt-mem.dsl | 5 +++ hw/i386/ssdt-misc.dsl| 13 +- include/hw/acpi/memory_hotplug.h | 6 +++ include/hw/acpi/pc-hotplug.h | 2 + include/hw/qdev-core.h | 1 + 11 files changed, 194 insertions(+), 31 deletions(-) -- 1.8.4.2
[Qemu-devel] [PATCH Part2 11/13] pc-dimm: Add memory hot unplug support for pc-dimm.
Implement unplug cb for pc-dimm. It remove the corresponding memory region, and unregister vmstat. At last, it calls memory unplug cb to reset memory status and do unparenting. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/i386/pc.c | 25 +++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index eacf290..d4450cb 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1628,6 +1628,23 @@ out: error_propagate(errp, local_err); } +static void pc_dimm_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ +PCMachineState *pcms = PC_MACHINE(hotplug_dev); +PCDIMMDevice *dimm = PC_DIMM(dev); +PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); +MemoryRegion *mr = ddc-get_memory_region(dimm); +HotplugHandlerClass *hhc; +Error *local_err = NULL; + +memory_region_del_subregion(pcms-hotplug_memory, mr); +vmstate_unregister_ram(mr, dev); + +hhc = HOTPLUG_HANDLER_GET_CLASS(pcms-acpi_dev); +hhc-unplug(HOTPLUG_HANDLER(pcms-acpi_dev), dev, local_err); +} + static void pc_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -1681,8 +1698,12 @@ static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { -error_setg(errp, acpi: device unplug for not supported device -type: %s, object_get_typename(OBJECT(dev))); +if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { +pc_dimm_unplug(hotplug_dev, dev, errp); +} else { +error_setg(errp, acpi: device unplug for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} } static HotplugHandler *pc_get_hotpug_handler(MachineState *machine, -- 1.8.4.2
[Qemu-devel] [PATCH Part2 03/13] acpi, mem-hotplug: Add acpi_memory_hotplug_sci() to rise sci for memory hotplug.
Add a new API named acpi_memory_hotplug_sci() to send memory hotplug SCI. Doing this is because this procedure will be used by other functions in the next coming patches. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/memory_hotplug.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index ef56bf6..9839963 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -188,6 +188,12 @@ acpi_memory_get_slot_status_descriptor(MemHotplugState *mem_st, return mem_st-devs[slot]; } +static void acpi_memory_hotplug_sci(ACPIREGS *ar, qemu_irq irq) +{ +ar-gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS; +acpi_update_sci(ar, irq); +} + void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, DeviceState *dev, Error **errp) { @@ -201,10 +207,8 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, mdev-is_enabled = true; mdev-is_inserting = true; -/* do ACPI magic */ -ar-gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS; -acpi_update_sci(ar, irq); -return; +/* Do ACPI magic */ +acpi_memory_hotplug_sci(ar, irq); } static const VMStateDescription vmstate_memhp_sts = { -- 1.8.4.2
[Qemu-devel] [PATCH Part2 05/13] acpi, piix4: Add memory hot unplug request support for piix4.
From: Hu Tao hu...@cn.fujitsu.com Call memory unplug request cb in piix4_device_unplug_request_cb(). Signed-off-by: Hu Tao hu...@cn.fujitsu.com Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/piix4.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 353f91a..6c7dff9 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -360,7 +360,11 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, { PIIX4PMState *s = PIIX4_PM(hotplug_dev); -if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { +if (s-acpi_memory_hotplug.is_enabled +object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { +acpi_memory_unplug_request_cb(s-ar, s-irq, s-acpi_memory_hotplug, + dev, errp); +} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { acpi_pcihp_device_unplug_cb(s-ar, s-irq, s-acpi_pci_hotplug, dev, errp); } else { -- 1.8.4.2
[Qemu-devel] [PATCH Part2 10/13] acpi, ich9: Add memory hot unplug support for ich9.
Call memory unplug cb in ich9_pm_device_unplug_cb(). Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/ich9.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 841f57d..691299f 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -317,8 +317,14 @@ void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) { -error_setg(errp, acpi: device unplug for not supported device -type: %s, object_get_typename(OBJECT(dev))); +if (pm-acpi_memory_hotplug.is_enabled +object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { +acpi_memory_unplug_request_cb(pm-acpi_regs, pm-irq, + pm-acpi_memory_hotplug, dev, errp); +} else { +error_setg(errp, acpi: device unplug for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} } void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) -- 1.8.4.2
[Qemu-devel] [PATCH Part2 01/13] acpi, mem-hotplug: Use PC_DIMM_SLOT_PROP in acpi_memory_plug_cb().
Replace string slot in acpi_memory_plug_cb() with MACRO PC_DIMM_SLOT_PROP. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/memory_hotplug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index ed39241..c6580da 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -168,7 +168,8 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, { MemStatus *mdev; Error *local_err = NULL; -int slot = object_property_get_int(OBJECT(dev), slot, local_err); +int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, + local_err); if (local_err) { error_propagate(errp, local_err); -- 1.8.4.2
[Qemu-devel] [PATCH Part2 06/13] acpi, ich9: Add memory hot unplug request support for ich9.
Call memory unplug request cb in ich9_pm_device_unplug_request_cb(). Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/ich9.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index c48d176..841f57d 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -304,8 +304,14 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) { -error_setg(errp, acpi: device unplug request for not supported device -type: %s, object_get_typename(OBJECT(dev))); +if (pm-acpi_memory_hotplug.is_enabled +object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { +acpi_memory_unplug_request_cb(pm-acpi_regs, pm-irq, + pm-acpi_memory_hotplug, dev, errp); +} else { +error_setg(errp, acpi: device unplug request for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} } void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, -- 1.8.4.2
[Qemu-devel] [PATCH v2 2/3] virtio-balloon: Fix balloon not working correctly when hotplug memory
When do memory balloon, it takes the 'ram_size' as the VM's current ram size, But 'ram_size' is the startup configured ram size, it does not take into account the hotplugged memory. As a result, the balloon result will be confused. Steps to reproduce: (1)Start VM: qemu -m size=1024,slots=4,maxmem=8G (2)In VM: #free -m : 1024M (3)qmp balloon 512M (4)In VM: #free -m : 512M (5)hotplug pc-dimm 1G (6)In VM: #free -m : 1512M (7)qmp balloon 256M (8)In VM: #free -m :1256M We expect the VM's available ram size to be 256M after 'qmp balloon 256M' command, but VM's real available ram size is 1256M. For qmp balloon is not performance critical code, we use function 'get_current_ram_size' to get VM's current ram size. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- hw/virtio/virtio-balloon.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 7bfbb75..41b24c9 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -294,10 +294,12 @@ static void virtio_balloon_set_config(VirtIODevice *vdev, VirtIOBalloon *dev = VIRTIO_BALLOON(vdev); struct virtio_balloon_config config; uint32_t oldactual = dev-actual; +ram_addr_t vm_ram_size = get_current_ram_size(); + memcpy(config, config_data, sizeof(struct virtio_balloon_config)); dev-actual = le32_to_cpu(config.actual); if (dev-actual != oldactual) { -qapi_event_send_balloon_change(ram_size - +qapi_event_send_balloon_change(vm_ram_size - ((ram_addr_t) dev-actual VIRTIO_BALLOON_PFN_SHIFT), error_abort); } @@ -312,20 +314,21 @@ static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f) static void virtio_balloon_stat(void *opaque, BalloonInfo *info) { VirtIOBalloon *dev = opaque; -info-actual = ram_size - ((uint64_t) dev-actual - VIRTIO_BALLOON_PFN_SHIFT); +info-actual = get_current_ram_size() - ((uint64_t) dev-actual + VIRTIO_BALLOON_PFN_SHIFT); } static void virtio_balloon_to_target(void *opaque, ram_addr_t target) { VirtIOBalloon *dev = VIRTIO_BALLOON(opaque); VirtIODevice *vdev = VIRTIO_DEVICE(dev); +ram_addr_t vm_ram_size = get_current_ram_size(); -if (target ram_size) { -target = ram_size; +if (target vm_ram_size) { +target = vm_ram_size; } if (target) { -dev-num_pages = (ram_size - target) VIRTIO_BALLOON_PFN_SHIFT; +dev-num_pages = (vm_ram_size - target) VIRTIO_BALLOON_PFN_SHIFT; virtio_notify_config(vdev); } } -- 1.7.12.4
[Qemu-devel] [PATCH Part2 12/13] acpi: Add hardware implementation for memory hot unplug.
This patch adds a new bit to memory hotplug IO port indicating that ej0 has been evaluated by guest OS. And call pc-dimm unplug cb to do the real removal. Signed-off-by: Hu Tao hu...@cn.fujitsu.com Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- docs/specs/acpi_mem_hotplug.txt | 8 ++-- hw/acpi/memory_hotplug.c| 23 --- hw/core/qdev.c | 2 +- include/hw/qdev-core.h | 1 + 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt index 1290994..28a1ffa 100644 --- a/docs/specs/acpi_mem_hotplug.txt +++ b/docs/specs/acpi_mem_hotplug.txt @@ -19,7 +19,9 @@ Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access): 1: Device insert event, used to distinguish device for which no device check event to OSPM was issued. It's valid only when bit 1 is set. - 2-7: reserved and should be ignored by OSPM + 2: Device remove event, used to indicate that device is being +removed. + 3-7: reserved and should be ignored by OSPM [0x15-0x17] reserved write access: @@ -35,7 +37,9 @@ Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access): 1: if set to 1 clears device insert event, set by OSPM after it has emitted device check event for the selected memory device - 2-7: reserved, OSPM must clear them before writing to register + 2: set by hardware after it has emitted device eject event for +selected memory device + 3-7: reserved, OSPM must clear them before writing to register Selecting memory device slot beyond present range has no effect on platform: - write accesses to memory hot-plug registers not documented above are diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index 2b0c8ca..b9e8752 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -2,6 +2,7 @@ #include hw/acpi/pc-hotplug.h #include hw/mem/pc-dimm.h #include hw/boards.h +#include hw/qdev-core.h #include trace.h #include qapi-event.h @@ -75,6 +76,7 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr, case 0x14: /* pack and return is_* fields */ val |= mdev-is_enabled ? 1 : 0; val |= mdev-is_inserting ? 2 : 0; +val |= mdev-is_removing ? 4 : 0; trace_mhp_acpi_read_flags(mem_st-selector, val); break; default: @@ -90,6 +92,8 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, MemHotplugState *mem_st = opaque; MemStatus *mdev; ACPIOSTInfo *info; +DeviceState *dev = NULL; +HotplugHandler *hotplug_ctrl = NULL; if (!mem_st-dev_count) { return; @@ -121,21 +125,34 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, mdev = mem_st-devs[mem_st-selector]; mdev-ost_status = data; trace_mhp_acpi_write_ost_status(mem_st-selector, mdev-ost_status); -/* TODO: implement memory removal on guest signal */ info = acpi_memory_device_status(mem_st-selector, mdev); qapi_event_send_acpi_device_ost(info, error_abort); qapi_free_ACPIOSTInfo(info); break; -case 0x14: +case 0x14: /* set is_* fields */ mdev = mem_st-devs[mem_st-selector]; + if (data 2) { /* clear insert event */ mdev-is_inserting = false; trace_mhp_acpi_clear_insert_evt(mem_st-selector); +} else if (data 4) { /* request removal of device */ +/* + * QEmu memory hot unplug is an asynchronized procedure. QEmu first + * calls pc-dimm unplug request cb to send a SCI to guest. When the + * Guest OS finished handling the SCI, it evaluates ACPI ej0, and + * QEmu calls pc-dimm unplug cb to remove memory device. + */ +dev = DEVICE(mdev-dimm); +hotplug_ctrl = qdev_get_hotplug_handler(dev); +/* Call pc-dimm unplug cb. */ +hotplug_handler_unplug(hotplug_ctrl, dev, NULL); } + +break; +default: break; } - } static const MemoryRegionOps acpi_memory_hotplug_ops = { .read = acpi_memory_hotplug_read, diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 413b413..12a3557 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -223,7 +223,7 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, dev-alias_required_for_version = required_for_version; } -static HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev) +HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev) { HotplugHandler *hotplug_ctrl = NULL; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index d3a2940..128fcfc 100644 --- a/include/hw/qdev-core.h +++
[Qemu-devel] [PATCH Part2 07/13] pc-dimm: Add memory hot unplug request support for pc-dimm.
Implement memory unplug request cb for pc-dimm, and call it in pc_machine_device_unplug_request_cb(). Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/i386/pc.c | 28 ++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index d5073df..eacf290 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1608,6 +1608,26 @@ out: error_propagate(errp, local_err); } +static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ +HotplugHandlerClass *hhc; +Error *local_err = NULL; +PCMachineState *pcms = PC_MACHINE(hotplug_dev); + +if (!pcms-acpi_dev) { +error_setg(local_err, + memory hotplug is not enabled: missing acpi device); + goto out; +} + +hhc = HOTPLUG_HANDLER_GET_CLASS(pcms-acpi_dev); +hhc-unplug_request(HOTPLUG_HANDLER(pcms-acpi_dev), dev, local_err); + +out: +error_propagate(errp, local_err); +} + static void pc_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -1650,8 +1670,12 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev, static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { -error_setg(errp, acpi: device unplug request for not supported device -type: %s, object_get_typename(OBJECT(dev))); +if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { +pc_dimm_unplug_request(hotplug_dev, dev, errp); +} else { +error_setg(errp, acpi: device unplug request for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} } static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev, -- 1.8.4.2
[Qemu-devel] [PATCH Part2 08/13] acpi, mem-hotplug: Add unplug cb for memory device.
Reset all memory status, and unparent the memory device. Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/memory_hotplug.c | 16 include/hw/acpi/memory_hotplug.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index 3d8e398..2b0c8ca 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -227,6 +227,22 @@ void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, acpi_memory_hotplug_sci(ar, irq); } +void acpi_memory_unplug_cb(ACPIREGS *ar, qemu_irq irq, + MemHotplugState *mem_st, + DeviceState *dev, Error **errp) +{ +MemStatus *mdev; + +mdev = acpi_memory_get_slot_status_descriptor(mem_st, dev, errp); +if (!mdev) +return; + +mdev-is_removing = false; +mdev-is_enabled = false; +object_unparent(OBJECT(mdev-dimm)); +mdev-dimm = NULL; +} + static const VMStateDescription vmstate_memhp_sts = { .name = memory hotplug device state, .version_id = 1, diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h index c437a85..6b8d9f7 100644 --- a/include/hw/acpi/memory_hotplug.h +++ b/include/hw/acpi/memory_hotplug.h @@ -32,6 +32,8 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, DeviceState *dev, Error **errp); +void acpi_memory_unplug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, + DeviceState *dev, Error **errp); extern const VMStateDescription vmstate_memory_hotplug; #define VMSTATE_MEMORY_HOTPLUG(memhp, state) \ -- 1.8.4.2
[Qemu-devel] [PATCH Part2 13/13] pc, acpi bios: Add memory hot unplug interface.
From: Hu Tao hu...@cn.fujitsu.com This patch implements MEMORY_SLOT_EJECT_METHOD according to ACPI spec. Signed-off-by: Hu Tao hu...@cn.fujitsu.com Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/i386/ssdt-mem.dsl | 5 + hw/i386/ssdt-misc.dsl| 13 - include/hw/acpi/pc-hotplug.h | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/hw/i386/ssdt-mem.dsl b/hw/i386/ssdt-mem.dsl index 22ff5dd..1416639 100644 --- a/hw/i386/ssdt-mem.dsl +++ b/hw/i386/ssdt-mem.dsl @@ -43,6 +43,7 @@ DefinitionBlock (ssdt-mem.aml, SSDT, 0x02, BXPC, CSSDT, 0x1) External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD, MethodObj) External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_OST_METHOD, MethodObj) External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD, MethodObj) +External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_EJECT_METHOD, MethodObj) Scope(\_SB) { /* v-- DO NOT EDIT --v */ @@ -72,6 +73,10 @@ DefinitionBlock (ssdt-mem.aml, SSDT, 0x02, BXPC, CSSDT, 0x1) Method(_OST, 3) { \_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_OST_METHOD(_UID, Arg0, Arg1, Arg2) } + +Method(_EJ0, 1) { +\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_EJECT_METHOD(_UID, Arg0) +} } } } diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl index 0fd4480..7b29539 100644 --- a/hw/i386/ssdt-misc.dsl +++ b/hw/i386/ssdt-misc.dsl @@ -156,6 +156,7 @@ DefinitionBlock (ssdt-misc.aml, SSDT, 0x01, BXPC, BXSSDTSUSP, 0x1) Offset(20), MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event +MEMORY_SLOT_REMOVE_EVENT, 1, // 1 if DIMM has a remove request, read only } Mutex (MEMORY_SLOT_LOCK, 0) @@ -174,11 +175,14 @@ DefinitionBlock (ssdt-misc.aml, SSDT, 0x01, BXPC, BXSSDTSUSP, 0x1) Acquire(MEMORY_SLOT_LOCK, 0x) while (LLess(Local0, MEMORY_SLOTS_NUMBER)) { Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM + If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check MEMORY_SLOT_NOTIFY_METHOD(Local0, 1) Store(1, MEMORY_SLOT_INSERT_EVENT) +} Elseif (LEqual(MEMORY_SLOT_REMOVE_EVENT, One)) { // Ejection request +MEMORY_SLOT_NOTIFY_METHOD(Local0, 3) } -// TODO: handle memory eject request + Add(Local0, One, Local0) // goto next DIMM } Release(MEMORY_SLOT_LOCK) @@ -278,6 +282,13 @@ DefinitionBlock (ssdt-misc.aml, SSDT, 0x01, BXPC, BXSSDTSUSP, 0x1) Store(Arg2, MEMORY_SLOT_OST_STATUS) Release(MEMORY_SLOT_LOCK) } + +Method(MEMORY_SLOT_EJECT_METHOD, 2) { +Acquire(MEMORY_SLOT_LOCK, 0x) +Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM +Store(One, MEMORY_SLOT_REMOVE_EVENT) +Release(MEMORY_SLOT_LOCK) +} } // Device() } // Scope() } diff --git a/include/hw/acpi/pc-hotplug.h b/include/hw/acpi/pc-hotplug.h index b9db295..b61b6ea 100644 --- a/include/hw/acpi/pc-hotplug.h +++ b/include/hw/acpi/pc-hotplug.h @@ -42,6 +42,7 @@ #define MEMORY_SLOT_PROXIMITYMPX #define MEMORY_SLOT_ENABLED MES #define MEMORY_SLOT_INSERT_EVENT MINS +#define MEMORY_SLOT_REMOVE_EVENT MRMV #define MEMORY_SLOT_SLECTOR MSEL #define MEMORY_SLOT_OST_EVENTMOEV #define MEMORY_SLOT_OST_STATUS MOSC @@ -50,6 +51,7 @@ #define MEMORY_SLOT_CRS_METHOD MCRS #define MEMORY_SLOT_OST_METHOD MOST #define MEMORY_SLOT_PROXIMITY_METHOD MPXM +#define MEMORY_SLOT_EJECT_METHOD MEJ0 #define MEMORY_SLOT_NOTIFY_METHODMTFY #define MEMORY_SLOT_SCAN_METHOD MSCN -- 1.8.4.2
[Qemu-devel] [PATCH Part2 09/13] acpi, piix4: Add memory hot unplug support for piix4.
Call memory unplug cb in piix4_device_unplug_cb(). Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/piix4.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 6c7dff9..440c9e8 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -376,8 +376,16 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { -error_setg(errp, acpi: device unplug for not supported device -type: %s, object_get_typename(OBJECT(dev))); +PIIX4PMState *s = PIIX4_PM(hotplug_dev); + +if (s-acpi_memory_hotplug.is_enabled +object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { +acpi_memory_unplug_cb(s-ar, s-irq, s-acpi_memory_hotplug, + dev, errp); +} else { +error_setg(errp, acpi: device unplug for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} } static void piix4_update_bus_hotplug(PCIBus *pci_bus, void *opaque) -- 1.8.4.2
[Qemu-devel] [PATCH v2 3/3] virtio-balloon: Add some trace events
Add some trace events for easier debugging Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- hw/virtio/virtio-balloon.c | 6 ++ trace-events | 4 2 files changed, 10 insertions(+) diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 41b24c9..8a48d2a 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -25,6 +25,7 @@ #include exec/address-spaces.h #include qapi/visitor.h #include qapi-event.h +#include trace.h #if defined(__linux__) #include sys/mman.h @@ -222,6 +223,8 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) if (!int128_nz(section.size) || !memory_region_is_ram(section.mr)) continue; +trace_virtio_balloon_handle_output(memory_region_name(section.mr), + pa); /* Using memory_region_get_ram_ptr is bending the rules a bit, but should be OK because we only want a single page. */ addr = section.offset_within_region; @@ -285,6 +288,7 @@ static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data) config.num_pages = cpu_to_le32(dev-num_pages); config.actual = cpu_to_le32(dev-actual); +trace_virtio_balloon_get_config(config.num_pages, config.actual); memcpy(config_data, config, sizeof(struct virtio_balloon_config)); } @@ -303,6 +307,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev, ((ram_addr_t) dev-actual VIRTIO_BALLOON_PFN_SHIFT), error_abort); } +trace_virtio_balloon_set_config(dev-actual, oldactual); } static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f) @@ -331,6 +336,7 @@ static void virtio_balloon_to_target(void *opaque, ram_addr_t target) dev-num_pages = (vm_ram_size - target) VIRTIO_BALLOON_PFN_SHIFT; virtio_notify_config(vdev); } +trace_virtio_balloon_to_target(target, dev-num_pages); } static void virtio_balloon_save(QEMUFile *f, void *opaque) diff --git a/trace-events b/trace-events index b5722ea..bba5be8 100644 --- a/trace-events +++ b/trace-events @@ -142,6 +142,10 @@ cpu_out(unsigned int addr, unsigned int val) addr %#x value %u # balloon.c # Since requests are raised via monitor, not many tracepoints are needed. balloon_event(void *opaque, unsigned long addr) opaque %p addr %lu +virtio_balloon_handle_output(const char *name, uint64_t gpa) setion name: %s gpa: %PRIx64 +virtio_balloon_get_config(uint32_t num_pages, uint32_t acutal) num_pages: %d acutal: %d +virtio_balloon_set_config(uint32_t acutal, uint32_t oldacutal) acutal: %d oldacutal: %d +virtio_balloon_to_target(uint64_t target, uint32_t num_pages) balloon target: %PRIx64 num_pages: %d # hw/intc/apic_common.c cpu_set_apic_base(uint64_t val) %016PRIx64 -- 1.7.12.4
[Qemu-devel] [PATCH v2 0/3] fix bug about balloon working incorrectly when hotplug memeory
Hi, Patch 1 and 2 mainly fix bug about balloon not working correctly when we do hotplug memory. It takes 'ram_size' as VM's real RAM size which is wrong after we hotplug memory. This bug exists since we begin to support hotplug memory, and it is better to fix it. Patch 3 add some trace events, it helps debugging balloon. If it is unnecessary, pls feel free to remove it. Thanks, zhanghailiang v2: - fix compiling break for other targets that don't support pc-dimm zhanghailiang (3): pc-dimm: add a function to calculate VM's current RAM size virtio-balloon: Fix balloon not working correctly when hotplug memory virtio-balloon: Add some trace events hw/mem/pc-dimm.c| 26 ++ hw/virtio/virtio-balloon.c | 21 +++-- include/exec/cpu-common.h | 1 + stubs/qmp_pc_dimm_device_list.c | 5 + trace-events| 4 5 files changed, 51 insertions(+), 6 deletions(-) -- 1.7.12.4
[Qemu-devel] [PATCH v2 1/3] pc-dimm: add a function to calculate VM's current RAM size
The global parameter 'ram_size' does not take into account the hotplugged memory. In some codes, we use 'ram_size' as current VM's real RAM size, which is not correct. Add function 'get_current_ram_size' to calculate VM's current RAM size, it will enumerate present memory devices and also plus ram_size. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- hw/mem/pc-dimm.c| 26 ++ include/exec/cpu-common.h | 1 + stubs/qmp_pc_dimm_device_list.c | 5 + 3 files changed, 32 insertions(+) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index a800ea7..38465d0 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -62,6 +62,32 @@ int qmp_pc_dimm_device_list(Object *obj, void *opaque) return 0; } +ram_addr_t get_current_ram_size(void) +{ +MemoryDeviceInfoList *info_list = NULL; +MemoryDeviceInfoList **prev = info_list; +MemoryDeviceInfoList *info; +ram_addr_t size = ram_size; + +qmp_pc_dimm_device_list(qdev_get_machine(), prev); +for (info = info_list; info; info = info-next) { +MemoryDeviceInfo *value = info-value; + +if (value) { +switch (value-kind) { +case MEMORY_DEVICE_INFO_KIND_DIMM: +size += value-dimm-size; +break; +default: +break; +} +} +} +qapi_free_MemoryDeviceInfoList(info_list); + +return size; +} + static int pc_dimm_slot2bitmap(Object *obj, void *opaque) { unsigned long *bitmap = opaque; diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 427b851..fcc3162 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -52,6 +52,7 @@ typedef uintptr_t ram_addr_t; #endif extern ram_addr_t ram_size; +ram_addr_t get_current_ram_size(void); /* memory API */ diff --git a/stubs/qmp_pc_dimm_device_list.c b/stubs/qmp_pc_dimm_device_list.c index 5cb220c..b584bd8 100644 --- a/stubs/qmp_pc_dimm_device_list.c +++ b/stubs/qmp_pc_dimm_device_list.c @@ -5,3 +5,8 @@ int qmp_pc_dimm_device_list(Object *obj, void *opaque) { return 0; } + +ram_addr_t get_current_ram_size(void) +{ +return ram_size; +} -- 1.7.12.4
Re: [Qemu-devel] [PATCH] l2tpv3: fix possible double free
On 2014/11/14 16:45, Paolo Bonzini wrote: On 14/11/2014 02:39, zhanghailiang wrote: freeaddrinfo(result) does not assign result = NULL, after frees it. There will be a double free when it goes error case. It is reported by covertiy. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- net/l2tpv3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/l2tpv3.c b/net/l2tpv3.c index 528d95b..f9e0c98 100644 --- a/net/l2tpv3.c +++ b/net/l2tpv3.c @@ -661,6 +661,7 @@ int net_init_l2tpv3(const NetClientOptions *opts, fd = -errno; error_report(l2tpv3_open : socket creation failed, errno = %d, -fd); freeaddrinfo(result); +result = NULL; You can just remove the call to freeaddrinfo(). I made the change and applied the patch. This is a better choice ;) Thanks. goto outerr; } if (bind(fd, (struct sockaddr *) result-ai_addr, result-ai_addrlen)) {
Re: [Qemu-devel] [PATCH v2] libcacard: fix resource leak
On 2014/11/14 17:29, Markus Armbruster wrote: zhanghailiang zhang.zhanghaili...@huawei.com writes: In function connect_to_qemu(), getaddrinfo() will allocate memory that is stored into server, it should be freed by using freeaddrinfo() before connect_to_qemu() return. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- v2: - fix typo in title ;) --- libcacard/vscclient.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c index 80111df..fa6041d 100644 --- a/libcacard/vscclient.c +++ b/libcacard/vscclient.c @@ -597,7 +597,7 @@ connect_to_qemu( const char *port ) { struct addrinfo hints; -struct addrinfo *server; +struct addrinfo *server = NULL; int ret, sock; sock = socket(AF_INET, SOCK_STREAM, 0); @@ -629,9 +629,14 @@ connect_to_qemu( if (verbose) { printf(Connected (sizeof Header=%zd)!\n, sizeof(VSCMsgHeader)); } + +freeaddrinfo(server); return sock; cleanup_socket: +if (server) { +freeaddrinfo(server); +} closesocket(sock); return -1; } Reviewed-by: Markus Armbruster arm...@redhat.com Aside: this code uses the first result from getaddrinfo(), and fails if it can't connect. This is a common misuse of getaddrinfo(). Consider a remote host with both an IPv4 and an IPv6 address, but only one of them actually connects. If getaddrinfo() puts the connectable one first, we succeed. Else, we fail. We should try the addresses in order until connect() succeeds, like qemu-sockets.c does. Good catch, i will fix it soon. And this patch mainly fix the coverity warning. Maybe i should fix the problem after this patch been merged. ;) Thanks.
[Qemu-devel] [PATCH] usb: delete error_report() for usb-bot
When no device under usb-bot bus, usb_msd_handle_data() will print usb-msd: Bad LUN 0. This is not correct hints. So delete error_report here. When scsi_device_find() return NULL, just goto fail. This patch fixes following bug. https://bugzilla.redhat.com/show_bug.cgi?id=1164665 Signed-off-by: Jun Li junm...@gmail.com --- hw/usb/dev-storage.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 4539733..f386d62 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -424,7 +424,6 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p) DPRINTF(Command on LUN %d\n, cbw.lun); scsi_dev = scsi_device_find(s-bus, 0, 0, cbw.lun); if (scsi_dev == NULL) { -error_report(usb-msd: Bad LUN %d, cbw.lun); goto fail; } tag = le32_to_cpu(cbw.tag); -- 1.9.3
[Qemu-devel] [PATCH] net: The third parameter of getsockname should be initialized
Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- net/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/socket.c b/net/socket.c index fb21e20..ca4b8ba 100644 --- a/net/socket.c +++ b/net/socket.c @@ -352,7 +352,7 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer, { struct sockaddr_in saddr; int newfd; -socklen_t saddr_len; +socklen_t saddr_len = sizeof(saddr); NetClientState *nc; NetSocketState *s; -- 1.7.12.4
[Qemu-devel] [PATCH] target-cris/translate.c: fix out of bounds read
In function t_gen_mov_TN_preg and t_gen_mov_preg_TN, The begin check about the validity of in-parameter 'r' is useless. We still access cpu_PR[r] in the follow code if it is invalid. Which will be an out-of-bounds read error. Fix it by using assert() to ensure it is valid before using it. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- target-cris/translate.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/target-cris/translate.c b/target-cris/translate.c index e37b04e..76406af 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -169,9 +169,7 @@ static int preg_sizes[] = { static inline void t_gen_mov_TN_preg(TCGv tn, int r) { -if (r 0 || r 15) { -fprintf(stderr, wrong register read $p%d\n, r); -} +assert(r = 0 r = 15); if (r == PR_BZ || r == PR_WZ || r == PR_DZ) { tcg_gen_mov_tl(tn, tcg_const_tl(0)); } else if (r == PR_VR) { @@ -182,9 +180,7 @@ static inline void t_gen_mov_TN_preg(TCGv tn, int r) } static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn) { -if (r 0 || r 15) { -fprintf(stderr, wrong register write $p%d\n, r); -} +assert(r = 0 r = 15); if (r == PR_BZ || r == PR_WZ || r == PR_DZ) { return; } else if (r == PR_SRS) { -- 1.7.12.4
Re: [Qemu-devel] [PATCH v2 0/3] fix bug about balloon working incorrectly when hotplug memeory
On Mon, Nov 17, 2014 at 01:11:07PM +0800, zhanghailiang wrote: Hi, Patch 1 and 2 mainly fix bug about balloon not working correctly when we do hotplug memory. It takes 'ram_size' as VM's real RAM size which is wrong after we hotplug memory. This bug exists since we begin to support hotplug memory, and it is better to fix it. Patch 3 add some trace events, it helps debugging balloon. If it is unnecessary, pls feel free to remove it. Thanks, zhanghailiang OK but what about other devices that access ram_size? Are they also broken? v2: - fix compiling break for other targets that don't support pc-dimm zhanghailiang (3): pc-dimm: add a function to calculate VM's current RAM size virtio-balloon: Fix balloon not working correctly when hotplug memory virtio-balloon: Add some trace events hw/mem/pc-dimm.c| 26 ++ hw/virtio/virtio-balloon.c | 21 +++-- include/exec/cpu-common.h | 1 + stubs/qmp_pc_dimm_device_list.c | 5 + trace-events| 4 5 files changed, 51 insertions(+), 6 deletions(-) -- 1.7.12.4
Re: [Qemu-devel] [RFC][PATCH 2/2] xen:i386:pc_piix: create isa bridge specific to IGD passthrough
On Mon, Nov 17, 2014 at 10:47:56AM +0800, Chen, Tiejun wrote: On 2014/11/5 22:09, Michael S. Tsirkin wrote: On Wed, Nov 05, 2014 at 03:22:59PM +0800, Tiejun Chen wrote: Currently IGD drivers always need to access PCH by 1f.0, and PCH vendor/device id is used to identify the card. Signed-off-by: Tiejun Chen tiejun.c...@intel.com --- hw/i386/pc_piix.c | 28 +++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index b559181..b19c7a9 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -50,7 +50,7 @@ #include cpu.h #include qemu/error-report.h #ifdef CONFIG_XEN -# include xen/hvm/hvm_info_table.h +#include xen/hvm/hvm_info_table.h #endif #define MAX_IDE_BUS 2 @@ -452,6 +452,31 @@ static void pc_init_isa(MachineState *machine) } #ifdef CONFIG_XEN +static void xen_igd_passthrough_isa_bridge_create(PCIBus *bus) +{ +struct PCIDevice *dev; +Error *local_err = NULL; +uint16_t device_id = 0x; + +/* Currently IGD drivers always need to access PCH by 1f.0. */ +dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0), +xen-igd-passthrough-isa-bridge); + +/* Identify PCH card with its own real vendor/device ids. + * Here that vendor id is always PCI_VENDOR_ID_INTEL. + */ +if (dev) { +device_id = object_property_get_int(OBJECT(dev), device-id, +local_err); +if (!local_err device_id != 0x) { +pci_config_set_device_id(dev-config, device_id); +return; +} +} + +fprintf(stderr, xen set xen-igd-passthrough-isa-bridge failed\n); +} + static void pc_xen_hvm_init(MachineState *machine) { PCIBus *bus; @@ -461,6 +486,7 @@ static void pc_xen_hvm_init(MachineState *machine) bus = pci_find_primary_bus(); if (bus != NULL) { pci_create_simple(bus, -1, xen-platform); +xen_igd_passthrough_isa_bridge_create(bus); } } #endif Can't we defer this step until the GPU is added? Sounds great but I can't figure out where we can to do this exactly. This way there won't be need to poke at host device directly, you could get all info from dev-config of the host device. As I understand We have two steps here: #1 At first I have to write something to check if we're registering 00:02.0 IGD, right? But where? While registering each pci device? In xen_pt_initfn. Just check the device and vendor ID against the table you have. #2 Then if that condition is matched, we register this ISA bridge on its associated bus. Thanks Tiejun Yep. Additionally the correct bridge would be initialized automatically. -- 1.9.1
Re: [Qemu-devel] [PATCH Part2 10/13] acpi, ich9: Add memory hot unplug support for ich9.
On Mon, 2014-11-17 at 13:03 +0800, Tang Chen wrote: Call memory unplug cb in ich9_pm_device_unplug_cb(). Signed-off-by: Tang Chen tangc...@cn.fujitsu.com --- hw/acpi/ich9.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 841f57d..691299f 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -317,8 +317,14 @@ void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) { -error_setg(errp, acpi: device unplug for not supported device -type: %s, object_get_typename(OBJECT(dev))); +if (pm-acpi_memory_hotplug.is_enabled +object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { +acpi_memory_unplug_request_cb(pm-acpi_regs, pm-irq, + pm-acpi_memory_hotplug, dev, errp); This should invoke acpi_memory_unplug_cb(). Regards, Zhu +} else { +error_setg(errp, acpi: device unplug for not supported device +type: %s, object_get_typename(OBJECT(dev))); +} } void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
Re: [Qemu-devel] [PATCH] usb: delete error_report() for usb-bot
On 2014/11/17 13:49, Jun Li wrote: When no device under usb-bot bus, usb_msd_handle_data() will print usb-msd: Bad LUN 0. This is not correct hints. So delete error_report here. When scsi_device_find() return NULL, just goto fail. If the hints is incorrect, I think you should change the hint message, but not delete it, because that's a recession. Best regards, -Gonglei This patch fixes following bug. https://bugzilla.redhat.com/show_bug.cgi?id=1164665 Signed-off-by: Jun Li junm...@gmail.com --- hw/usb/dev-storage.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 4539733..f386d62 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -424,7 +424,6 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p) DPRINTF(Command on LUN %d\n, cbw.lun); scsi_dev = scsi_device_find(s-bus, 0, 0, cbw.lun); if (scsi_dev == NULL) { -error_report(usb-msd: Bad LUN %d, cbw.lun); goto fail; } tag = le32_to_cpu(cbw.tag);
Re: [Qemu-devel] [PATCH 0/4] migration: fix CVE-2014-7840
On (Wed) 12 Nov 2014 [11:44:35], Michael S. Tsirkin wrote: This patchset fixes CVE-2014-7840: invalid migration stream can cause arbitrary qemu memory overwrite. First patch includes the minimal fix for the issue. Follow-up patches on top add extra checking to reduce the chance this kind of bug recurs. Note: these are already (tentatively-pending review) queued in my tree, so only review/ack is necessary. Why not let this go in via the migration tree? Amit
Re: [Qemu-devel] [PATCH] net: The third parameter of getsockname should be initialized
zhanghailiang zhang.zhanghaili...@huawei.com writes: Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- net/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/socket.c b/net/socket.c index fb21e20..ca4b8ba 100644 --- a/net/socket.c +++ b/net/socket.c @@ -352,7 +352,7 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer, { struct sockaddr_in saddr; int newfd; -socklen_t saddr_len; +socklen_t saddr_len = sizeof(saddr); NetClientState *nc; NetSocketState *s; Reviewed-by: Markus Armbruster arm...@redhat.com