Message ID | 1456919441-101204-5-git-send-email-guangrong.xiao@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Mar 02, 2016 at 07:50:40PM +0800, Xiao Guangrong wrote: > Emulate dsm method after IO VM-exit > > Currently, we only introduce the framework and no function is actually > supported > > Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> > --- > hw/acpi/nvdimm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ > include/hw/mem/nvdimm.h | 8 +++++++ > 2 files changed, 64 insertions(+) > > diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c > index 781f6c1..5a17ee2 100644 > --- a/hw/acpi/nvdimm.c > +++ b/hw/acpi/nvdimm.c > @@ -390,15 +390,71 @@ struct NvdimmDsmOut { > } QEMU_PACKED; > typedef struct NvdimmDsmOut NvdimmDsmOut; > > +struct NvdimmDsmFunc0Out { > + /* the size of buffer filled by QEMU. */ > + uint32_t len; > + uint32_t supported_func; > +} QEMU_PACKED; > +typedef struct NvdimmDsmFunc0Out NvdimmDsmFunc0Out; > + > +struct NvdimmDsmFuncNoPayloadOut { > + /* the size of buffer filled by QEMU. */ > + uint32_t len; > + uint32_t func_ret_status; > +} QEMU_PACKED; > +typedef struct NvdimmDsmFuncNoPayloadOut NvdimmDsmFuncNoPayloadOut; > + > static uint64_t > nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size) > { > + nvdimm_debug("BUG: we never read _DSM IO Port.\n"); > return 0; > } > > static void > nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) > { > + NvdimmDsmIn *in; > + hwaddr dsm_mem_addr = val; > + > + nvdimm_debug("dsm memory address %#lx.\n", dsm_mem_addr); > + > + /* > + * The DSM memory is mapped to guest address space so an evil guest > + * can change its content while we are doing DSM emulation. Avoid > + * this by copying DSM memory to QEMU local memory. > + */ > + in = g_malloc(TARGET_PAGE_SIZE); > + cpu_physical_memory_read(dsm_mem_addr, in, TARGET_PAGE_SIZE); > + > + le32_to_cpus(&in->revision); > + le32_to_cpus(&in->function); > + le32_to_cpus(&in->handle); > + > + nvdimm_debug("Revision %#x Handler %#x Function %#x.\n", in->revision, > + in->handle, in->function); > + > + /* > + * function 0 is called to inquire what functions which functions > are supported by > + * OSPM > + */ > + if (in->function == 0) { > + NvdimmDsmFunc0Out func0 = { > + .len = cpu_to_le32(sizeof(func0)), > + /* No function supported other than function 0 */ > + .supported_func = cpu_to_le32(0), > + }; > + cpu_physical_memory_write(dsm_mem_addr, &func0, sizeof func0); > + } else { > + /* No function except function 0 is supported yet. */ > + NvdimmDsmFuncNoPayloadOut out = { > + .len = cpu_to_le32(sizeof(out)), > + .func_ret_status = cpu_to_le32(1) /* Not Supported */, > + }; > + cpu_physical_memory_write(dsm_mem_addr, &out, sizeof(out)); > + } > + > + g_free(in); > } > > static const MemoryRegionOps nvdimm_dsm_ops = { > diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h > index 634c60b..aaa2608 100644 > --- a/include/hw/mem/nvdimm.h > +++ b/include/hw/mem/nvdimm.h > @@ -25,6 +25,14 @@ > > #include "hw/mem/pc-dimm.h" > > +#define NVDIMM_DEBUG 0 > +#define nvdimm_debug(fmt, ...) \ > + do { \ > + if (NVDIMM_DEBUG) { \ > + fprintf(stderr, "nvdimm: " fmt, ## __VA_ARGS__); \ > + } \ > + } while (0) > + > #define TYPE_NVDIMM "nvdimm" > > #define NVDIMM_DSM_MEM_FILE "etc/acpi/nvdimm-mem" > -- > 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 03/03/2016 09:25 PM, Michael S. Tsirkin wrote: >> + >> + /* >> + * function 0 is called to inquire what functions > > which functions Okay, will fix. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 781f6c1..5a17ee2 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -390,15 +390,71 @@ struct NvdimmDsmOut { } QEMU_PACKED; typedef struct NvdimmDsmOut NvdimmDsmOut; +struct NvdimmDsmFunc0Out { + /* the size of buffer filled by QEMU. */ + uint32_t len; + uint32_t supported_func; +} QEMU_PACKED; +typedef struct NvdimmDsmFunc0Out NvdimmDsmFunc0Out; + +struct NvdimmDsmFuncNoPayloadOut { + /* the size of buffer filled by QEMU. */ + uint32_t len; + uint32_t func_ret_status; +} QEMU_PACKED; +typedef struct NvdimmDsmFuncNoPayloadOut NvdimmDsmFuncNoPayloadOut; + static uint64_t nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size) { + nvdimm_debug("BUG: we never read _DSM IO Port.\n"); return 0; } static void nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { + NvdimmDsmIn *in; + hwaddr dsm_mem_addr = val; + + nvdimm_debug("dsm memory address %#lx.\n", dsm_mem_addr); + + /* + * The DSM memory is mapped to guest address space so an evil guest + * can change its content while we are doing DSM emulation. Avoid + * this by copying DSM memory to QEMU local memory. + */ + in = g_malloc(TARGET_PAGE_SIZE); + cpu_physical_memory_read(dsm_mem_addr, in, TARGET_PAGE_SIZE); + + le32_to_cpus(&in->revision); + le32_to_cpus(&in->function); + le32_to_cpus(&in->handle); + + nvdimm_debug("Revision %#x Handler %#x Function %#x.\n", in->revision, + in->handle, in->function); + + /* + * function 0 is called to inquire what functions are supported by + * OSPM + */ + if (in->function == 0) { + NvdimmDsmFunc0Out func0 = { + .len = cpu_to_le32(sizeof(func0)), + /* No function supported other than function 0 */ + .supported_func = cpu_to_le32(0), + }; + cpu_physical_memory_write(dsm_mem_addr, &func0, sizeof func0); + } else { + /* No function except function 0 is supported yet. */ + NvdimmDsmFuncNoPayloadOut out = { + .len = cpu_to_le32(sizeof(out)), + .func_ret_status = cpu_to_le32(1) /* Not Supported */, + }; + cpu_physical_memory_write(dsm_mem_addr, &out, sizeof(out)); + } + + g_free(in); } static const MemoryRegionOps nvdimm_dsm_ops = { diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h index 634c60b..aaa2608 100644 --- a/include/hw/mem/nvdimm.h +++ b/include/hw/mem/nvdimm.h @@ -25,6 +25,14 @@ #include "hw/mem/pc-dimm.h" +#define NVDIMM_DEBUG 0 +#define nvdimm_debug(fmt, ...) \ + do { \ + if (NVDIMM_DEBUG) { \ + fprintf(stderr, "nvdimm: " fmt, ## __VA_ARGS__); \ + } \ + } while (0) + #define TYPE_NVDIMM "nvdimm" #define NVDIMM_DSM_MEM_FILE "etc/acpi/nvdimm-mem"
Emulate dsm method after IO VM-exit Currently, we only introduce the framework and no function is actually supported Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> --- hw/acpi/nvdimm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/mem/nvdimm.h | 8 +++++++ 2 files changed, 64 insertions(+)