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 <guangrong.xiao@linux.intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
		
							parent
							
								
									18c440e1e1
								
							
						
					
					
						commit
						f7df22de56
					
				| @ -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 %#" HWADDR_PRIx ".\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 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 = { | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Xiao Guangrong
						Xiao Guangrong