From patchwork Mon Sep 11 04:41:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haozhong Zhang X-Patchwork-Id: 9946645 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D00EC6035D for ; Mon, 11 Sep 2017 04:43:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5A2328ABB for ; Mon, 11 Sep 2017 04:43:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9DFA28AD7; Mon, 11 Sep 2017 04:43:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 312F428ABB for ; Mon, 11 Sep 2017 04:43:58 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1drGYE-0006I1-DI; Mon, 11 Sep 2017 04:42:26 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1drGYC-0006Ew-O8 for xen-devel@lists.xen.org; Mon, 11 Sep 2017 04:42:24 +0000 Received: from [85.158.137.68] by server-1.bemta-3.messagelabs.com id 3A/B8-02048-03416B95; Mon, 11 Sep 2017 04:42:24 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpgkeJIrShJLcpLzFFi42Jpa+uQ19UX2RZ p8P2+gMWSj4tZHBg9ju7+zRTAGMWamZeUX5HAmjH3/THWgpdGFQfmXWVsYPyu1sXIySEkUCnx /cwONhBbQoBX4siyGawQdoDEu9Wf2bsYuYBqehklnvT2MoMk2AT0JVY8PghUxMEhImAs0XbTG aSGWWAls8S8CQuZQGqEBaIkHvTOZgexWQRUJV7tusMIYvMK2EpM23ieEWKBvMSutotgyzgF7C T6Wt4zQxxkK7F25QOWCYy8CxgZVjFqFKcWlaUW6RqZ6SUVZaZnlOQmZuboGhoY6+WmFhcnpqf mJCYV6yXn525iBIZDPQMD4w7Ghr1+hxglOZiURHnfHd8SKcSXlJ9SmZFYnBFfVJqTWnyIUYaD Q0mC967QtkghwaLU9NSKtMwcYGDCpCU4eJREeKNA0rzFBYm5xZnpEKlTjMYcxzZd/sPE0XHz7 h8mIZa8/LxUKXHe6SClAiClGaV5cINgEXOJUVZKmJeRgYFBiKcgtSg3swRV/hWjOAejkjDvRZ ApPJl5JXD7XgGdwgR0Cs+lLSCnlCQipKQaGBeFvb9+Zrm4h9T6arEeg74Jz2R68pMdojRVz3d 7bGgwczqtye/L8eSYMrNUizHL76cdOdscdSxic3a4ldY5z778aF7ruSOCVeYHlCcdE7j5rO3j rOdrr7BvbpivE75tcRu7yYIPsbb7V0tvaNwjELS/8k1T8s1rR16fT7fYanCL8SyX8jsJbyWW4 oxEQy3mouJEAMMikBWTAgAA X-Env-Sender: haozhong.zhang@intel.com X-Msg-Ref: server-8.tower-31.messagelabs.com!1505104925!114186094!7 X-Originating-IP: [134.134.136.31] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 33510 invoked from network); 11 Sep 2017 04:42:22 -0000 Received: from mga06.intel.com (HELO mga06.intel.com) (134.134.136.31) by server-8.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 11 Sep 2017 04:42:22 -0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP; 10 Sep 2017 21:42:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.42,376,1500966000"; d="scan'208"; a="1217079145" Received: from hz-desktop.sh.intel.com (HELO localhost) ([10.239.159.142]) by fmsmga002.fm.intel.com with ESMTP; 10 Sep 2017 21:42:20 -0700 From: Haozhong Zhang To: qemu-devel@nongnu.org, xen-devel@lists.xen.org Date: Mon, 11 Sep 2017 12:41:53 +0800 Message-Id: <20170911044157.15403-7-haozhong.zhang@intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170911044157.15403-1-haozhong.zhang@intel.com> References: <20170911044157.15403-1-haozhong.zhang@intel.com> Cc: Haozhong Zhang , Stefano Stabellini , Eduardo Habkost , "Michael S. Tsirkin" , Paolo Bonzini , Anthony Perard , Chao Peng , Dan Williams , Richard Henderson Subject: [Xen-devel] [RFC QEMU PATCH v3 06/10] hw/xen-hvm: add function to copy ACPI into guest memory X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Xen relies on QEMU to build guest NFIT and NVDIMM namespace devices, and implements an interface to allow QEMU to copy its ACPI into guest memory. This commit implements the QEMU side support. The location of guest memory that can receive QEMU ACPI can be found from XenStore entries /local/domain/$dom_id/hvmloader/dm-acpi/{address,length}, which have been handled by previous commit. QEMU ACPI copied to guest is organized in blobs. For each blob, QEMU creates following XenStore entries under /local/domain/$dom_id/hvmloader/dm-acpi/$name to indicate its type, location in above guest memory region and size. - type the type of the passed ACPI, which can be the following values. * XEN_DM_ACPI_BLOB_TYPE_TABLE (0) indicates it's a complete ACPI table, and its signature is indicated by $name in the XenStore path. * XEN_DM_ACPI_BLOB_TYPE_NSDEV (1) indicates it's the body of a namespace device, and its device name is indicated by $name in the XenStore path. - offset offset in byte from the beginning of above guest memory region - length size in byte of the copied ACPI Signed-off-by: Haozhong Zhang --- Cc: Stefano Stabellini Cc: Anthony Perard Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost --- hw/i386/xen/xen-hvm.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/xen/xen.h | 18 ++++++++ stubs/xen-hvm.c | 6 +++ 3 files changed, 137 insertions(+) diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index ae895aaf03..b74c4ffb9c 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -1286,6 +1286,20 @@ static int dm_acpi_buf_init(XenIOState *state) return 0; } +static ram_addr_t dm_acpi_buf_alloc(size_t length) +{ + ram_addr_t addr; + + if (dm_acpi_buf->length - dm_acpi_buf->used < length) { + return 0; + } + + addr = dm_acpi_buf->base + dm_acpi_buf->used; + dm_acpi_buf->used += length; + + return addr; +} + static int xen_dm_acpi_init(PCMachineState *pcms, XenIOState *state) { if (!xen_dm_acpi_needed(pcms)) { @@ -1295,6 +1309,105 @@ static int xen_dm_acpi_init(PCMachineState *pcms, XenIOState *state) return dm_acpi_buf_init(state); } +static int xs_write_dm_acpi_blob_entry(const char *name, + const char *entry, const char *value) +{ + XenIOState *state = container_of(dm_acpi_buf, XenIOState, dm_acpi_buf); + char path[80]; + + snprintf(path, sizeof(path), + "/local/domain/%d"HVM_XS_DM_ACPI_ROOT"/%s/%s", + xen_domid, name, entry); + if (!xs_write(state->xenstore, 0, path, value, strlen(value))) { + return -EIO; + } + + return 0; +} + +static size_t xen_memcpy_to_guest(ram_addr_t gpa, + const void *buf, size_t length) +{ + size_t copied = 0, size; + ram_addr_t s, e, offset, cur = gpa; + xen_pfn_t cur_pfn; + void *page; + + if (!buf || !length) { + return 0; + } + + s = gpa & TARGET_PAGE_MASK; + e = gpa + length; + if (e < s) { + return 0; + } + + while (cur < e) { + cur_pfn = cur >> TARGET_PAGE_BITS; + offset = cur - (cur_pfn << TARGET_PAGE_BITS); + size = (length >= TARGET_PAGE_SIZE - offset) ? + TARGET_PAGE_SIZE - offset : length; + + page = xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ | PROT_WRITE, + 1, &cur_pfn, NULL); + if (!page) { + break; + } + + memcpy(page + offset, buf, size); + xenforeignmemory_unmap(xen_fmem, page, 1); + + copied += size; + buf += size; + cur += size; + length -= size; + } + + return copied; +} + +int xen_acpi_copy_to_guest(const char *name, const void *blob, size_t length, + int type) +{ + char value[21]; + ram_addr_t buf_addr; + int rc; + + if (type != XEN_DM_ACPI_BLOB_TYPE_TABLE && + type != XEN_DM_ACPI_BLOB_TYPE_NSDEV) { + return -EINVAL; + } + + buf_addr = dm_acpi_buf_alloc(length); + if (!buf_addr) { + return -ENOMEM; + } + if (xen_memcpy_to_guest(buf_addr, blob, length) != length) { + return -EIO; + } + + snprintf(value, sizeof(value), "%d", type); + rc = xs_write_dm_acpi_blob_entry(name, "type", value); + if (rc) { + return rc; + } + + snprintf(value, sizeof(value), "%"PRIu64, buf_addr - dm_acpi_buf->base); + rc = xs_write_dm_acpi_blob_entry(name, "offset", value); + if (rc) { + return rc; + } + + snprintf(value, sizeof(value), "%"PRIu64, length); + rc = xs_write_dm_acpi_blob_entry(name, "length", value); + if (rc) { + return rc; + } + + return 0; +} + void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory) { int i, rc; diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 7efcdaa8fe..38dcd1a7d4 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -48,4 +48,22 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length); void xen_register_framebuffer(struct MemoryRegion *mr); +/* + * Copy an ACPI blob from QEMU to HVM guest. + * + * Parameters: + * name: a unique name of the data blob; for XEN_DM_ACPI_BLOB_TYPE_NSDEV, + * name should be less then 4 characters + * blob: the ACPI blob to be copied + * length: the length in bytes of the ACPI blob + * type: the type of content in the ACPI blob, one of XEN_DM_ACPI_BLOB_TYPE_* + * + * Return: + * 0 on success; a non-zero error code on failures. + */ +#define XEN_DM_ACPI_BLOB_TYPE_TABLE 0 /* ACPI table */ +#define XEN_DM_ACPI_BLOB_TYPE_NSDEV 1 /* AML of ACPI namespace device */ +int xen_acpi_copy_to_guest(const char *name, const void *blob, size_t length, + int type); + #endif /* QEMU_HW_XEN_H */ diff --git a/stubs/xen-hvm.c b/stubs/xen-hvm.c index 3ca6c51b21..58889ae0fb 100644 --- a/stubs/xen-hvm.c +++ b/stubs/xen-hvm.c @@ -61,3 +61,9 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory) void qmp_xen_set_global_dirty_log(bool enable, Error **errp) { } + +int xen_acpi_copy_to_guest(const char *name, const void *blob, size_t length, + int type) +{ + return -1; +}