[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC QEMU PATCH v2 03/10] xen-hvm: support copying ACPI to
From: |
Haozhong Zhang |
Subject: |
[Qemu-devel] [RFC QEMU PATCH v2 03/10] xen-hvm: support copying ACPI to guest memory |
Date: |
Mon, 20 Mar 2017 08:12:42 +0800 |
Signed-off-by: Haozhong Zhang <address@hidden>
---
Cc: Stefano Stabellini <address@hidden>
Cc: Anthony Perard <address@hidden>
Cc: address@hidden
---
include/hw/xen/xen.h | 18 ++++++++
xen-hvm-stub.c | 6 +++
xen-hvm.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 137 insertions(+)
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index 09c2ce5170..d67cdd8c7d 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -47,4 +47,22 @@ void xen_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
+ *
+ * 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/xen-hvm-stub.c b/xen-hvm-stub.c
index c5003251cb..a6c018505c 100644
--- a/xen-hvm-stub.c
+++ b/xen-hvm-stub.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;
+}
diff --git a/xen-hvm.c b/xen-hvm.c
index c42c958a0a..4ddc47e5f1 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -1252,6 +1252,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_required(PCMachineState *pcms)
{
return 0;
@@ -1486,3 +1500,102 @@ void qmp_xen_set_global_dirty_log(bool enable, Error
**errp)
memory_global_dirty_log_stop();
}
}
+
+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;
+}
--
2.12.0
- [Qemu-devel] [RFC QEMU PATCH v2 00/10] Implement vNVDIMM for Xen HVM guest, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 02/10] xen-hvm: initialize DM ACPI, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 01/10] nvdimm xen: disable label support on Xen, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 03/10] xen-hvm: support copying ACPI to guest memory,
Haozhong Zhang <=
- [Qemu-devel] [RFC QEMU PATCH v2 04/10] nvdimm acpi: do not use fw_cfg on Xen, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 05/10] nvdimm acpi: copy NFIT to Xen guest, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 06/10] nvdimm acpi: build and copy NVDIMM namespace devices to guest on Xen, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 07/10] xen-hvm: initiate building DM ACPI on i386 machine, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 08/10] hostmem: add a host memory backend for Xen, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 09/10] xen-hvm: create hotplug memory region on Xen, Haozhong Zhang, 2017/03/19
- [Qemu-devel] [RFC QEMU PATCH v2 10/10] qapi: extend 'query-memory-devices' to list devices of specified type, Haozhong Zhang, 2017/03/19
- Re: [Qemu-devel] [RFC QEMU PATCH v2 00/10] Implement vNVDIMM for Xen HVM guest, no-reply, 2017/03/19
- Re: [Qemu-devel] [RFC QEMU PATCH v2 00/10] Implement vNVDIMM for Xen HVM guest, no-reply, 2017/03/28