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.
Attachment:
signature.asc
Description: PGP signature