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@xxxxxxxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html