qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v6 27/33] nvdimm acpi: support function 0


From: Stefan Hajnoczi
Subject: Re: [Qemu-devel] [PATCH v6 27/33] nvdimm acpi: support function 0
Date: Fri, 30 Oct 2015 10:14:36 +0000
User-agent: Mutt/1.5.24 (2015-08-30)

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]