From patchwork Fri Aug 12 06:54:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Guangrong X-Patchwork-Id: 658666 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3s9nQF2jc8z9stY for ; Sat, 13 Aug 2016 00:31:49 +1000 (AEST) Received: from localhost ([::1]:52443 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bYDUx-0005JA-9C for incoming@patchwork.ozlabs.org; Fri, 12 Aug 2016 10:31:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33045) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bYDKc-0004ZN-ER for qemu-devel@nongnu.org; Fri, 12 Aug 2016 10:21:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bYDKR-0001jW-Sd for qemu-devel@nongnu.org; Fri, 12 Aug 2016 10:21:06 -0400 Received: from mga04.intel.com ([192.55.52.120]:25524) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bYDKR-0001g8-LM for qemu-devel@nongnu.org; Fri, 12 Aug 2016 10:20:55 -0400 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP; 12 Aug 2016 00:07:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,509,1464678000"; d="scan'208";a="154662660" Received: from xiaoreal1.sh.intel.com (HELO xiaoreal1.sh.intel.com.sh.intel.com) ([10.239.48.133]) by fmsmga004.fm.intel.com with ESMTP; 12 Aug 2016 00:07:19 -0700 From: Xiao Guangrong To: pbonzini@redhat.com, imammedo@redhat.com Date: Fri, 12 Aug 2016 14:54:07 +0800 Message-Id: <1470984850-66891-6-git-send-email-guangrong.xiao@linux.intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1470984850-66891-1-git-send-email-guangrong.xiao@linux.intel.com> References: <1470984850-66891-1-git-send-email-guangrong.xiao@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.120 Subject: [Qemu-devel] [PATCH v2 5/8] pc-dimm: introduce prepare_unplug() callback X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiao Guangrong , ehabkost@redhat.com, kvm@vger.kernel.org, mst@redhat.com, gleb@kernel.org, mtosatti@redhat.com, qemu-devel@nongnu.org, stefanha@redhat.com, dan.j.williams@intel.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We should let nvdimm acpi know which nvdimm device is being unplugged before QEMU interrupts the guest so that nvdimm acpi can update its FIT properly prepare_unplug() callback is introduced exactly for this purpose then the being removed device is skipped when guest reads FIT Signed-off-by: Xiao Guangrong --- hw/acpi/ich9.c | 3 +++ hw/acpi/nvdimm.c | 9 +++++++++ hw/acpi/piix4.c | 3 +++ hw/mem/nvdimm.c | 8 ++++++++ hw/mem/pc-dimm.c | 5 +++++ include/hw/mem/nvdimm.h | 3 +++ include/hw/mem/pc-dimm.h | 1 + 7 files changed, 32 insertions(+) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index e5a3c18..af08471 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -511,6 +511,9 @@ void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, if (lpc->pm.acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dev); + + ddc->prepare_unplug(dev); acpi_memory_unplug_request_cb(hotplug_dev, &lpc->pm.acpi_memory_hotplug, dev, errp); diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index f6f8413..0f569c7 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -355,6 +355,15 @@ static GArray *nvdimm_build_device_structure(GSList *device_list) for (; device_list; device_list = device_list->next) { DeviceState *dev = device_list->data; + NVDIMMDevice *nvdimm = NVDIMM(dev); + + /* + * the nvdimm device which is being removed should not be included + * in nfit/fit. + */ + if (nvdimm->is_removing) { + continue; + } /* build System Physical Address Range Structure. */ nvdimm_build_structure_spa(structures, dev); diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 2adc246..57e19e6 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -400,6 +400,9 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, if (s->acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dev); + + ddc->prepare_unplug(dev); acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c index 7895805..5bc81fe 100644 --- a/hw/mem/nvdimm.c +++ b/hw/mem/nvdimm.c @@ -146,6 +146,13 @@ static MemoryRegion *nvdimm_get_vmstate_memory_region(PCDIMMDevice *dimm) return host_memory_backend_get_memory(dimm->hostmem, &error_abort); } +static void nvdimm_prepare_unplug(DeviceState *dev) +{ + NVDIMMDevice *nvdimm = NVDIMM(dev); + + nvdimm->is_removing = true; +} + static void nvdimm_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -158,6 +165,7 @@ static void nvdimm_class_init(ObjectClass *oc, void *data) ddc->realize = nvdimm_realize; ddc->get_memory_region = nvdimm_get_memory_region; ddc->get_vmstate_memory_region = nvdimm_get_vmstate_memory_region; + ddc->prepare_unplug = nvdimm_prepare_unplug; nvc->read_label_data = nvdimm_read_label_data; nvc->write_label_data = nvdimm_write_label_data; diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 9e8dab0..09364c9 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -436,6 +436,10 @@ static MemoryRegion *pc_dimm_get_vmstate_memory_region(PCDIMMDevice *dimm) return host_memory_backend_get_memory(dimm->hostmem, &error_abort); } +static void pc_dimm_prepare_unplug(DeviceState *dev) +{ +} + static void pc_dimm_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -448,6 +452,7 @@ static void pc_dimm_class_init(ObjectClass *oc, void *data) ddc->get_memory_region = pc_dimm_get_memory_region; ddc->get_vmstate_memory_region = pc_dimm_get_vmstate_memory_region; + ddc->prepare_unplug = pc_dimm_prepare_unplug; } static TypeInfo pc_dimm_info = { diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h index 63a2b20..e626199 100644 --- a/include/hw/mem/nvdimm.h +++ b/include/hw/mem/nvdimm.h @@ -71,6 +71,9 @@ struct NVDIMMDevice { * guest via ACPI NFIT and _FIT method if NVDIMM hotplug is supported. */ MemoryRegion nvdimm_mr; + + /* the device is being unplugged. */ + bool is_removing; }; typedef struct NVDIMMDevice NVDIMMDevice; diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index 1e483f2..34797ba 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -73,6 +73,7 @@ typedef struct PCDIMMDeviceClass { void (*realize)(PCDIMMDevice *dimm, Error **errp); MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm); MemoryRegion *(*get_vmstate_memory_region)(PCDIMMDevice *dimm); + void (*prepare_unplug)(DeviceState *dev); } PCDIMMDeviceClass; /**