On 10/30/2015 06:14 PM, Stefan Hajnoczi wrote:
On Fri, Oct 30, 2015 at 01:56:21PM +0800, Xiao Guangrong wrote:
static uint64_t
nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size)
{
- return 0;
+ AcpiNVDIMMState *state = opaque;
+ MemoryRegion *dsm_ram_mr = &state->ram_mr;
+ NvdimmDsmIn *in;
+ GArray *out;
+ void *dsm_ram_addr;
+ uint32_t buf_size;
+
+ assert(memory_region_size(dsm_ram_mr) >= sizeof(NvdimmDsmIn));
+ dsm_ram_addr = memory_region_get_ram_ptr(dsm_ram_mr);
+
+ /*
+ * 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(memory_region_size(dsm_ram_mr));
+ memcpy(in, dsm_ram_addr, memory_region_size(dsm_ram_mr));
+
+ 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);
+
+ out = g_array_new(false, true /* clear */, 1);
+
+ if (in->revision != 0x1 /* Current we support DSM Spec Rev1. */) {
+ nvdimm_debug("Revision %#x is not supported, expect %#x.\n",
+ in->revision, 0x1);
+ nvdimm_dsm_write_status(out, NVDIMM_DSM_STATUS_NOT_SUPPORTED);
+ goto exit;
+ }
+
+ /* Handle 0 is reserved for NVDIMM Root Device. */
+ if (!in->handle) {
+ nvdimm_dsm_root(in, out);
+ goto exit;
+ }
+
+ nvdimm_dsm_device(in, out);
+
+exit:
+ /* Write output result to dsm memory. */
+ memcpy(dsm_ram_addr, out->data, out->len);
+ memory_region_set_dirty(dsm_ram_mr, 0, out->len);
If you respin this series, please add this before the memcpy out:
assert(out->len <= memory_region_size(dsm_ram_mr))
That way we can catch situations where too much output data was
generated by mistake.
Okay. If this patchset is okay to be merged, i will add this in
future development.
Thanks for your continuous and active review, Stefan!