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