From c409572678936d3ffa8694f5a1dae531c2212e21 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 2 Nov 2014 18:48:32 +0200 Subject: qemu-char: fix tcp_get_fds tcp_get_fds API discards fds if there's more than 1 of these. It's tricky to fix this without API changes in the generic case. However, this API is only used by tests ATM, and tests know how many fds they expect. So let's not waste cycles trying to fix this properly: simply assume at most 16 fds (tests use at most 8 now). assert if some test tries to get more. Signed-off-by: Michael S. Tsirkin --- qemu-char.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qemu-char.c b/qemu-char.c index 4a76f0f805..a8b01da3ee 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -88,6 +88,7 @@ #define READ_BUF_LEN 4096 #define READ_RETRIES 10 #define CHR_MAX_FILENAME_SIZE 256 +#define TCP_MAX_FDS 16 /***********************************************************/ /* Socket address helpers */ @@ -2668,6 +2669,8 @@ static int tcp_get_msgfds(CharDriverState *chr, int *fds, int num) TCPCharDriver *s = chr->opaque; int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num; + assert(num <= TCP_MAX_FDS); + if (to_copy) { int i; @@ -2762,7 +2765,7 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) struct iovec iov[1]; union { struct cmsghdr cmsg; - char control[CMSG_SPACE(sizeof(int))]; + char control[CMSG_SPACE(sizeof(int) * TCP_MAX_FDS)]; } msg_control; int flags = 0; ssize_t ret; -- cgit v1.2.1 From b8865591d4d5680b4f766c25ca1db110320b4d15 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 31 Oct 2014 16:38:32 +0000 Subject: pc: kvm: check if KVM has free memory slots to avoid abort() When more memory devices are used than available KVM memory slots, QEMU crashes with: kvm_alloc_slot: no free slot available Aborted (core dumped) Fix this by checking that KVM has a free slot before attempting to map memory in guest address space. Signed-off-by: Igor Mammedov Acked-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 5 +++++ include/sysemu/kvm.h | 1 + kvm-all.c | 18 +++++++++++++++++- kvm-stub.c | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 1205db83bc..ce7b75217a 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1598,6 +1598,11 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, goto out; } + if (kvm_enabled() && !kvm_has_free_slot(machine)) { + error_setg(&local_err, "hypervisor has no free memory slots left"); + goto out; + } + memory_region_add_subregion(&pcms->hotplug_memory, addr - pcms->hotplug_memory_base, mr); vmstate_register_ram(mr, dev); diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index b0cd657f77..22e42ef236 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -163,6 +163,7 @@ extern KVMState *kvm_state; /* external API */ +bool kvm_has_free_slot(MachineState *ms); int kvm_has_sync_mmu(void); int kvm_has_vcpu_events(void); int kvm_has_robust_singlestep(void); diff --git a/kvm-all.c b/kvm-all.c index 596e7ce6c3..937bc9d903 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -132,7 +132,7 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = { KVM_CAP_LAST_INFO }; -static KVMSlot *kvm_alloc_slot(KVMState *s) +static KVMSlot *kvm_get_free_slot(KVMState *s) { int i; @@ -142,6 +142,22 @@ static KVMSlot *kvm_alloc_slot(KVMState *s) } } + return NULL; +} + +bool kvm_has_free_slot(MachineState *ms) +{ + return kvm_get_free_slot(KVM_STATE(ms->accelerator)); +} + +static KVMSlot *kvm_alloc_slot(KVMState *s) +{ + KVMSlot *slot = kvm_get_free_slot(s); + + if (slot) { + return slot; + } + fprintf(stderr, "%s: no free slot available\n", __func__); abort(); } diff --git a/kvm-stub.c b/kvm-stub.c index 43fc0dd01e..7ba90c546f 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -147,4 +147,9 @@ int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq) { return -ENOSYS; } + +bool kvm_has_free_slot(MachineState *ms) +{ + return false; +} #endif -- cgit v1.2.1 From 34dde13685ebc2c07923f32ad69e40b27c0e0bb4 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 31 Oct 2014 16:38:35 +0000 Subject: pc: make pc_dimm_plug() more readble split addr initialization from declaration so that later when new local vars are added property getter wouldn't drift off of error check. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ce7b75217a..70ae3cfde6 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1556,8 +1556,9 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr = ddc->get_memory_region(dimm); - uint64_t addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, - &local_err); + uint64_t addr; + + addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); if (local_err) { goto out; } -- cgit v1.2.1 From 92a37a04d6e034b73ea1ba4825ba4d5860f0a810 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 31 Oct 2014 16:38:36 +0000 Subject: pc: limit DIMM address and size to page aligned values When running in KVM mode, kvm_set_phys_mem() will silently fail if registered MemoryRegion address/size is not page aligned. Causing memory hotplug failure in guest. Mapping non aligned MemoryRegion in TCG mode 'works', but sane guest OS still expects page aligned memory module and fails to initialize it if it's not aligned. So do not allow non aligned (i.e. valid) address/size values for DIMM to avoid either KVM failure or guest issues caused by it. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 3 ++- hw/mem/pc-dimm.c | 14 +++++++++++++- include/hw/mem/pc-dimm.h | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 70ae3cfde6..33928b90fd 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1556,6 +1556,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr = ddc->get_memory_region(dimm); + uint64_t align = TARGET_PAGE_SIZE; uint64_t addr; addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); @@ -1565,7 +1566,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, addr = pc_dimm_get_free_addr(pcms->hotplug_memory_base, memory_region_size(&pcms->hotplug_memory), - !addr ? NULL : &addr, + !addr ? NULL : &addr, align, memory_region_size(mr), &local_err); if (local_err) { goto out; diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index a800ea7a9f..4944f0faf9 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -139,7 +139,7 @@ static int pc_dimm_built_list(Object *obj, void *opaque) uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, uint64_t address_space_size, - uint64_t *hint, uint64_t size, + uint64_t *hint, uint64_t align, uint64_t size, Error **errp) { GSList *list = NULL, *item; @@ -152,6 +152,18 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, goto out; } + if (hint && QEMU_ALIGN_UP(*hint, align) != *hint) { + error_setg(errp, "address must be aligned to 0x%" PRIx64 " bytes", + align); + goto out; + } + + if (QEMU_ALIGN_UP(size, align) != size) { + error_setg(errp, "backend memory size must be multiple of 0x%" + PRIx64, align); + goto out; + } + assert(address_space_end > address_space_start); object_child_foreach(qdev_get_machine(), pc_dimm_built_list, &list); diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index 761eeef801..e1dcbbcd58 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -72,7 +72,7 @@ typedef struct PCDIMMDeviceClass { uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, uint64_t address_space_size, - uint64_t *hint, uint64_t size, + uint64_t *hint, uint64_t align, uint64_t size, Error **errp); int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp); -- cgit v1.2.1 From a2b257d6212ade772473f86bf0637480b2578a7e Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 31 Oct 2014 16:38:37 +0000 Subject: memory: expose alignment used for allocating RAM as MemoryRegion API introduce memory_region_get_alignment() that returns underlying memory block alignment or 0 if it's not relevant/implemented for backend. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- exec.c | 9 ++++++--- include/exec/exec-all.h | 2 +- include/exec/memory.h | 2 ++ include/qemu/osdep.h | 3 ++- memory.c | 5 +++++ target-s390x/kvm.c | 2 +- util/oslib-posix.c | 5 ++++- util/oslib-win32.c | 2 +- 8 files changed, 22 insertions(+), 8 deletions(-) diff --git a/exec.c b/exec.c index f0e2bd32b6..71ac104b39 100644 --- a/exec.c +++ b/exec.c @@ -909,14 +909,15 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, uint16_t section); static subpage_t *subpage_init(AddressSpace *as, hwaddr base); -static void *(*phys_mem_alloc)(size_t size) = qemu_anon_ram_alloc; +static void *(*phys_mem_alloc)(size_t size, uint64_t *align) = + qemu_anon_ram_alloc; /* * Set a custom physical guest memory alloator. * Accelerators with unusual needs may need this. Hopefully, we can * get rid of it eventually. */ -void phys_mem_set_alloc(void *(*alloc)(size_t)) +void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align)) { phys_mem_alloc = alloc; } @@ -1098,6 +1099,7 @@ static void *file_ram_alloc(RAMBlock *block, error_propagate(errp, local_err); goto error; } + block->mr->align = hpagesize; if (memory < hpagesize) { error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to " @@ -1309,7 +1311,8 @@ static ram_addr_t ram_block_add(RAMBlock *new_block, Error **errp) if (xen_enabled()) { xen_ram_alloc(new_block->offset, new_block->length, new_block->mr); } else { - new_block->host = phys_mem_alloc(new_block->length); + new_block->host = phys_mem_alloc(new_block->length, + &new_block->mr->align); if (!new_block->host) { error_setg_errno(errp, errno, "cannot set up guest memory '%s'", diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 421a142a0d..0844885edd 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -333,7 +333,7 @@ extern uintptr_t tci_tb_ptr; #if !defined(CONFIG_USER_ONLY) -void phys_mem_set_alloc(void *(*alloc)(size_t)); +void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align)); struct MemoryRegion *iotlb_to_region(AddressSpace *as, hwaddr index); bool io_mem_read(struct MemoryRegion *mr, hwaddr addr, diff --git a/include/exec/memory.h b/include/exec/memory.h index 74a58b4883..f64ab5e3e5 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -146,6 +146,7 @@ struct MemoryRegion { hwaddr addr; void (*destructor)(MemoryRegion *mr); ram_addr_t ram_addr; + uint64_t align; bool subpage; bool terminates; bool romd_mode; @@ -838,6 +839,7 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr, */ ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr); +uint64_t memory_region_get_alignment(const MemoryRegion *mr); /** * memory_region_del_subregion: Remove a subregion. * diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index c0324344d5..b3300cc239 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #ifdef __OpenBSD__ #include @@ -103,7 +104,7 @@ typedef signed int int_fast16_t; int qemu_daemon(int nochdir, int noclose); void *qemu_try_memalign(size_t alignment, size_t size); void *qemu_memalign(size_t alignment, size_t size); -void *qemu_anon_ram_alloc(size_t size); +void *qemu_anon_ram_alloc(size_t size, uint64_t *align); void qemu_vfree(void *ptr); void qemu_anon_ram_free(void *ptr, size_t size); diff --git a/memory.c b/memory.c index 0f4fdc7db7..15cf9ebd84 100644 --- a/memory.c +++ b/memory.c @@ -1749,6 +1749,11 @@ ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr) return mr->ram_addr; } +uint64_t memory_region_get_alignment(const MemoryRegion *mr) +{ + return mr->align; +} + static int cmp_flatrange_addr(const void *addr_, const void *fr_) { const AddrRange *addr = addr_; diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index d247471119..50709ba6b5 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -404,7 +404,7 @@ int kvm_arch_get_registers(CPUState *cs) * to grow. We also have to use MAP parameters that avoid * read-only mapping of guest pages. */ -static void *legacy_s390_alloc(size_t size) +static void *legacy_s390_alloc(size_t size, , uint64_t *align) { void *mem; diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 8c9d80e9fe..16fcec2f37 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -124,7 +124,7 @@ void *qemu_memalign(size_t alignment, size_t size) } /* alloc shared memory pages */ -void *qemu_anon_ram_alloc(size_t size) +void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment) { size_t align = QEMU_VMALLOC_ALIGN; size_t total = size + align - getpagesize(); @@ -136,6 +136,9 @@ void *qemu_anon_ram_alloc(size_t size) return NULL; } + if (alignment) { + *alignment = align; + } ptr += offset; total -= offset; diff --git a/util/oslib-win32.c b/util/oslib-win32.c index a3eab4acba..87cfbe0834 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -67,7 +67,7 @@ void *qemu_memalign(size_t alignment, size_t size) return qemu_oom_check(qemu_try_memalign(alignment, size)); } -void *qemu_anon_ram_alloc(size_t size) +void *qemu_anon_ram_alloc(size_t size, uint64_t *align) { void *ptr; -- cgit v1.2.1 From 91aa70ab2a748e3a72004d1a729248221b7bb24a Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 31 Oct 2014 16:38:39 +0000 Subject: pc: align DIMM's address/size by backend's alignment value Performance wise it's better to align GVA by the backend's page size. Also do not allow to create DIMM device with suboptimal size (i.e. not aligned to backends page size) to aviod memory loss. Do above only for 2.2 and newer machine types to avoid breaking working configs with 2.1 machine type. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 17 +++++++++++++++++ hw/i386/pc_piix.c | 2 ++ hw/i386/pc_q35.c | 3 +++ include/hw/i386/pc.h | 4 ++++ 4 files changed, 26 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 33928b90fd..021ec44768 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1564,6 +1564,10 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, goto out; } + if (memory_region_get_alignment(mr) && pcms->enforce_aligned_dimm) { + align = memory_region_get_alignment(mr); + } + addr = pc_dimm_get_free_addr(pcms->hotplug_memory_base, memory_region_size(&pcms->hotplug_memory), !addr ? NULL : &addr, align, @@ -1732,6 +1736,13 @@ static void pc_machine_set_vmport(Object *obj, bool value, Error **errp) pcms->vmport = value; } +static bool pc_machine_get_aligned_dimm(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return pcms->enforce_aligned_dimm; +} + static void pc_machine_initfn(Object *obj) { PCMachineState *pcms = PC_MACHINE(obj); @@ -1744,11 +1755,17 @@ static void pc_machine_initfn(Object *obj) pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g, NULL, NULL, NULL); + pcms->vmport = !xen_enabled(); object_property_add_bool(obj, PC_MACHINE_VMPORT, pc_machine_get_vmport, pc_machine_set_vmport, NULL); + + pcms->enforce_aligned_dimm = true; + object_property_add_bool(obj, PC_MACHINE_ENFORCE_ALIGNED_DIMM, + pc_machine_get_aligned_dimm, + NULL, NULL); } static void pc_machine_class_init(ObjectClass *oc, void *data) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 7bb97a4923..741dffd5f3 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -305,10 +305,12 @@ static void pc_init_pci(MachineState *machine) static void pc_compat_2_1(MachineState *machine) { + PCMachineState *pcms = PC_MACHINE(machine); smbios_uuid_encoded = false; x86_cpu_compat_set_features("coreduo", FEAT_1_ECX, CPUID_EXT_VMX, 0); x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0); x86_cpu_compat_kvm_no_autodisable(FEAT_8000_0001_ECX, CPUID_EXT3_SVM); + pcms->enforce_aligned_dimm = false; } static void pc_compat_2_0(MachineState *machine) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 598e679749..e9ba1a2735 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -284,6 +284,9 @@ static void pc_q35_init(MachineState *machine) static void pc_compat_2_1(MachineState *machine) { + PCMachineState *pcms = PC_MACHINE(machine); + + pcms->enforce_aligned_dimm = false; smbios_uuid_encoded = false; x86_cpu_compat_set_features("coreduo", FEAT_1_ECX, CPUID_EXT_VMX, 0); x86_cpu_compat_set_features("core2duo", FEAT_1_ECX, CPUID_EXT_VMX, 0); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 7c3731f1b0..9d85b89e4f 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -24,6 +24,8 @@ * address space begins. * @hotplug_memory: hotplug memory addess space container * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling + * @enforce_aligned_dimm: check that DIMM's address/size is aligned by + * backend's alignment value if provided */ struct PCMachineState { /*< private >*/ @@ -38,12 +40,14 @@ struct PCMachineState { uint64_t max_ram_below_4g; bool vmport; + bool enforce_aligned_dimm; }; #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" #define PC_MACHINE_MEMHP_REGION_SIZE "hotplug-memory-region-size" #define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g" #define PC_MACHINE_VMPORT "vmport" +#define PC_MACHINE_ENFORCE_ALIGNED_DIMM "enforce-aligned-dimm" /** * PCMachineClass: -- cgit v1.2.1 From 0c0de1b681bc11a8ebc94bd45e99d6f4e8fafd80 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 31 Oct 2014 16:38:40 +0000 Subject: pc: pc-dimm: use backend alignment during address auto allocation Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/mem/pc-dimm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 4944f0faf9..d431834030 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -146,6 +146,9 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, uint64_t new_addr, ret = 0; uint64_t address_space_end = address_space_start + address_space_size; + g_assert(QEMU_ALIGN_UP(address_space_start, align) == address_space_start); + g_assert(QEMU_ALIGN_UP(address_space_size, align) == address_space_size); + if (!address_space_size) { error_setg(errp, "memory hotplug is not enabled, " "please add maxmem option"); @@ -189,7 +192,7 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, error_setg(errp, "address range conflicts with '%s'", d->id); goto out; } - new_addr = dimm->addr + dimm_size; + new_addr = QEMU_ALIGN_UP(dimm->addr + dimm_size, align); } } ret = new_addr; -- cgit v1.2.1 From b03541fa7722d64a1c961a8467d778d7e086a933 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 31 Oct 2014 16:38:41 +0000 Subject: pc: explicitly check maxmem limit when adding DIMM Currently maxmem limit is not checked and depends on hotplug region container not being able to fit more RAM than maxmem. Do check explicitly so that it would be possible to change hotplug container size later to deal with fragmentation. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 021ec44768..3d732cf5a5 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1545,6 +1545,37 @@ void qemu_register_pc_machine(QEMUMachine *m) g_free(name); } +static int pc_dimm_count(Object *obj, void *opaque) +{ + int *count = opaque; + + if (object_dynamic_cast(obj, TYPE_PC_DIMM)) { + (*count)++; + } + + object_child_foreach(obj, pc_dimm_count, opaque); + return 0; +} + +static int pc_existing_dimms_capacity(Object *obj, void *opaque) +{ + Error *local_err = NULL; + uint64_t *size = opaque; + + if (object_dynamic_cast(obj, TYPE_PC_DIMM)) { + (*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP, &local_err); + + if (local_err) { + qerror_report_err(local_err); + error_free(local_err); + return 1; + } + } + + object_child_foreach(obj, pc_dimm_count, opaque); + return 0; +} + static void pc_dimm_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -1556,6 +1587,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr = ddc->get_memory_region(dimm); + uint64_t existing_dimms_capacity = 0; uint64_t align = TARGET_PAGE_SIZE; uint64_t addr; @@ -1576,6 +1608,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, goto out; } + if (pc_existing_dimms_capacity(OBJECT(machine), &existing_dimms_capacity)) { + error_setg(&local_err, "failed to get total size of existing DIMMs"); + goto out; + } + + if (existing_dimms_capacity + memory_region_size(mr) > + machine->maxram_size - machine->ram_size) { + error_setg(&local_err, "not enough space, currently 0x%" PRIx64 + " in use of total 0x" RAM_ADDR_FMT, + existing_dimms_capacity, machine->maxram_size); + goto out; + } + object_property_set_int(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err); if (local_err) { goto out; -- cgit v1.2.1 From 085f8e88ba73b7ff80298b0085f6e615d3b5c45f Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 31 Oct 2014 16:38:42 +0000 Subject: pc: count in 1Gb hugepage alignment when sizing hotplug-memory container if DIMMs with different size/alignment are interleaved in creation order, it could lead to hotplug-memory container fragmentation and following inability to use all RAM upto maxmem. For example: -m 4G,slots=3,maxmem=7G -object memory-backend-file,id=mem-1,size=256M,mem-path=/pagesize-2MB -device pc-dimm,id=mem1,memdev=mem-1 -object memory-backend-file,id=mem-2,size=1G,mem-path=/pagesize-1GB -device pc-dimm,id=mem2,memdev=mem-2 -object memory-backend-file,id=mem-3,size=256M,mem-path=/pagesize-2MB -device pc-dimm,id=mem3,memdev=mem-3 fragments hotplug-memory container and doesn't allow to use 1GB hugepage backend to consume remainig 1Gb. To ease managment factor count in max 1Gb alignment for each memory slot when sizing hotplug-memory region so that regadless of fragmentaion it would be possible to add max aligned DIMM. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3d732cf5a5..8be50a4ad6 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1247,6 +1247,11 @@ FWCfgState *pc_memory_init(MachineState *machine, pcms->hotplug_memory_base = ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30); + if (pcms->enforce_aligned_dimm) { + /* size hotplug region assuming 1G page max alignment per slot */ + hotplug_mem_size += (1ULL << 30) * machine->ram_slots; + } + if ((pcms->hotplug_memory_base + hotplug_mem_size) < hotplug_mem_size) { error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT, -- cgit v1.2.1 From 109e90e47029f415783cd6e9a0eb9d0f10954c18 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Wed, 5 Nov 2014 16:29:35 +0200 Subject: hw/pci: fix crash on shpc error flow If the pci bridge enters in error flow as part of init process it will only delete the shpc mmio subregion but not remove it from the properties list, resulting in segmentation fault when the bridge runs the exit function. Example: add a pci bridge without specifing the chassis number: ... -device pci-bridge,id=p1 Result: (qemu) qemu-system-x86_64: -device pci-bridge,id=p1: Bridge chassis not specified. Each bridge is required to be assigned a unique chassis id > 0. qemu-system-x86_64: -device pci-bridge,id=p1: Device initialization failed. Segmentation fault (core dumped) if (child->class->unparent) { #0 0x00005555558d629b in object_finalize_child_property (obj=0x555556d2e830, name=0x555556d30630 "shpc-mmio[0]", opaque=0x555556a42fc8) at qom/object.c:1078 #1 0x00005555558d4b1f in object_property_del_all (obj=0x555556d2e830) at qom/object.c:367 #2 0x00005555558d4ca1 in object_finalize (data=0x555556d2e830) at qom/object.c:412 #3 0x00005555558d55a1 in object_unref (obj=0x555556d2e830) at qom/object.c:720 #4 0x000055555572c907 in qdev_device_add (opts=0x5555563544f0) at qdev-monitor.c:566 #5 0x0000555555744f16 in device_init_func (opts=0x5555563544f0, opaque=0x0) at vl.c:2213 #6 0x00005555559cf5f0 in qemu_opts_foreach (list=0x555555e0f8e0 , func=0x555555744efa , opaque=0x0, abort_on_failure=1) at util/qemu-option.c:1057 #7 0x000055555574a11b in main (argc=16, argv=0x7fffffffdde8, envp=0x7fffffffde70) at vl.c:423 Unparent the shpc mmio region as part of shpc cleanup. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Amos Kong --- hw/pci/shpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c index 9a39060933..27c496e8c3 100644 --- a/hw/pci/shpc.c +++ b/hw/pci/shpc.c @@ -663,6 +663,7 @@ void shpc_cleanup(PCIDevice *d, MemoryRegion *bar) SHPCDevice *shpc = d->shpc; d->cap_present &= ~QEMU_PCI_CAP_SHPC; memory_region_del_subregion(bar, &shpc->mmio); + object_unparent(OBJECT(&shpc->mmio)); /* TODO: cleanup config space changes? */ g_free(shpc->config); g_free(shpc->cmask); -- cgit v1.2.1 From ad5b88b1f198182642b6cbf3dacb4cade0c80fb9 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 17 Nov 2014 07:49:21 +0200 Subject: acpi-build: mark RAM dirty on table update acpi build modifies internal FW CFG RAM on first access but we forgot to mark it dirty. If this RAM has been migrated already, it won't be migrated again, returning corrupted tables to guest. Signed-off-by: Michael S. Tsirkin --- hw/core/loader.c | 8 +++++--- hw/i386/acpi-build.c | 11 ++++++++--- include/hw/loader.h | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/hw/core/loader.c b/hw/core/loader.c index fc155359f8..7527fd3036 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -811,12 +811,12 @@ err: return -1; } -void *rom_add_blob(const char *name, const void *blob, size_t len, +ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len, hwaddr addr, const char *fw_file_name, FWCfgReadCallback fw_callback, void *callback_opaque) { Rom *rom; - void *data = NULL; + ram_addr_t ret = RAM_ADDR_MAX; rom = g_malloc0(sizeof(*rom)); rom->name = g_strdup(name); @@ -828,11 +828,13 @@ void *rom_add_blob(const char *name, const void *blob, size_t len, rom_insert(rom); if (fw_file_name && fw_cfg) { char devpath[100]; + void *data; snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); if (rom_file_has_mr) { data = rom_set_mr(rom, OBJECT(fw_cfg), devpath); + ret = memory_region_get_ram_addr(rom->mr); } else { data = rom->data; } @@ -841,7 +843,7 @@ void *rom_add_blob(const char *name, const void *blob, size_t len, fw_callback, callback_opaque, data, rom->romsize); } - return data; + return ret; } /* This function is specific for elf program because we don't need to allocate diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 4003b6bf9b..92a36e3b9b 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -56,6 +56,7 @@ #include "qapi/qmp/qint.h" #include "qom/qom-qobject.h" +#include "exec/ram_addr.h" /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows @@ -1511,7 +1512,7 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) typedef struct AcpiBuildState { /* Copy of table in RAM (for patching). */ - uint8_t *table_ram; + ram_addr_t table_ram; uint32_t table_size; /* Is table patched? */ uint8_t patched; @@ -1716,9 +1717,12 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) acpi_build(build_state->guest_info, &tables); assert(acpi_data_len(tables.table_data) == build_state->table_size); - memcpy(build_state->table_ram, tables.table_data->data, + memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data, build_state->table_size); + cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram, + build_state->table_size); + acpi_build_tables_cleanup(&tables, true); } @@ -1728,7 +1732,7 @@ static void acpi_build_reset(void *build_opaque) build_state->patched = 0; } -static void *acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob, +static ram_addr_t acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob, const char *name) { return rom_add_blob(name, blob->data, acpi_data_len(blob), -1, name, @@ -1777,6 +1781,7 @@ void acpi_setup(PcGuestInfo *guest_info) /* Now expose it all to Guest */ build_state->table_ram = acpi_add_rom_blob(build_state, tables.table_data, ACPI_BUILD_TABLE_FILE); + assert(build_state->table_ram != RAM_ADDR_MAX); build_state->table_size = acpi_data_len(tables.table_data); acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader"); diff --git a/include/hw/loader.h b/include/hw/loader.h index 054c6a22b5..64816395dc 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -59,7 +59,7 @@ extern bool rom_file_has_mr; int rom_add_file(const char *file, const char *fw_dir, hwaddr addr, int32_t bootindex, bool option_rom); -void *rom_add_blob(const char *name, const void *blob, size_t len, +ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len, hwaddr addr, const char *fw_file_name, FWCfgReadCallback fw_callback, void *callback_opaque); int rom_add_elf_program(const char *name, void *data, size_t datasize, -- cgit v1.2.1 From 4f99ab7a782250847ca33ae23a172501496c604d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 15 Oct 2014 09:45:44 +0200 Subject: target-i386: move generic memory hotplug methods to DSDTs This makes it simpler to keep the SSDT byte-for-byte identical for a given machine type, which is a goal we want to have for 2.2 and newer types. Signed-off-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-dsdt-mem-hotplug.dsl | 176 ++++++++ hw/i386/acpi-dsdt.dsl | 3 +- hw/i386/acpi-dsdt.hex.generated | 795 +++++++++++++++++++++++++++++++++- hw/i386/q35-acpi-dsdt.dsl | 3 +- hw/i386/q35-acpi-dsdt.hex.generated | 797 +++++++++++++++++++++++++++++++++- hw/i386/ssdt-mem.hex.generated | 8 +- hw/i386/ssdt-misc.dsl | 165 +------ hw/i386/ssdt-misc.hex.generated | 834 ++---------------------------------- tests/acpi-test-data/pc/DSDT | Bin 2807 -> 3592 bytes tests/acpi-test-data/pc/SSDT | Bin 3065 -> 2279 bytes tests/acpi-test-data/q35/DSDT | Bin 7397 -> 8182 bytes tests/acpi-test-data/q35/SSDT | Bin 1346 -> 560 bytes 12 files changed, 1789 insertions(+), 992 deletions(-) create mode 100644 hw/i386/acpi-dsdt-mem-hotplug.dsl diff --git a/hw/i386/acpi-dsdt-mem-hotplug.dsl b/hw/i386/acpi-dsdt-mem-hotplug.dsl new file mode 100644 index 0000000000..2a36c4799e --- /dev/null +++ b/hw/i386/acpi-dsdt-mem-hotplug.dsl @@ -0,0 +1,176 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + + External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj) + + Scope(\_SB.PCI0) { + Device(MEMORY_HOTPLUG_DEVICE) { + Name(_HID, "PNP0A06") + Name(_UID, "Memory hotplug resources") + External(MEMORY_SLOTS_NUMBER, IntObj) + + /* Memory hotplug IO registers */ + OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO, + ACPI_MEMORY_HOTPLUG_BASE, + ACPI_MEMORY_HOTPLUG_IO_LEN) + + Name(_CRS, ResourceTemplate() { + IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE, + 0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO) + }) + + Method(_STA, 0) { + If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) { + Return(0x0) + } + /* present, functioning, decoding, not shown in UI */ + Return(0xB) + } + + Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) { + MEMORY_SLOT_ADDR_LOW, 32, // read only + MEMORY_SLOT_ADDR_HIGH, 32, // read only + MEMORY_SLOT_SIZE_LOW, 32, // read only + MEMORY_SLOT_SIZE_HIGH, 32, // read only + MEMORY_SLOT_PROXIMITY, 32, // read only + } + Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) { + 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 + } + + Mutex (MEMORY_SLOT_LOCK, 0) + Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) { + MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only + MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only + MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only + } + + Method(MEMORY_SLOT_SCAN_METHOD, 0) { + If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) { + Return(Zero) + } + + Store(Zero, Local0) // Mem devs iterrator + Acquire(MEMORY_SLOT_LOCK, 0xFFFF) + 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) + } + // TODO: handle memory eject request + Add(Local0, One, Local0) // goto next DIMM + } + Release(MEMORY_SLOT_LOCK) + Return(One) + } + + Method(MEMORY_SLOT_STATUS_METHOD, 1) { + Store(Zero, Local0) + + Acquire(MEMORY_SLOT_LOCK, 0xFFFF) + Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM + + If (LEqual(MEMORY_SLOT_ENABLED, One)) { + Store(0xF, Local0) + } + + Release(MEMORY_SLOT_LOCK) + Return(Local0) + } + + Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) { + Acquire(MEMORY_SLOT_LOCK, 0xFFFF) + Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM + + Name(MR64, ResourceTemplate() { + QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x0000000000000000, // Address Space Granularity + 0x0000000000000000, // Address Range Minimum + 0xFFFFFFFFFFFFFFFE, // Address Range Maximum + 0x0000000000000000, // Address Translation Offset + 0xFFFFFFFFFFFFFFFF, // Address Length + ,, MW64, AddressRangeMemory, TypeStatic) + }) + + CreateDWordField(MR64, 14, MINL) + CreateDWordField(MR64, 18, MINH) + CreateDWordField(MR64, 38, LENL) + CreateDWordField(MR64, 42, LENH) + CreateDWordField(MR64, 22, MAXL) + CreateDWordField(MR64, 26, MAXH) + + Store(MEMORY_SLOT_ADDR_HIGH, MINH) + Store(MEMORY_SLOT_ADDR_LOW, MINL) + Store(MEMORY_SLOT_SIZE_HIGH, LENH) + Store(MEMORY_SLOT_SIZE_LOW, LENL) + + // 64-bit math: MAX = MIN + LEN - 1 + Add(MINL, LENL, MAXL) + Add(MINH, LENH, MAXH) + If (LLess(MAXL, MINL)) { + Add(MAXH, One, MAXH) + } + If (LLess(MAXL, One)) { + Subtract(MAXH, One, MAXH) + } + Subtract(MAXL, One, MAXL) + + If (LEqual(MAXH, Zero)){ + Name(MR32, ResourceTemplate() { + DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, // Address Space Granularity + 0x00000000, // Address Range Minimum + 0xFFFFFFFE, // Address Range Maximum + 0x00000000, // Address Translation Offset + 0xFFFFFFFF, // Address Length + ,, MW32, AddressRangeMemory, TypeStatic) + }) + CreateDWordField(MR32, MW32._MIN, MIN) + CreateDWordField(MR32, MW32._MAX, MAX) + CreateDWordField(MR32, MW32._LEN, LEN) + Store(MINL, MIN) + Store(MAXL, MAX) + Store(LENL, LEN) + + Release(MEMORY_SLOT_LOCK) + Return(MR32) + } + + Release(MEMORY_SLOT_LOCK) + Return(MR64) + } + + Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) { + Acquire(MEMORY_SLOT_LOCK, 0xFFFF) + Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM + Store(MEMORY_SLOT_PROXIMITY, Local0) + Release(MEMORY_SLOT_LOCK) + Return(Local0) + } + + Method(MEMORY_SLOT_OST_METHOD, 4) { + Acquire(MEMORY_SLOT_LOCK, 0xFFFF) + Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM + Store(Arg1, MEMORY_SLOT_OST_EVENT) + Store(Arg2, MEMORY_SLOT_OST_STATUS) + Release(MEMORY_SLOT_LOCK) + } + } // Device() + } // Scope() diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index 559f4b6653..a611e07ec8 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -297,13 +297,12 @@ DefinitionBlock ( #include "hw/acpi/pc-hotplug.h" #define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE #include "acpi-dsdt-cpu-hotplug.dsl" +#include "acpi-dsdt-mem-hotplug.dsl" /**************************************************************** * General purpose events ****************************************************************/ - External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj) - Scope(\_GPE) { Name(_HID, "ACPI0006") diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated index a21bf410e5..875570e5b1 100644 --- a/hw/i386/acpi-dsdt.hex.generated +++ b/hw/i386/acpi-dsdt.hex.generated @@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x53, 0x44, 0x54, -0xf7, -0xa, +0x8, +0xe, 0x0, 0x0, 0x1, -0x1f, +0xfc, 0x42, 0x58, 0x50, @@ -32,8 +32,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x54, 0x4c, 0x28, -0x5, -0x10, +0x8, +0x14, 0x20, 0x10, 0x49, @@ -2593,6 +2593,791 @@ static unsigned char AcpiDsdtAmlCode[] = { 0xa, 0xb, 0x10, +0x40, +0x31, +0x2e, +0x5f, +0x53, +0x42, +0x5f, +0x50, +0x43, +0x49, +0x30, +0x5b, +0x82, +0x43, +0x30, +0x4d, +0x48, +0x50, +0x44, +0x8, +0x5f, +0x48, +0x49, +0x44, +0xd, +0x50, +0x4e, +0x50, +0x30, +0x41, +0x30, +0x36, +0x0, +0x8, +0x5f, +0x55, +0x49, +0x44, +0xd, +0x4d, +0x65, +0x6d, +0x6f, +0x72, +0x79, +0x20, +0x68, +0x6f, +0x74, +0x70, +0x6c, +0x75, +0x67, +0x20, +0x72, +0x65, +0x73, +0x6f, +0x75, +0x72, +0x63, +0x65, +0x73, +0x0, +0x5b, +0x80, +0x48, +0x50, +0x4d, +0x52, +0x1, +0xb, +0x0, +0xa, +0xa, +0x18, +0x8, +0x5f, +0x43, +0x52, +0x53, +0x11, +0xd, +0xa, +0xa, +0x47, +0x1, +0x0, +0xa, +0x0, +0xa, +0x0, +0x18, +0x79, +0x0, +0x14, +0x13, +0x5f, +0x53, +0x54, +0x41, +0x0, +0xa0, +0x9, +0x93, +0x4d, +0x44, +0x4e, +0x52, +0x0, +0xa4, +0x0, +0xa4, +0xa, +0xb, +0x5b, +0x81, +0x1f, +0x48, +0x50, +0x4d, +0x52, +0x3, +0x4d, +0x52, +0x42, +0x4c, +0x20, +0x4d, +0x52, +0x42, +0x48, +0x20, +0x4d, +0x52, +0x4c, +0x4c, +0x20, +0x4d, +0x52, +0x4c, +0x48, +0x20, +0x4d, +0x50, +0x58, +0x5f, +0x20, +0x5b, +0x81, +0x13, +0x48, +0x50, +0x4d, +0x52, +0x1, +0x0, +0x40, +0xa, +0x4d, +0x45, +0x53, +0x5f, +0x1, +0x4d, +0x49, +0x4e, +0x53, +0x1, +0x5b, +0x1, +0x4d, +0x4c, +0x43, +0x4b, +0x0, +0x5b, +0x81, +0x15, +0x48, +0x50, +0x4d, +0x52, +0x3, +0x4d, +0x53, +0x45, +0x4c, +0x20, +0x4d, +0x4f, +0x45, +0x56, +0x20, +0x4d, +0x4f, +0x53, +0x43, +0x20, +0x14, +0x4a, +0x4, +0x4d, +0x53, +0x43, +0x4e, +0x0, +0xa0, +0x9, +0x93, +0x4d, +0x44, +0x4e, +0x52, +0x0, +0xa4, +0x0, +0x70, +0x0, +0x60, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0xa2, +0x25, +0x95, +0x60, +0x4d, +0x44, +0x4e, +0x52, +0x70, +0x60, +0x4d, +0x53, +0x45, +0x4c, +0xa0, +0x13, +0x93, +0x4d, +0x49, +0x4e, +0x53, +0x1, +0x4d, +0x54, +0x46, +0x59, +0x60, +0x1, +0x70, +0x1, +0x4d, +0x49, +0x4e, +0x53, +0x72, +0x60, +0x1, +0x60, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x1, +0x14, +0x2d, +0x4d, +0x52, +0x53, +0x54, +0x1, +0x70, +0x0, +0x60, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0x70, +0x99, +0x68, +0x0, +0x4d, +0x53, +0x45, +0x4c, +0xa0, +0xb, +0x93, +0x4d, +0x45, +0x53, +0x5f, +0x1, +0x70, +0xa, +0xf, +0x60, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x60, +0x14, +0x41, +0x18, +0x4d, +0x43, +0x52, +0x53, +0x9, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0x70, +0x99, +0x68, +0x0, +0x4d, +0x53, +0x45, +0x4c, +0x8, +0x4d, +0x52, +0x36, +0x34, +0x11, +0x33, +0xa, +0x30, +0x8a, +0x2b, +0x0, +0x0, +0xc, +0x3, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0xfe, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x79, +0x0, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0xe, +0x4d, +0x49, +0x4e, +0x4c, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x12, +0x4d, +0x49, +0x4e, +0x48, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x26, +0x4c, +0x45, +0x4e, +0x4c, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x2a, +0x4c, +0x45, +0x4e, +0x48, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x16, +0x4d, +0x41, +0x58, +0x4c, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x1a, +0x4d, +0x41, +0x58, +0x48, +0x70, +0x4d, +0x52, +0x42, +0x48, +0x4d, +0x49, +0x4e, +0x48, +0x70, +0x4d, +0x52, +0x42, +0x4c, +0x4d, +0x49, +0x4e, +0x4c, +0x70, +0x4d, +0x52, +0x4c, +0x48, +0x4c, +0x45, +0x4e, +0x48, +0x70, +0x4d, +0x52, +0x4c, +0x4c, +0x4c, +0x45, +0x4e, +0x4c, +0x72, +0x4d, +0x49, +0x4e, +0x4c, +0x4c, +0x45, +0x4e, +0x4c, +0x4d, +0x41, +0x58, +0x4c, +0x72, +0x4d, +0x49, +0x4e, +0x48, +0x4c, +0x45, +0x4e, +0x48, +0x4d, +0x41, +0x58, +0x48, +0xa0, +0x14, +0x95, +0x4d, +0x41, +0x58, +0x4c, +0x4d, +0x49, +0x4e, +0x4c, +0x72, +0x4d, +0x41, +0x58, +0x48, +0x1, +0x4d, +0x41, +0x58, +0x48, +0xa0, +0x11, +0x95, +0x4d, +0x41, +0x58, +0x4c, +0x1, +0x74, +0x4d, +0x41, +0x58, +0x48, +0x1, +0x4d, +0x41, +0x58, +0x48, +0x74, +0x4d, +0x41, +0x58, +0x4c, +0x1, +0x4d, +0x41, +0x58, +0x4c, +0xa0, +0x44, +0x7, +0x93, +0x4d, +0x41, +0x58, +0x48, +0x0, +0x8, +0x4d, +0x52, +0x33, +0x32, +0x11, +0x1f, +0xa, +0x1c, +0x87, +0x17, +0x0, +0x0, +0xc, +0x3, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0xfe, +0xff, +0xff, +0xff, +0x0, +0x0, +0x0, +0x0, +0xff, +0xff, +0xff, +0xff, +0x79, +0x0, +0x8a, +0x4d, +0x52, +0x33, +0x32, +0xa, +0xa, +0x4d, +0x49, +0x4e, +0x5f, +0x8a, +0x4d, +0x52, +0x33, +0x32, +0xa, +0xe, +0x4d, +0x41, +0x58, +0x5f, +0x8a, +0x4d, +0x52, +0x33, +0x32, +0xa, +0x16, +0x4c, +0x45, +0x4e, +0x5f, +0x70, +0x4d, +0x49, +0x4e, +0x4c, +0x4d, +0x49, +0x4e, +0x5f, +0x70, +0x4d, +0x41, +0x58, +0x4c, +0x4d, +0x41, +0x58, +0x5f, +0x70, +0x4c, +0x45, +0x4e, +0x4c, +0x4c, +0x45, +0x4e, +0x5f, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x4d, +0x52, +0x33, +0x32, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x4d, +0x52, +0x36, +0x34, +0x14, +0x24, +0x4d, +0x50, +0x58, +0x4d, +0x1, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0x70, +0x99, +0x68, +0x0, +0x4d, +0x53, +0x45, +0x4c, +0x70, +0x4d, +0x50, +0x58, +0x5f, +0x60, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x60, +0x14, +0x28, +0x4d, +0x4f, +0x53, +0x54, +0x4, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0x70, +0x99, +0x68, +0x0, +0x4d, +0x53, +0x45, +0x4c, +0x70, +0x69, +0x4d, +0x4f, +0x45, +0x56, +0x70, +0x6a, +0x4d, +0x4f, +0x53, +0x43, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0x10, 0x45, 0xd, 0x5f, diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index 054b035b08..e1cee5d89a 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -405,13 +405,12 @@ DefinitionBlock ( #include "hw/acpi/pc-hotplug.h" #define CPU_STATUS_BASE ICH9_CPU_HOTPLUG_IO_BASE #include "acpi-dsdt-cpu-hotplug.dsl" +#include "acpi-dsdt-mem-hotplug.dsl" /**************************************************************** * General purpose events ****************************************************************/ - External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj) - Scope(\_GPE) { Name(_HID, "ACPI0006") diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated index c9eb4ac6ad..4807bdf484 100644 --- a/hw/i386/q35-acpi-dsdt.hex.generated +++ b/hw/i386/q35-acpi-dsdt.hex.generated @@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x53, 0x44, 0x54, -0xe5, -0x1c, +0xf6, +0x1f, 0x0, 0x0, 0x1, -0xb7, +0x91, 0x42, 0x58, 0x50, @@ -31,9 +31,9 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x4e, 0x54, 0x4c, -0x15, -0x11, -0x13, +0x28, +0x8, +0x14, 0x20, 0x10, 0x49, @@ -7234,6 +7234,791 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0xa, 0xb, 0x10, +0x40, +0x31, +0x2e, +0x5f, +0x53, +0x42, +0x5f, +0x50, +0x43, +0x49, +0x30, +0x5b, +0x82, +0x43, +0x30, +0x4d, +0x48, +0x50, +0x44, +0x8, +0x5f, +0x48, +0x49, +0x44, +0xd, +0x50, +0x4e, +0x50, +0x30, +0x41, +0x30, +0x36, +0x0, +0x8, +0x5f, +0x55, +0x49, +0x44, +0xd, +0x4d, +0x65, +0x6d, +0x6f, +0x72, +0x79, +0x20, +0x68, +0x6f, +0x74, +0x70, +0x6c, +0x75, +0x67, +0x20, +0x72, +0x65, +0x73, +0x6f, +0x75, +0x72, +0x63, +0x65, +0x73, +0x0, +0x5b, +0x80, +0x48, +0x50, +0x4d, +0x52, +0x1, +0xb, +0x0, +0xa, +0xa, +0x18, +0x8, +0x5f, +0x43, +0x52, +0x53, +0x11, +0xd, +0xa, +0xa, +0x47, +0x1, +0x0, +0xa, +0x0, +0xa, +0x0, +0x18, +0x79, +0x0, +0x14, +0x13, +0x5f, +0x53, +0x54, +0x41, +0x0, +0xa0, +0x9, +0x93, +0x4d, +0x44, +0x4e, +0x52, +0x0, +0xa4, +0x0, +0xa4, +0xa, +0xb, +0x5b, +0x81, +0x1f, +0x48, +0x50, +0x4d, +0x52, +0x3, +0x4d, +0x52, +0x42, +0x4c, +0x20, +0x4d, +0x52, +0x42, +0x48, +0x20, +0x4d, +0x52, +0x4c, +0x4c, +0x20, +0x4d, +0x52, +0x4c, +0x48, +0x20, +0x4d, +0x50, +0x58, +0x5f, +0x20, +0x5b, +0x81, +0x13, +0x48, +0x50, +0x4d, +0x52, +0x1, +0x0, +0x40, +0xa, +0x4d, +0x45, +0x53, +0x5f, +0x1, +0x4d, +0x49, +0x4e, +0x53, +0x1, +0x5b, +0x1, +0x4d, +0x4c, +0x43, +0x4b, +0x0, +0x5b, +0x81, +0x15, +0x48, +0x50, +0x4d, +0x52, +0x3, +0x4d, +0x53, +0x45, +0x4c, +0x20, +0x4d, +0x4f, +0x45, +0x56, +0x20, +0x4d, +0x4f, +0x53, +0x43, +0x20, +0x14, +0x4a, +0x4, +0x4d, +0x53, +0x43, +0x4e, +0x0, +0xa0, +0x9, +0x93, +0x4d, +0x44, +0x4e, +0x52, +0x0, +0xa4, +0x0, +0x70, +0x0, +0x60, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0xa2, +0x25, +0x95, +0x60, +0x4d, +0x44, +0x4e, +0x52, +0x70, +0x60, +0x4d, +0x53, +0x45, +0x4c, +0xa0, +0x13, +0x93, +0x4d, +0x49, +0x4e, +0x53, +0x1, +0x4d, +0x54, +0x46, +0x59, +0x60, +0x1, +0x70, +0x1, +0x4d, +0x49, +0x4e, +0x53, +0x72, +0x60, +0x1, +0x60, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x1, +0x14, +0x2d, +0x4d, +0x52, +0x53, +0x54, +0x1, +0x70, +0x0, +0x60, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0x70, +0x99, +0x68, +0x0, +0x4d, +0x53, +0x45, +0x4c, +0xa0, +0xb, +0x93, +0x4d, +0x45, +0x53, +0x5f, +0x1, +0x70, +0xa, +0xf, +0x60, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x60, +0x14, +0x41, +0x18, +0x4d, +0x43, +0x52, +0x53, +0x9, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0x70, +0x99, +0x68, +0x0, +0x4d, +0x53, +0x45, +0x4c, +0x8, +0x4d, +0x52, +0x36, +0x34, +0x11, +0x33, +0xa, +0x30, +0x8a, +0x2b, +0x0, +0x0, +0xc, +0x3, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0xfe, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0xff, +0x79, +0x0, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0xe, +0x4d, +0x49, +0x4e, +0x4c, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x12, +0x4d, +0x49, +0x4e, +0x48, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x26, +0x4c, +0x45, +0x4e, +0x4c, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x2a, +0x4c, +0x45, +0x4e, +0x48, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x16, +0x4d, +0x41, +0x58, +0x4c, +0x8a, +0x4d, +0x52, +0x36, +0x34, +0xa, +0x1a, +0x4d, +0x41, +0x58, +0x48, +0x70, +0x4d, +0x52, +0x42, +0x48, +0x4d, +0x49, +0x4e, +0x48, +0x70, +0x4d, +0x52, +0x42, +0x4c, +0x4d, +0x49, +0x4e, +0x4c, +0x70, +0x4d, +0x52, +0x4c, +0x48, +0x4c, +0x45, +0x4e, +0x48, +0x70, +0x4d, +0x52, +0x4c, +0x4c, +0x4c, +0x45, +0x4e, +0x4c, +0x72, +0x4d, +0x49, +0x4e, +0x4c, +0x4c, +0x45, +0x4e, +0x4c, +0x4d, +0x41, +0x58, +0x4c, +0x72, +0x4d, +0x49, +0x4e, +0x48, +0x4c, +0x45, +0x4e, +0x48, +0x4d, +0x41, +0x58, +0x48, +0xa0, +0x14, +0x95, +0x4d, +0x41, +0x58, +0x4c, +0x4d, +0x49, +0x4e, +0x4c, +0x72, +0x4d, +0x41, +0x58, +0x48, +0x1, +0x4d, +0x41, +0x58, +0x48, +0xa0, +0x11, +0x95, +0x4d, +0x41, +0x58, +0x4c, +0x1, +0x74, +0x4d, +0x41, +0x58, +0x48, +0x1, +0x4d, +0x41, +0x58, +0x48, +0x74, +0x4d, +0x41, +0x58, +0x4c, +0x1, +0x4d, +0x41, +0x58, +0x4c, +0xa0, +0x44, +0x7, +0x93, +0x4d, +0x41, +0x58, +0x48, +0x0, +0x8, +0x4d, +0x52, +0x33, +0x32, +0x11, +0x1f, +0xa, +0x1c, +0x87, +0x17, +0x0, +0x0, +0xc, +0x3, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0x0, +0xfe, +0xff, +0xff, +0xff, +0x0, +0x0, +0x0, +0x0, +0xff, +0xff, +0xff, +0xff, +0x79, +0x0, +0x8a, +0x4d, +0x52, +0x33, +0x32, +0xa, +0xa, +0x4d, +0x49, +0x4e, +0x5f, +0x8a, +0x4d, +0x52, +0x33, +0x32, +0xa, +0xe, +0x4d, +0x41, +0x58, +0x5f, +0x8a, +0x4d, +0x52, +0x33, +0x32, +0xa, +0x16, +0x4c, +0x45, +0x4e, +0x5f, +0x70, +0x4d, +0x49, +0x4e, +0x4c, +0x4d, +0x49, +0x4e, +0x5f, +0x70, +0x4d, +0x41, +0x58, +0x4c, +0x4d, +0x41, +0x58, +0x5f, +0x70, +0x4c, +0x45, +0x4e, +0x4c, +0x4c, +0x45, +0x4e, +0x5f, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x4d, +0x52, +0x33, +0x32, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x4d, +0x52, +0x36, +0x34, +0x14, +0x24, +0x4d, +0x50, +0x58, +0x4d, +0x1, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0x70, +0x99, +0x68, +0x0, +0x4d, +0x53, +0x45, +0x4c, +0x70, +0x4d, +0x50, +0x58, +0x5f, +0x60, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0xa4, +0x60, +0x14, +0x28, +0x4d, +0x4f, +0x53, +0x54, +0x4, +0x5b, +0x23, +0x4d, +0x4c, +0x43, +0x4b, +0xff, +0xff, +0x70, +0x99, +0x68, +0x0, +0x4d, +0x53, +0x45, +0x4c, +0x70, +0x69, +0x4d, +0x4f, +0x45, +0x56, +0x70, +0x6a, +0x4d, +0x4f, +0x53, +0x43, +0x5b, +0x27, +0x4d, +0x4c, +0x43, +0x4b, +0x10, 0x42, 0xa, 0x5f, diff --git a/hw/i386/ssdt-mem.hex.generated b/hw/i386/ssdt-mem.hex.generated index 00bd34d269..b3bfbbda09 100644 --- a/hw/i386/ssdt-mem.hex.generated +++ b/hw/i386/ssdt-mem.hex.generated @@ -11,7 +11,7 @@ static unsigned char ssdm_mem_aml[] = { 0x0, 0x0, 0x2, -0x71, +0x66, 0x42, 0x58, 0x50, @@ -34,9 +34,9 @@ static unsigned char ssdm_mem_aml[] = { 0x4e, 0x54, 0x4c, -0x15, -0x11, -0x13, +0x28, +0x8, +0x14, 0x20, 0x10, 0x42, diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl index 0fd448000b..1e3baaed3d 100644 --- a/hw/i386/ssdt-misc.dsl +++ b/hw/i386/ssdt-misc.dsl @@ -36,6 +36,8 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) + ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots + Name(MEMORY_SLOTS_NUMBER, 0x12345678) } @@ -117,167 +119,4 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) } } } - - External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj) - Scope(\_SB.PCI0) { - Device(MEMORY_HOTPLUG_DEVICE) { - Name(_HID, "PNP0A06") - Name(_UID, "Memory hotplug resources") - - ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots - Name(MEMORY_SLOTS_NUMBER, 0x12345678) - - /* Memory hotplug IO registers */ - OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO, - ACPI_MEMORY_HOTPLUG_BASE, - ACPI_MEMORY_HOTPLUG_IO_LEN) - - Name(_CRS, ResourceTemplate() { - IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE, - 0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO) - }) - - Method(_STA, 0) { - If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) { - Return(0x0) - } - /* present, functioning, decoding, not shown in UI */ - Return(0xB) - } - - Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) { - MEMORY_SLOT_ADDR_LOW, 32, // read only - MEMORY_SLOT_ADDR_HIGH, 32, // read only - MEMORY_SLOT_SIZE_LOW, 32, // read only - MEMORY_SLOT_SIZE_HIGH, 32, // read only - MEMORY_SLOT_PROXIMITY, 32, // read only - } - Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) { - 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 - } - - Mutex (MEMORY_SLOT_LOCK, 0) - Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) { - MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only - MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only - MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only - } - - Method(MEMORY_SLOT_SCAN_METHOD, 0) { - If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) { - Return(Zero) - } - - Store(Zero, Local0) // Mem devs iterrator - Acquire(MEMORY_SLOT_LOCK, 0xFFFF) - 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) - } - // TODO: handle memory eject request - Add(Local0, One, Local0) // goto next DIMM - } - Release(MEMORY_SLOT_LOCK) - Return(One) - } - - Method(MEMORY_SLOT_STATUS_METHOD, 1) { - Store(Zero, Local0) - - Acquire(MEMORY_SLOT_LOCK, 0xFFFF) - Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM - - If (LEqual(MEMORY_SLOT_ENABLED, One)) { - Store(0xF, Local0) - } - - Release(MEMORY_SLOT_LOCK) - Return(Local0) - } - - Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) { - Acquire(MEMORY_SLOT_LOCK, 0xFFFF) - Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM - - Name(MR64, ResourceTemplate() { - QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, - Cacheable, ReadWrite, - 0x0000000000000000, // Address Space Granularity - 0x0000000000000000, // Address Range Minimum - 0xFFFFFFFFFFFFFFFE, // Address Range Maximum - 0x0000000000000000, // Address Translation Offset - 0xFFFFFFFFFFFFFFFF, // Address Length - ,, MW64, AddressRangeMemory, TypeStatic) - }) - - CreateDWordField(MR64, 14, MINL) - CreateDWordField(MR64, 18, MINH) - CreateDWordField(MR64, 38, LENL) - CreateDWordField(MR64, 42, LENH) - CreateDWordField(MR64, 22, MAXL) - CreateDWordField(MR64, 26, MAXH) - - Store(MEMORY_SLOT_ADDR_HIGH, MINH) - Store(MEMORY_SLOT_ADDR_LOW, MINL) - Store(MEMORY_SLOT_SIZE_HIGH, LENH) - Store(MEMORY_SLOT_SIZE_LOW, LENL) - - // 64-bit math: MAX = MIN + LEN - 1 - Add(MINL, LENL, MAXL) - Add(MINH, LENH, MAXH) - If (LLess(MAXL, MINL)) { - Add(MAXH, One, MAXH) - } - If (LLess(MAXL, One)) { - Subtract(MAXH, One, MAXH) - } - Subtract(MAXL, One, MAXL) - - If (LEqual(MAXH, Zero)){ - Name(MR32, ResourceTemplate() { - DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, - Cacheable, ReadWrite, - 0x00000000, // Address Space Granularity - 0x00000000, // Address Range Minimum - 0xFFFFFFFE, // Address Range Maximum - 0x00000000, // Address Translation Offset - 0xFFFFFFFF, // Address Length - ,, MW32, AddressRangeMemory, TypeStatic) - }) - CreateDWordField(MR32, MW32._MIN, MIN) - CreateDWordField(MR32, MW32._MAX, MAX) - CreateDWordField(MR32, MW32._LEN, LEN) - Store(MINL, MIN) - Store(MAXL, MAX) - Store(LENL, LEN) - - Release(MEMORY_SLOT_LOCK) - Return(MR32) - } - - Release(MEMORY_SLOT_LOCK) - Return(MR64) - } - - Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) { - Acquire(MEMORY_SLOT_LOCK, 0xFFFF) - Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM - Store(MEMORY_SLOT_PROXIMITY, Local0) - Release(MEMORY_SLOT_LOCK) - Return(Local0) - } - - Method(MEMORY_SLOT_OST_METHOD, 4) { - Acquire(MEMORY_SLOT_LOCK, 0xFFFF) - Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM - Store(Arg1, MEMORY_SLOT_OST_EVENT) - Store(Arg2, MEMORY_SLOT_OST_STATUS) - Release(MEMORY_SLOT_LOCK) - } - } // Device() - } // Scope() } diff --git a/hw/i386/ssdt-misc.hex.generated b/hw/i386/ssdt-misc.hex.generated index ba4268a60b..cbcf61dcce 100644 --- a/hw/i386/ssdt-misc.hex.generated +++ b/hw/i386/ssdt-misc.hex.generated @@ -2,13 +2,13 @@ static unsigned char acpi_pci64_length[] = { 0x6f }; static unsigned char acpi_s4_pkg[] = { -0x8f +0x99 }; -static unsigned short ssdt_mctrl_nr_slots[] = { -0x1aa +static unsigned char ssdt_mctrl_nr_slots[] = { +0x7d }; static unsigned char acpi_s3_name[] = { -0x7c +0x86 }; static unsigned char acpi_pci32_start[] = { 0x2f @@ -21,12 +21,12 @@ static unsigned char ssdp_misc_aml[] = { 0x53, 0x44, 0x54, -0x7e, -0x4, +0x6c, +0x1, 0x0, 0x0, 0x1, -0x8b, +0x3, 0x42, 0x58, 0x50, @@ -49,12 +49,12 @@ static unsigned char ssdp_misc_aml[] = { 0x4e, 0x54, 0x4c, -0x15, -0x11, -0x13, +0x28, +0x8, +0x14, 0x20, 0x10, -0x42, +0x4c, 0x5, 0x5c, 0x0, @@ -136,6 +136,16 @@ static unsigned char ssdp_misc_aml[] = { 0x0, 0x0, 0x0, +0x8, +0x4d, +0x44, +0x4e, +0x52, +0xc, +0x78, +0x56, +0x34, +0x12, 0x10, 0x29, 0x5c, @@ -370,809 +380,13 @@ static unsigned char ssdp_misc_aml[] = { 0x49, 0x4f, 0x4d, -0x58, -0x10, -0x4b, -0x31, -0x5c, -0x2e, -0x5f, -0x53, -0x42, -0x5f, -0x50, -0x43, -0x49, -0x30, -0x5b, -0x82, -0x4d, -0x30, -0x4d, -0x48, -0x50, -0x44, -0x8, -0x5f, -0x48, -0x49, -0x44, -0xd, -0x50, -0x4e, -0x50, -0x30, -0x41, -0x30, -0x36, -0x0, -0x8, -0x5f, -0x55, -0x49, -0x44, -0xd, -0x4d, -0x65, -0x6d, -0x6f, -0x72, -0x79, -0x20, -0x68, -0x6f, -0x74, -0x70, -0x6c, -0x75, -0x67, -0x20, -0x72, -0x65, -0x73, -0x6f, -0x75, -0x72, -0x63, -0x65, -0x73, -0x0, -0x8, -0x4d, -0x44, -0x4e, -0x52, -0xc, -0x78, -0x56, -0x34, -0x12, -0x5b, -0x80, -0x48, -0x50, -0x4d, -0x52, -0x1, -0xb, -0x0, -0xa, -0xa, -0x18, -0x8, -0x5f, -0x43, -0x52, -0x53, -0x11, -0xd, -0xa, -0xa, -0x47, -0x1, -0x0, -0xa, -0x0, -0xa, -0x0, -0x18, -0x79, -0x0, -0x14, -0x13, -0x5f, -0x53, -0x54, -0x41, -0x0, -0xa0, -0x9, -0x93, -0x4d, -0x44, -0x4e, -0x52, -0x0, -0xa4, -0x0, -0xa4, -0xa, -0xb, -0x5b, -0x81, -0x1f, -0x48, -0x50, -0x4d, -0x52, -0x3, -0x4d, -0x52, -0x42, -0x4c, -0x20, -0x4d, -0x52, -0x42, -0x48, -0x20, -0x4d, -0x52, -0x4c, -0x4c, -0x20, -0x4d, -0x52, -0x4c, -0x48, -0x20, -0x4d, -0x50, -0x58, -0x5f, -0x20, -0x5b, -0x81, -0x13, -0x48, -0x50, -0x4d, -0x52, -0x1, -0x0, -0x40, -0xa, -0x4d, -0x45, -0x53, -0x5f, -0x1, -0x4d, -0x49, -0x4e, -0x53, -0x1, -0x5b, -0x1, -0x4d, -0x4c, -0x43, -0x4b, -0x0, -0x5b, -0x81, -0x15, -0x48, -0x50, -0x4d, -0x52, -0x3, -0x4d, -0x53, -0x45, -0x4c, -0x20, -0x4d, -0x4f, -0x45, -0x56, -0x20, -0x4d, -0x4f, -0x53, -0x43, -0x20, -0x14, -0x4a, -0x4, -0x4d, -0x53, -0x43, -0x4e, -0x0, -0xa0, -0x9, -0x93, -0x4d, -0x44, -0x4e, -0x52, -0x0, -0xa4, -0x0, -0x70, -0x0, -0x60, -0x5b, -0x23, -0x4d, -0x4c, -0x43, -0x4b, -0xff, -0xff, -0xa2, -0x25, -0x95, -0x60, -0x4d, -0x44, -0x4e, -0x52, -0x70, -0x60, -0x4d, -0x53, -0x45, -0x4c, -0xa0, -0x13, -0x93, -0x4d, -0x49, -0x4e, -0x53, -0x1, -0x4d, -0x54, -0x46, -0x59, -0x60, -0x1, -0x70, -0x1, -0x4d, -0x49, -0x4e, -0x53, -0x72, -0x60, -0x1, -0x60, -0x5b, -0x27, -0x4d, -0x4c, -0x43, -0x4b, -0xa4, -0x1, -0x14, -0x2d, -0x4d, -0x52, -0x53, -0x54, -0x1, -0x70, -0x0, -0x60, -0x5b, -0x23, -0x4d, -0x4c, -0x43, -0x4b, -0xff, -0xff, -0x70, -0x99, -0x68, -0x0, -0x4d, -0x53, -0x45, -0x4c, -0xa0, -0xb, -0x93, -0x4d, -0x45, -0x53, -0x5f, -0x1, -0x70, -0xa, -0xf, -0x60, -0x5b, -0x27, -0x4d, -0x4c, -0x43, -0x4b, -0xa4, -0x60, -0x14, -0x41, -0x18, -0x4d, -0x43, -0x52, -0x53, -0x9, -0x5b, -0x23, -0x4d, -0x4c, -0x43, -0x4b, -0xff, -0xff, -0x70, -0x99, -0x68, -0x0, -0x4d, -0x53, -0x45, -0x4c, -0x8, -0x4d, -0x52, -0x36, -0x34, -0x11, -0x33, -0xa, -0x30, -0x8a, -0x2b, -0x0, -0x0, -0xc, -0x3, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0xfe, -0xff, -0xff, -0xff, -0xff, -0xff, -0xff, -0xff, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0xff, -0xff, -0xff, -0xff, -0xff, -0xff, -0xff, -0xff, -0x79, -0x0, -0x8a, -0x4d, -0x52, -0x36, -0x34, -0xa, -0xe, -0x4d, -0x49, -0x4e, -0x4c, -0x8a, -0x4d, -0x52, -0x36, -0x34, -0xa, -0x12, -0x4d, -0x49, -0x4e, -0x48, -0x8a, -0x4d, -0x52, -0x36, -0x34, -0xa, -0x26, -0x4c, -0x45, -0x4e, -0x4c, -0x8a, -0x4d, -0x52, -0x36, -0x34, -0xa, -0x2a, -0x4c, -0x45, -0x4e, -0x48, -0x8a, -0x4d, -0x52, -0x36, -0x34, -0xa, -0x16, -0x4d, -0x41, -0x58, -0x4c, -0x8a, -0x4d, -0x52, -0x36, -0x34, -0xa, -0x1a, -0x4d, -0x41, -0x58, -0x48, -0x70, -0x4d, -0x52, -0x42, -0x48, -0x4d, -0x49, -0x4e, -0x48, -0x70, -0x4d, -0x52, -0x42, -0x4c, -0x4d, -0x49, -0x4e, -0x4c, -0x70, -0x4d, -0x52, -0x4c, -0x48, -0x4c, -0x45, -0x4e, -0x48, -0x70, -0x4d, -0x52, -0x4c, -0x4c, -0x4c, -0x45, -0x4e, -0x4c, -0x72, -0x4d, -0x49, -0x4e, -0x4c, -0x4c, -0x45, -0x4e, -0x4c, -0x4d, -0x41, -0x58, -0x4c, -0x72, -0x4d, -0x49, -0x4e, -0x48, -0x4c, -0x45, -0x4e, -0x48, -0x4d, -0x41, -0x58, -0x48, -0xa0, -0x14, -0x95, -0x4d, -0x41, -0x58, -0x4c, -0x4d, -0x49, -0x4e, -0x4c, -0x72, -0x4d, -0x41, -0x58, -0x48, -0x1, -0x4d, -0x41, -0x58, -0x48, -0xa0, -0x11, -0x95, -0x4d, -0x41, -0x58, -0x4c, -0x1, -0x74, -0x4d, -0x41, -0x58, -0x48, -0x1, -0x4d, -0x41, -0x58, -0x48, -0x74, -0x4d, -0x41, -0x58, -0x4c, -0x1, -0x4d, -0x41, -0x58, -0x4c, -0xa0, -0x44, -0x7, -0x93, -0x4d, -0x41, -0x58, -0x48, -0x0, -0x8, -0x4d, -0x52, -0x33, -0x32, -0x11, -0x1f, -0xa, -0x1c, -0x87, -0x17, -0x0, -0x0, -0xc, -0x3, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0x0, -0xfe, -0xff, -0xff, -0xff, -0x0, -0x0, -0x0, -0x0, -0xff, -0xff, -0xff, -0xff, -0x79, -0x0, -0x8a, -0x4d, -0x52, -0x33, -0x32, -0xa, -0xa, -0x4d, -0x49, -0x4e, -0x5f, -0x8a, -0x4d, -0x52, -0x33, -0x32, -0xa, -0xe, -0x4d, -0x41, -0x58, -0x5f, -0x8a, -0x4d, -0x52, -0x33, -0x32, -0xa, -0x16, -0x4c, -0x45, -0x4e, -0x5f, -0x70, -0x4d, -0x49, -0x4e, -0x4c, -0x4d, -0x49, -0x4e, -0x5f, -0x70, -0x4d, -0x41, -0x58, -0x4c, -0x4d, -0x41, -0x58, -0x5f, -0x70, -0x4c, -0x45, -0x4e, -0x4c, -0x4c, -0x45, -0x4e, -0x5f, -0x5b, -0x27, -0x4d, -0x4c, -0x43, -0x4b, -0xa4, -0x4d, -0x52, -0x33, -0x32, -0x5b, -0x27, -0x4d, -0x4c, -0x43, -0x4b, -0xa4, -0x4d, -0x52, -0x36, -0x34, -0x14, -0x24, -0x4d, -0x50, -0x58, -0x4d, -0x1, -0x5b, -0x23, -0x4d, -0x4c, -0x43, -0x4b, -0xff, -0xff, -0x70, -0x99, -0x68, -0x0, -0x4d, -0x53, -0x45, -0x4c, -0x70, -0x4d, -0x50, -0x58, -0x5f, -0x60, -0x5b, -0x27, -0x4d, -0x4c, -0x43, -0x4b, -0xa4, -0x60, -0x14, -0x28, -0x4d, -0x4f, -0x53, -0x54, -0x4, -0x5b, -0x23, -0x4d, -0x4c, -0x43, -0x4b, -0xff, -0xff, -0x70, -0x99, -0x68, -0x0, -0x4d, -0x53, -0x45, -0x4c, -0x70, -0x69, -0x4d, -0x4f, -0x45, -0x56, -0x70, -0x6a, -0x4d, -0x4f, -0x53, -0x43, -0x5b, -0x27, -0x4d, -0x4c, -0x43, -0x4b +0x58 }; static unsigned char ssdt_isa_pest[] = { -0xd0 +0xda }; static unsigned char acpi_s4_name[] = { -0x88 +0x92 }; static unsigned char acpi_pci64_start[] = { 0x4d diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT index d37ec34454..ee9cc6781c 100644 Binary files a/tests/acpi-test-data/pc/DSDT and b/tests/acpi-test-data/pc/DSDT differ diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT index eb2d8b698c..558e4c85b0 100644 Binary files a/tests/acpi-test-data/pc/SSDT and b/tests/acpi-test-data/pc/SSDT differ diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT index 2d2bc4adaf..ef0c75f423 100644 Binary files a/tests/acpi-test-data/q35/DSDT and b/tests/acpi-test-data/q35/DSDT differ diff --git a/tests/acpi-test-data/q35/SSDT b/tests/acpi-test-data/q35/SSDT index 778b79bf42..4e45510181 100644 Binary files a/tests/acpi-test-data/q35/SSDT and b/tests/acpi-test-data/q35/SSDT differ -- cgit v1.2.1 From 8e815eeefe205155f5561ddd06a29c75819d2ca8 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Tue, 18 Nov 2014 10:47:57 +0800 Subject: pcie: fix typo in pcie_cap_deverr_init() Reported-by: https://bugs.launchpad.net/qemu/+bug/1393440 Signed-off-by: Gonglei Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 58455bd854..fbba589aa1 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -145,7 +145,7 @@ void pcie_cap_deverr_init(PCIDevice *dev) PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE); pci_long_test_and_set_mask(dev->w1cmask + pos + PCI_EXP_DEVSTA, PCI_EXP_DEVSTA_CED | PCI_EXP_DEVSTA_NFED | - PCI_EXP_DEVSTA_URD | PCI_EXP_DEVSTA_URD); + PCI_EXP_DEVSTA_FED | PCI_EXP_DEVSTA_URD); } void pcie_cap_deverr_reset(PCIDevice *dev) -- cgit v1.2.1 From 6c150fbd341ac10b8559abcfd5915cfff17b70c6 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Thu, 20 Nov 2014 16:55:54 +0800 Subject: pcie: fix improper use of negative value Signed-off-by: Gonglei Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index fbba589aa1..1abbbb192e 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -229,7 +229,7 @@ static void pcie_cap_slot_hotplug_common(PCIDevice *hotplug_dev, /* the slot is electromechanically locked. * This error is propagated up to qdev and then to HMP/QMP. */ - error_setg_errno(errp, -EBUSY, "slot is electromechanically locked"); + error_setg_errno(errp, EBUSY, "slot is electromechanically locked"); } } -- cgit v1.2.1 From dd0247e09a542d2a7ba6e390c70b5616edb9ec56 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 10 Nov 2014 16:20:50 +0000 Subject: pc: acpi: mark all possible CPUs as enabled in SRAT If QEMU is started with -numa ... Windows only notices that CPU has been hot-added but it will not online such CPUs. It's caused by the fact that possible CPUs are flagged as not enabled in SRAT and Windows honoring that information doesn't use corresponding CPU. ACPI 5.0 Spec regarding to flag says: " Table 5-47 Local APIC Flags ... Enabled: if zero, this processor is unusable, and the operating system support will not attempt to use it. " Fix QEMU to adhere to spec and mark possible CPUs as enabled in SRAT. With that Windows onlines hot-added CPUs as expected. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 92a36e3b9b..b37a397820 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1270,8 +1270,7 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, } static void -build_srat(GArray *table_data, GArray *linker, - AcpiCpuInfo *cpu, PcGuestInfo *guest_info) +build_srat(GArray *table_data, GArray *linker, PcGuestInfo *guest_info) { AcpiSystemResourceAffinityTable *srat; AcpiSratProcessorAffinity *core; @@ -1301,11 +1300,7 @@ build_srat(GArray *table_data, GArray *linker, core->proximity_lo = curnode; memset(core->proximity_hi, 0, 3); core->local_sapic_eid = 0; - if (test_bit(i, cpu->found_cpus)) { - core->flags = cpu_to_le32(1); - } else { - core->flags = cpu_to_le32(0); - } + core->flags = cpu_to_le32(1); } @@ -1623,7 +1618,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) } if (guest_info->numa_nodes) { acpi_add_table(table_offsets, tables->table_data); - build_srat(tables->table_data, tables->linker, &cpu, guest_info); + build_srat(tables->table_data, tables->linker, guest_info); } if (acpi_get_mcfg(&mcfg)) { acpi_add_table(table_offsets, tables->table_data); -- cgit v1.2.1