Skip to content

Commit f7df22d

Browse files
Xiao Guangrongmstsirkin
Xiao Guangrong
authored andcommitted
nvdimm acpi: emulate dsm method
Emulate dsm method after IO VM-exit Currently, we only introduce the framework and no function is actually supported Signed-off-by: Xiao Guangrong <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent 18c440e commit f7df22d

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

hw/acpi/nvdimm.c

+56
Original file line numberDiff line numberDiff line change
@@ -390,15 +390,71 @@ struct NvdimmDsmOut {
390390
} QEMU_PACKED;
391391
typedef struct NvdimmDsmOut NvdimmDsmOut;
392392

393+
struct NvdimmDsmFunc0Out {
394+
/* the size of buffer filled by QEMU. */
395+
uint32_t len;
396+
uint32_t supported_func;
397+
} QEMU_PACKED;
398+
typedef struct NvdimmDsmFunc0Out NvdimmDsmFunc0Out;
399+
400+
struct NvdimmDsmFuncNoPayloadOut {
401+
/* the size of buffer filled by QEMU. */
402+
uint32_t len;
403+
uint32_t func_ret_status;
404+
} QEMU_PACKED;
405+
typedef struct NvdimmDsmFuncNoPayloadOut NvdimmDsmFuncNoPayloadOut;
406+
393407
static uint64_t
394408
nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size)
395409
{
410+
nvdimm_debug("BUG: we never read _DSM IO Port.\n");
396411
return 0;
397412
}
398413

399414
static void
400415
nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
401416
{
417+
NvdimmDsmIn *in;
418+
hwaddr dsm_mem_addr = val;
419+
420+
nvdimm_debug("dsm memory address %#" HWADDR_PRIx ".\n", dsm_mem_addr);
421+
422+
/*
423+
* The DSM memory is mapped to guest address space so an evil guest
424+
* can change its content while we are doing DSM emulation. Avoid
425+
* this by copying DSM memory to QEMU local memory.
426+
*/
427+
in = g_malloc(TARGET_PAGE_SIZE);
428+
cpu_physical_memory_read(dsm_mem_addr, in, TARGET_PAGE_SIZE);
429+
430+
le32_to_cpus(&in->revision);
431+
le32_to_cpus(&in->function);
432+
le32_to_cpus(&in->handle);
433+
434+
nvdimm_debug("Revision %#x Handler %#x Function %#x.\n", in->revision,
435+
in->handle, in->function);
436+
437+
/*
438+
* function 0 is called to inquire which functions are supported by
439+
* OSPM
440+
*/
441+
if (in->function == 0) {
442+
NvdimmDsmFunc0Out func0 = {
443+
.len = cpu_to_le32(sizeof(func0)),
444+
/* No function supported other than function 0 */
445+
.supported_func = cpu_to_le32(0),
446+
};
447+
cpu_physical_memory_write(dsm_mem_addr, &func0, sizeof func0);
448+
} else {
449+
/* No function except function 0 is supported yet. */
450+
NvdimmDsmFuncNoPayloadOut out = {
451+
.len = cpu_to_le32(sizeof(out)),
452+
.func_ret_status = cpu_to_le32(1) /* Not Supported */,
453+
};
454+
cpu_physical_memory_write(dsm_mem_addr, &out, sizeof(out));
455+
}
456+
457+
g_free(in);
402458
}
403459

404460
static const MemoryRegionOps nvdimm_dsm_ops = {

include/hw/mem/nvdimm.h

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@
2525

2626
#include "hw/mem/pc-dimm.h"
2727

28+
#define NVDIMM_DEBUG 0
29+
#define nvdimm_debug(fmt, ...) \
30+
do { \
31+
if (NVDIMM_DEBUG) { \
32+
fprintf(stderr, "nvdimm: " fmt, ## __VA_ARGS__); \
33+
} \
34+
} while (0)
35+
2836
#define TYPE_NVDIMM "nvdimm"
2937

3038
#define NVDIMM_DSM_MEM_FILE "etc/acpi/nvdimm-mem"

0 commit comments

Comments
 (0)