From patchwork Thu Nov 21 02:38:42 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Mammedov X-Patchwork-Id: 292933 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1A9162C0126 for ; Thu, 21 Nov 2013 13:49:10 +1100 (EST) Received: from localhost ([::1]:58205 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VjKKJ-0002Zc-Jq for incoming@patchwork.ozlabs.org; Wed, 20 Nov 2013 21:49:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54951) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VjKD8-0007nR-6B for qemu-devel@nongnu.org; Wed, 20 Nov 2013 21:41:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VjKD2-0004Br-5x for qemu-devel@nongnu.org; Wed, 20 Nov 2013 21:41:42 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52225) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VjKD1-0004BS-Ck for qemu-devel@nongnu.org; Wed, 20 Nov 2013 21:41:35 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rAL2fQIA021642 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 20 Nov 2013 21:41:26 -0500 Received: from dell-pet610-01.lab.eng.brq.redhat.com (dell-pet610-01.lab.eng.brq.redhat.com [10.34.42.20]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rAL2djGD031356; Wed, 20 Nov 2013 21:41:22 -0500 From: Igor Mammedov To: qemu-devel@nongnu.org Date: Thu, 21 Nov 2013 03:38:42 +0100 Message-Id: <1385001528-12003-22-git-send-email-imammedo@redhat.com> In-Reply-To: <1385001528-12003-1-git-send-email-imammedo@redhat.com> References: <1385001528-12003-1-git-send-email-imammedo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: peter.maydell@linaro.org, stefanha@redhat.com, mst@redhat.com, chegu_vinod@hp.com, stefanb@linux.vnet.ibm.com, mjt@tls.msk.ru, mdroth@linux.vnet.ibm.com, armbru@redhat.com, vasilis.liaskovitis@profitbricks.com, quintela@redhat.com, kraxel@redhat.com, aliguori@amazon.com, hutao@cn.fujitsu.com, pbonzini@redhat.com, marcel.a@redhat.com, lcapitulino@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add DimmBus for memory hotplug below 4Gb or above 4Gb depending on initial memory size and hotplug memory size. * if ram_size is less than 32-bit PCI hole start, reserve hotplug memory region as [ram_size,32bit-PCIhole-start) if hotplug memory region fits there, otherwise reserve hotplug memory region after "0x100000000ULL + above_4g_mem_size" * setup memory hotplug callback to pass event to ACPI hadware. Signed-off-by: Igor Mammedov --- hw/i386/pc.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ hw/i386/pc_piix.c | 6 ++++- hw/pci-host/piix.c | 13 ++++++++++- include/hw/i386/pc.h | 16 +++++++++++++ include/hw/pci-host/piix.h | 2 + 5 files changed, 87 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 85d0862..306ed22 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1236,6 +1236,58 @@ void pc_acpi_dev_memory_hotplug_init(DimmBus *hotplug_mem_bus, } } +static +void pc_hotplug_memory_init_impl(Object *owner, + MemoryRegion *system_memory, + ram_addr_t low_hotplug_mem_start, + ram_addr_t low_hotplug_mem_end, + DimmBus *hotplug_mem_bus, + ram_addr_t *high_mem_end) +{ + QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL); + ram_addr_t ram_size = qemu_opt_get_size(opts, "mem", 0); + ram_addr_t maxmem = qemu_opt_get_size(opts, "maxmem", 0); + ram_addr_t hotplug_mem_size; + + if (maxmem <= ram_size) { + /* Disable ACPI migration code and creation of memory devices in SSDT */ + qemu_opt_set_number(opts, "slots", 0); + return; + } + + hotplug_mem_size = maxmem - ram_size; + if (hotplug_mem_size <= (low_hotplug_mem_end - low_hotplug_mem_start)) { + hotplug_mem_bus->base = low_hotplug_mem_start; + } else { + hotplug_mem_bus->base = ROUND_UP(*high_mem_end, 1ULL << 30); + *high_mem_end = hotplug_mem_bus->base + hotplug_mem_size; + } + + memory_region_init(&hotplug_mem_bus->as, owner, "hotplug-memory", + hotplug_mem_size); + memory_region_add_subregion(system_memory, hotplug_mem_bus->base, + &hotplug_mem_bus->as); +} + +pc_hotplug_memory_init_fn pc_hotplug_memory_init = pc_hotplug_memory_init_impl; + +void pc_hotplug_memory_init_compat_1_7(Object *owner, + MemoryRegion *system_memory, + ram_addr_t low_hotplug_mem_start, + ram_addr_t low_hotplug_mem_end, + DimmBus *hotplug_mem_bus, + ram_addr_t *high_mem_end) +{ + QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL); + /* + * clearing slots tells acpi code that memory hotplug is disabled, + * so there is not need to migrate its state and create related + * SSDT table objects + */ + qemu_opt_set_number(opts, "slots", 0); +} + + qemu_irq *pc_allocate_cpu_irq(void) { return qemu_allocate_irqs(pic_irq_request, NULL, 1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e1fe85a..7d30c12 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -48,6 +48,8 @@ #include "exec/address-spaces.h" #include "hw/acpi/acpi.h" #include "cpu.h" +#include "hw/acpi/piix4.h" +#include "hw/pci-host/piix.h" #ifdef CONFIG_XEN # include #endif @@ -230,6 +232,8 @@ static void pc_init1(QEMUMachineInitArgs *args, gsi[9], *smi_irq, kvm_enabled(), fw_cfg); smbus_eeprom_init(smbus, 8, NULL, 0); + pc_acpi_dev_memory_hotplug_init(&i440fx_state->hotplug_mem_bus, + piix4_mem_hotplug, piix4_pm_find()); } if (pci_enabled) { @@ -250,6 +254,7 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args) { smbios_type1_defaults = false; pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7; + pc_hotplug_memory_init = pc_hotplug_memory_init_compat_1_7; } static void pc_compat_1_6(QEMUMachineInitArgs *args) @@ -367,7 +372,6 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args) .desc = "Standard PC (i440FX + PIIX, 1996)", \ .hot_add_cpu = pc_hot_add_cpu - #define PC_I440FX_1_8_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS static QEMUMachine pc_i440fx_machine_v1_8 = { PC_I440FX_1_8_MACHINE_OPTIONS, diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 8351430..2f2785b 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -282,6 +282,11 @@ static int i440fx_initfn(PCIDevice *dev) dev->config[I440FX_SMRAM] = 0x02; cpu_smm_register(&i440fx_set_smm, d); + + qbus_create_inplace(&d->hotplug_mem_bus, + sizeof(d->hotplug_mem_bus), + TYPE_DIMM_BUS, DEVICE(d), + "hotplug-membus"); return 0; } @@ -303,6 +308,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, PCII440FXState *f; unsigned i; I440FXState *i440fx; + ram_addr_t below_4g_mem_size = ram_size - above_4g_mem_size; + ram_addr_t high_memory_end = 0x100000000ULL + above_4g_mem_size; dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE); s = PCI_HOST_BRIDGE(dev); @@ -330,10 +337,14 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, i440fx->pci_info.w32.begin = 0xe0000000; } + pc_hotplug_memory_init(OBJECT(f), f->system_memory, + below_4g_mem_size, i440fx->pci_info.w32.begin, + &f->hotplug_mem_bus, &high_memory_end); + /* setup pci memory mapping */ pc_pci_as_mapping_init(OBJECT(f), f->system_memory, f->pci_address_space, - 0x100000000ULL + above_4g_mem_size); + high_memory_end); memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region", f->pci_address_space, 0xa0000, 0x20000); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 0c86ee5..fea7d60 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -154,6 +154,22 @@ void pc_acpi_dev_memory_hotplug_init(DimmBus *hotplug_mem_bus, hotplug_fn hotplug, Object *acpi_dev); +typedef +void (*pc_hotplug_memory_init_fn)(Object *owner, + MemoryRegion *system_memory, + ram_addr_t low_hotplug_mem_start, + ram_addr_t low_hotplug_mem_end, + DimmBus *hotplug_mem_bus, + ram_addr_t *high_mem_end); +extern pc_hotplug_memory_init_fn pc_hotplug_memory_init; + +void pc_hotplug_memory_init_compat_1_7(Object *owner, + MemoryRegion *system_memory, + ram_addr_t low_hotplug_mem_start, + ram_addr_t low_hotplug_mem_end, + DimmBus *hotplug_mem_bus, + ram_addr_t *high_mem_end); + qemu_irq *pc_allocate_cpu_irq(void); DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus); void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, diff --git a/include/hw/pci-host/piix.h b/include/hw/pci-host/piix.h index 1155996..a301c9d 100644 --- a/include/hw/pci-host/piix.h +++ b/include/hw/pci-host/piix.h @@ -6,6 +6,7 @@ #include "hw/pci/pci.h" #include "hw/pci/pci_host.h" #include "hw/pci-host/pam.h" +#include "hw/mem/dimm.h" #define TYPE_I440FX_PCI_DEVICE "i440FX" #define I440FX_PCI_DEVICE(obj) \ @@ -22,6 +23,7 @@ struct PCII440FXState { PAMMemoryRegion pam_regions[13]; MemoryRegion smram_region; uint8_t smm_enabled; + DimmBus hotplug_mem_bus; }; #endif