Re: [Qemu-devel] [PATCH v1 00/15] data-driven device registers

2015-10-29 Thread Peter Crosthwaite
Ping^3

This has been on list for a very long time without 3rd party review.
Can I send a PULL?

Regards,
Peter

On Wed, Oct 14, 2015 at 11:42 AM, Alistair Francis
 wrote:
> Ping^2
>
> On Thu, Aug 27, 2015 at 2:47 PM, Alistair Francis
>  wrote:
>> Ping!
>>
>> On Wed, Jul 29, 2015 at 1:24 PM, Alistair Francis
>>  wrote:
>>> From Peter:
>>> Hi All. This is a new scheme I've come up with handling device registers in 
>>> a
>>> data driven way. My motivation for this is to factor out a lot of the access
>>> checking that seems to be replicated in every device. See P1 commit message 
>>> for
>>> further discussion.
>>>
>>> P1 is the main patch, adds the register definition functionality
>>> P2-3,6 add helpers that glue the register API to the Memory API
>>> P4 Defines a set of macros that minimise register and field definitions
>>> P5 is QOMfication
>>> P7 is a trivial
>>> P10-13 Work up to GPIO support
>>> P8,9,14 add new devices (the Xilinx Zynq devcfg & ZynqMP SLCR) that use this
>>> scheme.
>>> P15: Connect the ZynqMP SLCR device
>>>
>>> This Zynq devcfg device was particularly finnicky with per-bit restrictions.
>>> I'm also looking for a higher-than-usual modelling fidelity
>>> on the register space, with semantics defined for random reserved bits
>>> in-between otherwise consistent fields.
>>>
>>> Here's an example of the qemu_log output for the devcfg device. This is 
>>> produced
>>> by now generic sharable code:
>>>
>>> /machine/unattached/device[44]:Addr 0x08:CFG: write of value 0508
>>> /machine/unattached/device[44]:Addr 0x80:MCTRL: write of value 00800010
>>> /machine/unattached/device[44]:Addr 0x10:INT_MASK: write of value 
>>> 
>>> /machine/unattached/device[44]:Addr :CTRL: write of value 0c00607f
>>>
>>> And an example of a rogue guest banging on a bad bit:
>>>
>>> /machine/unattached/device[44]:Addr 0x14:STATUS bits 0x01 may not 
>>> be \
>>> written to 1
>>>
>>> A future feature I am interested in is implementing TCG optimisation of
>>> side-effectless registers. The register API allows clear definition of
>>> what registers have txn side effects and which ones don't. You could even
>>> go a step further and translate such side-effectless accesses based on the
>>> data pointer for the register.
>>>
>>> Changes since RFC:
>>>  - Connect the ZynqMP IOU SLCR device
>>>  - Rebase
>>>
>>> Changed from RFC v4:
>>> Rebased
>>> Added QOMification
>>> Added GPIO support
>>> Refactored Devcfg device to use FIELD/REG/EX macros.
>>> Update style of devcfg device
>>> Added init_block help.
>>> Changed from v3:
>>> Rebased
>>> Added reserved bits.
>>> Cleaner separation of decode and access components (Patch 3)
>>> Changed from v2:
>>> Fixed for hw/ re-orginisation (Paolo review)
>>> Simplified and optimized (PMM and Gerd review)
>>> Changed from v1:
>>> Added ONES macro patch
>>> Dropped bogus former patch 1 (PMM review)
>>> Addressed Blue, Gerd and MST comments.
>>> Simplified to be more Memory API compatible.
>>> Added Memory API helpers.
>>> Please see discussion already on list and commit msgs for more detail.
>>>
>>>
>>> Alistair Francis (1):
>>>   xlnx-zynqmp: Connect the ZynqMP IOU SLCR
>>>
>>> Peter Crosthwaite (14):
>>>   register: Add Register API
>>>   register: Add Memory API glue
>>>   register: Add support for decoding information
>>>   register: Define REG and FIELD macros
>>>   register: QOMify
>>>   register: Add block initialise helper
>>>   bitops: Add ONES macro
>>>   dma: Add Xilinx Zynq devcfg device model
>>>   xilinx_zynq: add devcfg to machine model
>>>   qdev: Define qdev_get_gpio_out
>>>   qdev: Add qdev_pass_all_gpios API
>>>   irq: Add opaque setter routine
>>>   register: Add GPIO API
>>>   misc: Introduce ZynqMP IOU SLCR
>>>
>>>  default-configs/arm-softmmu.mak|1 +
>>>  hw/arm/xilinx_zynq.c   |8 +
>>>  hw/arm/xlnx-zynqmp.c   |   15 ++
>>>  hw/core/Makefile.objs  |1 +
>>>  hw/core/irq.c  |5 +
>>>  hw/core/qdev.c |   21 ++
>>>  hw/core/register.c |  390 
>>> ++
>>>  hw/dma/Makefile.objs   |1 +
>>>  hw/dma/xlnx-zynq-devcfg.c  |  406 
>>> 
>>>  hw/misc/Makefile.objs  |1 +
>>>  hw/misc/xlnx-zynqmp-iou-slcr.c |  113 +
>>>  include/hw/arm/xlnx-zynqmp.h   |2 +
>>>  include/hw/dma/xlnx-zynq-devcfg.h  |   62 +
>>>  include/hw/irq.h   |2 +
>>>  include/hw/misc/xlnx-zynqmp-iou-slcr.h |   47 
>>>  include/hw/qdev-core.h |3 +
>>>  include/hw/register.h  |  274 +
>>>  include/qemu/bitops.h  |2 +
>>>  18 files changed, 1354 insertions(+), 0 deletions(-)
>>>  create mode 100644 hw/core/register.c

Re: [Qemu-devel] [PATCH v6 0/4] qapi: child add/delete support

2015-10-29 Thread Wen Congyang
Ping...

On 10/16/2015 04:57 PM, Wen Congyang wrote:
> If quorum's child is broken, we can use mirror job to replace it.
> But sometimes, the user only need to remove the broken child, and
> add it later when the problem is fixed.
> 
> It is based on the Kevin's bdrv_swap() related patch:
> http://lists.nongnu.org/archive/html/qemu-devel/2015-10/msg02152.html
> 
> ChangLog:
> v6:
> 1. Use a single qmp command x-blockdev-change to replace x-blockdev-child-add
>and x-blockdev-child-delete
> v5:
> 1. Address Eric Blake's comments
> v4:
> 1. drop nbd driver's implementation. We can use human-monitor-command
>to do it.
> 2. Rename the command name.
> v3:
> 1. Don't open BDS in bdrv_add_child(). Use the existing BDS which is
>created by the QMP command blockdev-add.
> 2. The driver NBD can support filename, path, host:port now.
> v2:
> 1. Use bdrv_get_device_or_node_name() instead of new function
>bdrv_get_id_or_node_name()
> 2. Update the error message
> 3. Update the documents in block-core.json
> 
> 
> Wen Congyang (4):
>   Add new block driver interface to add/delete a BDS's child
>   quorum: implement bdrv_add_child() and bdrv_del_child()
>   qmp: add monitor command to add/remove a child
>   hmp: add monitor command to add/remove a child
> 
>  block.c   | 56 --
>  block/quorum.c| 59 ++--
>  blockdev.c| 76 
> +++
>  hmp-commands.hx   | 17 +++
>  hmp.c | 38 
>  hmp.h |  1 +
>  include/block/block.h |  8 +
>  include/block/block_int.h |  5 
>  qapi/block-core.json  | 40 +
>  qmp-commands.hx   | 50 +++
>  10 files changed, 345 insertions(+), 5 deletions(-)
> 




[Qemu-devel] [PATCH v6 33/33] nvdimm: add maintain info

2015-10-29 Thread Xiao Guangrong
Add NVDIMM maintainer

Signed-off-by: Xiao Guangrong 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3144113..865c0cf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -907,6 +907,13 @@ M: Jiri Pirko 
 S: Maintained
 F: hw/net/rocker/
 
+NVDIMM
+M: Xiao Guangrong 
+S: Maintained
+F: hw/acpi/nvdimm.c
+F: hw/mem/nvdimm.c
+F: include/hw/mem/nvdimm.h
+
 Subsystems
 --
 Audio
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 30/33] nvdimm acpi: support Set Namespace Label Data function

2015-10-29 Thread Xiao Guangrong
Function 6 is used to set Namespace Label Data

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/nvdimm.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 8c27b25..5c8be41 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -587,6 +587,34 @@ exit:
 nvdimm_dsm_write_status(out, status);
 }
 
+/*
+ * DSM Spec Rev1 4.6 Set Namespace Label Data (Function Index 6).
+ */
+static void nvdimm_dsm_func_set_label_data(NVDIMMDevice *nvdimm,
+   NvdimmDsmIn *in, GArray *out)
+{
+NVDIMMClass *nvc = NVDIMM_GET_CLASS(nvdimm);
+NvdimmFuncInSetLabelData *set_label_data = &in->func_set_label_data;
+uint32_t status;
+
+le32_to_cpus(&set_label_data->offset);
+le32_to_cpus(&set_label_data->length);
+
+nvdimm_debug("Write Label Data: offset %#x length %#x.\n",
+ set_label_data->offset, set_label_data->length);
+
+status = nvdimm_rw_label_data_check(nvdimm, set_label_data->offset,
+set_label_data->length);
+if (status != NVDIMM_DSM_STATUS_SUCCESS) {
+goto exit;
+}
+
+nvc->write_label_data(nvdimm, set_label_data->in_buf,
+  set_label_data->length, set_label_data->offset);
+exit:
+nvdimm_dsm_write_status(out, status);
+}
+
 static void nvdimm_dsm_device(NvdimmDsmIn *in, GArray *out)
 {
 GSList *list = nvdimm_get_plugged_device_list();
@@ -617,6 +645,9 @@ static void nvdimm_dsm_device(NvdimmDsmIn *in, GArray *out)
 case 0x5 /* Get Namespace Label Data */:
 nvdimm_dsm_func_get_label_data(nvdimm, in, out);
 goto free;
+case 0x6 /* Set Namespace Label Data */:
+nvdimm_dsm_func_set_label_data(nvdimm, in, out);
+goto free;
 default:
 status = NVDIMM_DSM_STATUS_NOT_SUPPORTED;
 };
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 29/33] nvdimm acpi: support Get Namespace Label Data function

2015-10-29 Thread Xiao Guangrong
Function 5 is used to get Namespace Label Data

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/nvdimm.c | 63 
 1 file changed, 63 insertions(+)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 67c4699..8c27b25 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -428,6 +428,7 @@ struct NvdimmDsmIn {
 union {
 uint8_t arg3[0];
 NvdimmFuncInSetLabelData func_set_label_data;
+NvdimmFuncInGetLabelData func_get_label_data;
 };
 } QEMU_PACKED;
 typedef struct NvdimmDsmIn NvdimmDsmIn;
@@ -527,6 +528,65 @@ static void nvdimm_dsm_func_label_size(NVDIMMDevice 
*nvdimm, GArray *out)
 g_array_append_vals(out, &func_label_size, sizeof(func_label_size));
 }
 
+static uint32_t nvdimm_rw_label_data_check(NVDIMMDevice *nvdimm,
+   uint32_t offset, uint32_t length)
+{
+if (offset + length < offset) {
+nvdimm_debug("offset %#x + length %#x is overflow.\n", offset,
+ length);
+return NVDIMM_DSM_DEV_STATUS_INVALID_PARAS;
+}
+
+if (nvdimm->label_size < offset + length) {
+nvdimm_debug("position %#x is beyond label data (len = %#lx).\n",
+ offset + length, nvdimm->label_size);
+return NVDIMM_DSM_DEV_STATUS_INVALID_PARAS;
+}
+
+if (length > nvdimm_get_max_xfer_label_size()) {
+nvdimm_debug("length (%#x) is larger than max_xfer (%#x).\n",
+ length, nvdimm_get_max_xfer_label_size());
+return NVDIMM_DSM_DEV_STATUS_INVALID_PARAS;
+}
+
+return NVDIMM_DSM_STATUS_SUCCESS;
+}
+
+/*
+ * DSM Spec Rev1 4.5 Get Namespace Label Data (Function Index 5).
+ */
+static void nvdimm_dsm_func_get_label_data(NVDIMMDevice *nvdimm,
+   NvdimmDsmIn *in, GArray *out)
+{
+NVDIMMClass *nvc = NVDIMM_GET_CLASS(nvdimm);
+NvdimmFuncInGetLabelData *get_label_data = &in->func_get_label_data;
+void *buf;
+uint32_t status;
+
+le32_to_cpus(&get_label_data->offset);
+le32_to_cpus(&get_label_data->length);
+
+nvdimm_debug("Read Label Data: offset %#x length %#x.\n",
+ get_label_data->offset, get_label_data->length);
+
+status = nvdimm_rw_label_data_check(nvdimm, get_label_data->offset,
+get_label_data->length);
+if (status != NVDIMM_DSM_STATUS_SUCCESS) {
+goto exit;
+}
+
+/* write nvdimm_func_out_get_label_data.status. */
+nvdimm_dsm_write_status(out, status);
+/* write nvdimm_func_out_get_label_data.out_buf. */
+buf = acpi_data_push(out, get_label_data->length);
+nvc->read_label_data(nvdimm, buf, get_label_data->length,
+ get_label_data->offset);
+return;
+
+exit:
+nvdimm_dsm_write_status(out, status);
+}
+
 static void nvdimm_dsm_device(NvdimmDsmIn *in, GArray *out)
 {
 GSList *list = nvdimm_get_plugged_device_list();
@@ -554,6 +614,9 @@ static void nvdimm_dsm_device(NvdimmDsmIn *in, GArray *out)
 case 0x4 /* Get Namespace Label Size */:
 nvdimm_dsm_func_label_size(nvdimm, out);
 goto free;
+case 0x5 /* Get Namespace Label Data */:
+nvdimm_dsm_func_get_label_data(nvdimm, in, out);
+goto free;
 default:
 status = NVDIMM_DSM_STATUS_NOT_SUPPORTED;
 };
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 28/33] nvdimm acpi: support Get Namespace Label Size function

2015-10-29 Thread Xiao Guangrong
Function 4 is used to get Namespace label size

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/nvdimm.c | 87 +++-
 1 file changed, 86 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 300a3aa..67c4699 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -407,15 +407,48 @@ enum {
 NVDIMM_DSM_DEV_STATUS_VENDOR_SPECIFIC_ERROR = 4,
 };
 
+struct NvdimmFuncInGetLabelData {
+uint32_t offset; /* the offset in the namespace label data area. */
+uint32_t length; /* the size of data is to be read via the function. */
+} QEMU_PACKED;
+typedef struct NvdimmFuncInGetLabelData NvdimmFuncInGetLabelData;
+
+struct NvdimmFuncInSetLabelData {
+uint32_t offset; /* the offset in the namespace label data area. */
+uint32_t length; /* the size of data is to be written via the function. */
+uint8_t in_buf[0]; /* the data written to label data area. */
+} QEMU_PACKED;
+typedef struct NvdimmFuncInSetLabelData NvdimmFuncInSetLabelData;
+
 struct NvdimmDsmIn {
 uint32_t handle;
 uint32_t revision;
 uint32_t function;
/* the remaining size in the page is used by arg3. */
-uint8_t arg3[0];
+union {
+uint8_t arg3[0];
+NvdimmFuncInSetLabelData func_set_label_data;
+};
 } QEMU_PACKED;
 typedef struct NvdimmDsmIn NvdimmDsmIn;
 
+struct NvdimmFuncOutLabelSize {
+uint32_t status; /* return status code. */
+uint32_t label_size; /* the size of label data area. */
+/*
+ * Maximum size of the namespace label data length supported by
+ * the platform in Get/Set Namespace Label Data functions.
+ */
+uint32_t max_xfer;
+} QEMU_PACKED;
+typedef struct NvdimmFuncOutLabelSize NvdimmFuncOutLabelSize;
+
+struct NvdimmFuncOutGetLabelData {
+uint32_t status;/*return status code. */
+uint8_t out_buf[0]; /* the data got via Get Namesapce Label function. */
+} QEMU_PACKED;
+typedef struct NvdimmFuncOutGetLabelData NvdimmFuncOutGetLabelData;
+
 static void nvdimm_dsm_write_status(GArray *out, uint32_t status)
 {
 status = cpu_to_le32(status);
@@ -445,6 +478,55 @@ static void nvdimm_dsm_root(NvdimmDsmIn *in, GArray *out)
 nvdimm_dsm_write_status(out, status);
 }
 
+/*
+ * the max transfer size is the max size transferred by both a
+ * 'Get Namespace Label Data' function and a 'Set Namespace Label Data'
+ * function.
+ */
+static uint32_t nvdimm_get_max_xfer_label_size(void)
+{
+NvdimmDsmIn *in;
+uint32_t max_get_size, max_set_size, dsm_memory_size = TARGET_PAGE_SIZE;
+
+/*
+ * the max data ACPI can read one time which is transferred by
+ * the response of 'Get Namespace Label Data' function.
+ */
+max_get_size = dsm_memory_size - sizeof(NvdimmFuncOutGetLabelData);
+
+/*
+ * the max data ACPI can write one time which is transferred by
+ * 'Set Namespace Label Data' function.
+ */
+max_set_size = dsm_memory_size - offsetof(NvdimmDsmIn, arg3) -
+   sizeof(in->func_set_label_data);
+
+return MIN(max_get_size, max_set_size);
+}
+
+/*
+ * DSM Spec Rev1 4.4 Get Namespace Label Size (Function Index 4).
+ *
+ * It gets the size of Namespace Label data area and the max data size
+ * that Get/Set Namespace Label Data functions can transfer.
+ */
+static void nvdimm_dsm_func_label_size(NVDIMMDevice *nvdimm, GArray *out)
+{
+NvdimmFuncOutLabelSize func_label_size;
+uint32_t label_size, mxfer;
+
+label_size = nvdimm->label_size;
+mxfer = nvdimm_get_max_xfer_label_size();
+
+nvdimm_debug("label_size %#x, max_xfer %#x.\n", label_size, mxfer);
+
+func_label_size.status = cpu_to_le32(NVDIMM_DSM_STATUS_SUCCESS);
+func_label_size.label_size = cpu_to_le32(label_size);
+func_label_size.max_xfer = cpu_to_le32(mxfer);
+
+g_array_append_vals(out, &func_label_size, sizeof(func_label_size));
+}
+
 static void nvdimm_dsm_device(NvdimmDsmIn *in, GArray *out)
 {
 GSList *list = nvdimm_get_plugged_device_list();
@@ -469,6 +551,9 @@ static void nvdimm_dsm_device(NvdimmDsmIn *in, GArray *out)
1 << 6 /* Set Namespace Label Data */);
 build_append_int_noprefix(out, cmd_list, sizeof(cmd_list));
 goto free;
+case 0x4 /* Get Namespace Label Size */:
+nvdimm_dsm_func_label_size(nvdimm, out);
+goto free;
 default:
 status = NVDIMM_DSM_STATUS_NOT_SUPPORTED;
 };
-- 
1.8.3.1




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

2015-10-29 Thread Xiao Guangrong
__DSM is defined in ACPI 6.0: 9.14.1 _DSM (Device Specific Method)

Function 0 is a query function. We do not support any function on root
device and only 3 functions are support for NVDIMM device, Get Namespace
Label Size, Get Namespace Label Data and Set Namespace Label Data, that
means we currently only allow to access device's Label Namespace

Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c |   2 +-
 hw/acpi/nvdimm.c| 156 +++-
 include/hw/acpi/aml-build.h |   1 +
 3 files changed, 157 insertions(+), 2 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 8bee8b2..90229c5 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -231,7 +231,7 @@ static void build_extop_package(GArray *package, uint8_t op)
 build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
 }
 
-static void build_append_int_noprefix(GArray *table, uint64_t value, int size)
+void build_append_int_noprefix(GArray *table, uint64_t value, int size)
 {
 int i;
 
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index e179a72..300a3aa 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -212,6 +212,22 @@ static uint32_t nvdimm_slot_to_dcr_index(int slot)
 return nvdimm_slot_to_spa_index(slot) + 1;
 }
 
+static NVDIMMDevice
+*nvdimm_get_device_by_handle(GSList *list, uint32_t handle)
+{
+for (; list; list = list->next) {
+NVDIMMDevice *nvdimm = list->data;
+int slot = object_property_get_int(OBJECT(nvdimm), DIMM_SLOT_PROP,
+   NULL);
+
+if (nvdimm_slot_to_handle(slot) == handle) {
+return nvdimm;
+}
+}
+
+return NULL;
+}
+
 /* ACPI 6.0: 5.2.25.1 System Physical Address Range Structure */
 static void
 nvdimm_build_structure_spa(GArray *structures, NVDIMMDevice *nvdimm)
@@ -368,6 +384,29 @@ static void nvdimm_build_nfit(GSList *device_list, GArray 
*table_offsets,
 g_array_free(structures, true);
 }
 
+/* define NVDIMM DSM return status codes according to DSM Spec Rev1. */
+enum {
+/* Common return status codes. */
+/* Success */
+NVDIMM_DSM_STATUS_SUCCESS = 0,
+/* Not Supported */
+NVDIMM_DSM_STATUS_NOT_SUPPORTED = 1,
+
+/* NVDIMM Root Device _DSM function return status codes*/
+/* Invalid Input Parameters */
+NVDIMM_DSM_ROOT_DEV_STATUS_INVALID_PARAS = 2,
+/* Function-Specific Error */
+NVDIMM_DSM_ROOT_DEV_STATUS_FUNCTION_SPECIFIC_ERROR = 3,
+
+/* NVDIMM Device (non-root) _DSM function return status codes*/
+/* Non-Existing Memory Device */
+NVDIMM_DSM_DEV_STATUS_NON_EXISTING_MEM_DEV = 2,
+/* Invalid Input Parameters */
+NVDIMM_DSM_DEV_STATUS_INVALID_PARAS = 3,
+/* Vendor Specific Error */
+NVDIMM_DSM_DEV_STATUS_VENDOR_SPECIFIC_ERROR = 4,
+};
+
 struct NvdimmDsmIn {
 uint32_t handle;
 uint32_t revision;
@@ -377,10 +416,125 @@ struct NvdimmDsmIn {
 } QEMU_PACKED;
 typedef struct NvdimmDsmIn NvdimmDsmIn;
 
+static void nvdimm_dsm_write_status(GArray *out, uint32_t status)
+{
+status = cpu_to_le32(status);
+build_append_int_noprefix(out, status, sizeof(status));
+}
+
+static void nvdimm_dsm_root(NvdimmDsmIn *in, GArray *out)
+{
+uint32_t status = NVDIMM_DSM_STATUS_NOT_SUPPORTED;
+
+/*
+ * Query command implemented per ACPI Specification, it is defined in
+ * ACPI 6.0: 9.14.1 _DSM (Device Specific Method).
+ */
+if (in->function == 0x0) {
+/*
+ * Set it to zero to indicate no function is supported for NVDIMM
+ * root.
+ */
+uint64_t cmd_list = cpu_to_le64(0);
+
+build_append_int_noprefix(out, cmd_list, sizeof(cmd_list));
+return;
+}
+
+nvdimm_debug("Return status %#x.\n", status);
+nvdimm_dsm_write_status(out, status);
+}
+
+static void nvdimm_dsm_device(NvdimmDsmIn *in, GArray *out)
+{
+GSList *list = nvdimm_get_plugged_device_list();
+NVDIMMDevice *nvdimm = nvdimm_get_device_by_handle(list, in->handle);
+uint32_t status = NVDIMM_DSM_DEV_STATUS_NON_EXISTING_MEM_DEV;
+uint64_t cmd_list;
+
+if (!nvdimm) {
+goto set_status_free;
+}
+
+/* Encode DSM function according to DSM Spec Rev1. */
+switch (in->function) {
+/* see comments in nvdimm_dsm_root(). */
+case 0x0:
+cmd_list = cpu_to_le64(0x1 /* Bit 0 indicates whether there is
+  support for any functions other
+  than function 0.
+*/   |
+   1 << 4 /* Get Namespace Label Size */ |
+   1 << 5 /* Get Namespace Label Data */ |
+   1 << 6 /* Set Namespace Label Data */);
+build_append_int_noprefix(out, cmd_list, sizeof(cmd_list));
+goto free;
+default:
+status = NVDIMM_DSM_STATUS_NOT_SUPPORTED;
+ 

[Qemu-devel] [PATCH v6 32/33] nvdimm acpi: support _FIT method

2015-10-29 Thread Xiao Guangrong
FIT buffer is not completely mapped into guest address space, so a new
function, Read FIT, function index 0x, is reserved by QEMU to
read the piece of FIT buffer. The buffer is concatenated before _FIT
return

Refer to docs/specs/acpi-nvdimm.txt for detailed design

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/nvdimm.c | 168 +--
 1 file changed, 164 insertions(+), 4 deletions(-)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index f8d7d19..3f35220 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -384,6 +384,18 @@ static void nvdimm_build_nfit(GSList *device_list, GArray 
*table_offsets,
 g_array_free(structures, true);
 }
 
+/*
+ * define UUID for NVDIMM Root Device according to Chapter 3 DSM Interface
+ * for NVDIMM Root Device - Example in DSM Spec Rev1.
+ */
+#define NVDIMM_DSM_ROOT_UUID "2F10E7A4-9E91-11E4-89D3-123B93F75CBA"
+
+/*
+ * Read FIT Function, which is a QEMU internal use only function, more detail
+ * refer to docs/specs/acpi_nvdimm.txt
+ */
+#define NVDIMM_DSM_FUNC_READ_FIT 0x
+
 /* define NVDIMM DSM return status codes according to DSM Spec Rev1. */
 enum {
 /* Common return status codes. */
@@ -420,6 +432,11 @@ struct NvdimmFuncInSetLabelData {
 } QEMU_PACKED;
 typedef struct NvdimmFuncInSetLabelData NvdimmFuncInSetLabelData;
 
+struct NvdimmFuncInReadFit {
+uint32_t offset; /* fit offset */
+} QEMU_PACKED;
+typedef struct NvdimmFuncInReadFit NvdimmFuncInReadFit;
+
 struct NvdimmDsmIn {
 uint32_t handle;
 uint32_t revision;
@@ -429,6 +446,7 @@ struct NvdimmDsmIn {
 uint8_t arg3[0];
 NvdimmFuncInSetLabelData func_set_label_data;
 NvdimmFuncInGetLabelData func_get_label_data;
+NvdimmFuncInReadFit func_read_fit;
 };
 } QEMU_PACKED;
 typedef struct NvdimmDsmIn NvdimmDsmIn;
@@ -450,13 +468,71 @@ struct NvdimmFuncOutGetLabelData {
 } QEMU_PACKED;
 typedef struct NvdimmFuncOutGetLabelData NvdimmFuncOutGetLabelData;
 
+struct NvdimmFuncOutReadFit {
+uint32_t status;/* return status code. */
+uint32_t length;/* the length of fit data we read. */
+uint8_t fit_data[0]; /* fit data. */
+} QEMU_PACKED;
+typedef struct NvdimmFuncOutReadFit NvdimmFuncOutReadFit;
+
 static void nvdimm_dsm_write_status(GArray *out, uint32_t status)
 {
 status = cpu_to_le32(status);
 build_append_int_noprefix(out, status, sizeof(status));
 }
 
-static void nvdimm_dsm_root(NvdimmDsmIn *in, GArray *out)
+/* Build fit memory which is presented to guest via _FIT method. */
+static void nvdimm_build_fit(AcpiNVDIMMState *state)
+{
+if (!state->fit) {
+GSList *device_list = nvdimm_get_plugged_device_list();
+
+nvdimm_debug("Rebuild FIT...\n");
+state->fit = nvdimm_build_device_structure(device_list);
+g_slist_free(device_list);
+}
+}
+
+/* Read FIT data, defined in docs/specs/acpi_nvdimm.txt. */
+static void nvdimm_dsm_func_read_fit(AcpiNVDIMMState *state,
+ NvdimmDsmIn *in, GArray *out)
+{
+NvdimmFuncInReadFit *read_fit = &in->func_read_fit;
+NvdimmFuncOutReadFit fit_out;
+uint32_t read_length = TARGET_PAGE_SIZE - sizeof(NvdimmFuncOutReadFit);
+uint32_t status = NVDIMM_DSM_ROOT_DEV_STATUS_INVALID_PARAS;
+
+nvdimm_build_fit(state);
+
+le32_to_cpus(&read_fit->offset);
+
+nvdimm_debug("Read FIT offset %#x.\n", read_fit->offset);
+
+if (read_fit->offset > state->fit->len) {
+nvdimm_debug("offset %#x is beyond fit size (%#x).\n",
+ read_fit->offset, state->fit->len);
+goto exit;
+}
+
+read_length = MIN(read_length, state->fit->len - read_fit->offset);
+nvdimm_debug("read length %#x.\n", read_length);
+
+fit_out.status = cpu_to_le32(NVDIMM_DSM_STATUS_SUCCESS);
+fit_out.length = cpu_to_le32(read_length);
+g_array_append_vals(out, &fit_out, sizeof(fit_out));
+
+if (read_length) {
+g_array_append_vals(out, state->fit->data + read_fit->offset,
+read_length);
+}
+return;
+
+exit:
+nvdimm_dsm_write_status(out, status);
+}
+
+static void nvdimm_dsm_root(AcpiNVDIMMState *state, NvdimmDsmIn *in,
+GArray *out)
 {
 uint32_t status = NVDIMM_DSM_STATUS_NOT_SUPPORTED;
 
@@ -475,6 +551,10 @@ static void nvdimm_dsm_root(NvdimmDsmIn *in, GArray *out)
 return;
 }
 
+if (in->function == NVDIMM_DSM_FUNC_READ_FIT /* FIT Read */) {
+return nvdimm_dsm_func_read_fit(state, in, out);
+}
+
 nvdimm_debug("Return status %#x.\n", status);
 nvdimm_dsm_write_status(out, status);
 }
@@ -710,7 +790,7 @@ nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size)
 
 /* Handle 0 is reserved for NVDIMM Root Device. */
 if (!in->handle) {
-nvdimm_dsm_root(in, out);
+nvdimm_dsm_root(state, in, out);
 goto exit;
 }
 
@@ -925,8 +1005,88 @@ static void nvdimm_build_acpi_devices(GSList 
*device_list, A

[Qemu-devel] [PATCH v6 25/33] nvdimm acpi: build ACPI nvdimm devices

2015-10-29 Thread Xiao Guangrong
NVDIMM devices is defined in ACPI 6.0 9.20 NVDIMM Devices

There is a root device under \_SB and specified NVDIMM devices are under the
root device. Each NVDIMM device has _ADR which returns its handle used to
associate MEMDEV structure in NFIT

We reserve handle 0 for root device. In this patch, we save handle, handle,
arg1 and arg2 to dsm memory. Arg3 is conditionally saved in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/nvdimm.c | 184 +++
 1 file changed, 184 insertions(+)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index dd84e5f..53ed675 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -368,6 +368,15 @@ static void nvdimm_build_nfit(GSList *device_list, GArray 
*table_offsets,
 g_array_free(structures, true);
 }
 
+struct NvdimmDsmIn {
+uint32_t handle;
+uint32_t revision;
+uint32_t function;
+   /* the remaining size in the page is used by arg3. */
+uint8_t arg3[0];
+} QEMU_PACKED;
+typedef struct NvdimmDsmIn NvdimmDsmIn;
+
 static uint64_t
 nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size)
 {
@@ -377,6 +386,7 @@ nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size)
 static void
 nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
 {
+fprintf(stderr, "BUG: we never write DSM notification IO Port.\n");
 }
 
 static const MemoryRegionOps nvdimm_dsm_ops = {
@@ -402,6 +412,179 @@ void nvdimm_init_acpi_state(MemoryRegion *memory, 
MemoryRegion *io,
 memory_region_add_subregion(io, NVDIMM_ACPI_IO_BASE, &state->io_mr);
 }
 
+#define BUILD_STA_METHOD(_dev_, _method_)  \
+do {   \
+_method_ = aml_method("_STA", 0);  \
+aml_append(_method_, aml_return(aml_int(0x0f)));   \
+aml_append(_dev_, _method_);   \
+} while (0)
+
+#define BUILD_DSM_METHOD(_dev_, _method_, _handle_, _uuid_)\
+do {   \
+Aml *ifctx, *uuid; \
+_method_ = aml_method("_DSM", 4);  \
+/* check UUID if it is we expect, return the errorcode if not.*/   \
+uuid = aml_touuid(_uuid_); \
+ifctx = aml_if(aml_lnot(aml_equal(aml_arg(0), uuid))); \
+aml_append(ifctx, aml_return(aml_int(1 /* Not Supported */))); \
+aml_append(method, ifctx); \
+aml_append(method, aml_return(aml_call4("NCAL", aml_int(_handle_), \
+   aml_arg(1), aml_arg(2), aml_arg(3;  \
+aml_append(_dev_, _method_);   \
+} while (0)
+
+#define BUILD_FIELD_UNIT_SIZE(_field_, _byte_, _name_) \
+aml_append(_field_, aml_named_field(_name_, (_byte_) * BITS_PER_BYTE))
+
+#define BUILD_FIELD_UNIT_STRUCT(_field_, _s_, _f_, _name_) \
+BUILD_FIELD_UNIT_SIZE(_field_, sizeof(typeof_field(_s_, _f_)), _name_)
+
+static void build_nvdimm_devices(GSList *device_list, Aml *root_dev)
+{
+for (; device_list; device_list = device_list->next) {
+NVDIMMDevice *nvdimm = device_list->data;
+int slot = object_property_get_int(OBJECT(nvdimm), DIMM_SLOT_PROP,
+   NULL);
+uint32_t handle = nvdimm_slot_to_handle(slot);
+Aml *dev, *method;
+
+dev = aml_device("NV%02X", slot);
+aml_append(dev, aml_name_decl("_ADR", aml_int(handle)));
+
+BUILD_STA_METHOD(dev, method);
+
+/*
+ * Chapter 4: _DSM Interface for NVDIMM Device (non-root) - Example
+ * in DSM Spec Rev1.
+ */
+BUILD_DSM_METHOD(dev, method,
+ handle /* NVDIMM Device Handle */,
+ "4309AC30-0D11-11E4-9191-0800200C9A66"
+ /* UUID for NVDIMM Devices. */);
+
+aml_append(root_dev, dev);
+}
+}
+
+static void nvdimm_build_acpi_devices(GSList *device_list, Aml *sb_scope)
+{
+Aml *dev, *method, *field;
+uint64_t page_size = TARGET_PAGE_SIZE;
+
+dev = aml_device("NVDR");
+aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0012")));
+
+/* map DSM memory and IO into ACPI namespace. */
+aml_append(dev, aml_operation_region("NPIO", AML_SYSTEM_IO,
+   NVDIMM_ACPI_IO_BASE, NVDIMM_ACPI_IO_LEN));
+aml_append(dev, aml_operation_region("NRAM", AML_SYSTEM_MEMORY,
+   NVDIMM_ACPI_MEM_BASE, page_size));
+
+/*
+ * DSM notifier:
+ * @NOTI: Read it will notify QEMU that _DSM method is being
+ *called and the parameters can be found in NvdimmDsmIn.
+ *The value read from it is the buffer size of

[Qemu-devel] [PATCH v6 24/33] nvdimm acpi: build ACPI NFIT table

2015-10-29 Thread Xiao Guangrong
NFIT is defined in ACPI 6.0: 5.2.25 NVDIMM Firmware Interface Table (NFIT)

Currently, we only support PMEM mode. Each device has 3 structures:
- SPA structure, defines the PMEM region info

- MEM DEV structure, it has the @handle which is used to associate specified
  ACPI NVDIMM  device we will introduce in later patch.
  Also we can happily ignored the memory device's interleave, the real
  nvdimm hardware access is hidden behind host

- DCR structure, it defines vendor ID used to associate specified vendor
  nvdimm driver. Since we only implement PMEM mode this time, Command
  window and Data window are not needed

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/nvdimm.c| 355 
 hw/i386/acpi-build.c|   6 +
 include/hw/mem/nvdimm.h |  10 ++
 3 files changed, 371 insertions(+)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 1223da2..dd84e5f 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -26,8 +26,348 @@
  * License along with this library; if not, see 
  */
 
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/aml-build.h"
 #include "hw/mem/nvdimm.h"
 
+static int nvdimm_plugged_device_list(Object *obj, void *opaque)
+{
+GSList **list = opaque;
+
+if (object_dynamic_cast(obj, TYPE_NVDIMM)) {
+NVDIMMDevice *nvdimm = NVDIMM(obj);
+
+if (memory_region_is_mapped(&nvdimm->nvdimm_mr)) {
+*list = g_slist_append(*list, DEVICE(obj));
+}
+}
+
+object_child_foreach(obj, nvdimm_plugged_device_list, opaque);
+return 0;
+}
+
+/*
+ * inquire plugged NVDIMM devices and link them into the list which is
+ * returned to the caller.
+ *
+ * Note: it is the caller's responsibility to free the list to avoid
+ * memory leak.
+ */
+static GSList *nvdimm_get_plugged_device_list(void)
+{
+GSList *list = NULL;
+
+object_child_foreach(qdev_get_machine(), nvdimm_plugged_device_list,
+ &list);
+return list;
+}
+
+#define NVDIMM_UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+   { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
+ (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff,  \
+ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }
+/*
+ * define Byte Addressable Persistent Memory (PM) Region according to
+ * ACPI 6.0: 5.2.25.1 System Physical Address Range Structure.
+ */
+static const uint8_t nvdimm_nfit_spa_uuid[] =
+  NVDIMM_UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
+ 0x18, 0xb7, 0x8c, 0xdb);
+
+/*
+ * NVDIMM Firmware Interface Table
+ * @signature: "NFIT"
+ *
+ * It provides information that allows OSPM to enumerate NVDIMM present in
+ * the platform and associate system physical address ranges created by the
+ * NVDIMMs.
+ *
+ * It is defined in ACPI 6.0: 5.2.25 NVDIMM Firmware Interface Table (NFIT)
+ */
+struct NvdimmNfitHeader {
+ACPI_TABLE_HEADER_DEF
+uint32_t reserved;
+} QEMU_PACKED;
+typedef struct NvdimmNfitHeader NvdimmNfitHeader;
+
+/*
+ * define NFIT structures according to ACPI 6.0: 5.2.25 NVDIMM Firmware
+ * Interface Table (NFIT).
+ */
+
+/*
+ * System Physical Address Range Structure
+ *
+ * It describes the system physical address ranges occupied by NVDIMMs and
+ * the types of the regions.
+ */
+struct NvdimmNfitSpa {
+uint16_t type;
+uint16_t length;
+uint16_t spa_index;
+uint16_t flags;
+uint32_t reserved;
+uint32_t proximity_domain;
+uint8_t type_guid[16];
+uint64_t spa_base;
+uint64_t spa_length;
+uint64_t mem_attr;
+} QEMU_PACKED;
+typedef struct NvdimmNfitSpa NvdimmNfitSpa;
+
+/*
+ * Memory Device to System Physical Address Range Mapping Structure
+ *
+ * It enables identifying each NVDIMM region and the corresponding SPA
+ * describing the memory interleave
+ */
+struct NvdimmNfitMemDev {
+uint16_t type;
+uint16_t length;
+uint32_t nfit_handle;
+uint16_t phys_id;
+uint16_t region_id;
+uint16_t spa_index;
+uint16_t dcr_index;
+uint64_t region_len;
+uint64_t region_offset;
+uint64_t region_dpa;
+uint16_t interleave_index;
+uint16_t interleave_ways;
+uint16_t flags;
+uint16_t reserved;
+} QEMU_PACKED;
+typedef struct NvdimmNfitMemDev NvdimmNfitMemDev;
+
+/*
+ * NVDIMM Control Region Structure
+ *
+ * It describes the NVDIMM and if applicable, Block Control Window.
+ */
+struct NvdimmNfitControlRegion {
+uint16_t type;
+uint16_t length;
+uint16_t dcr_index;
+uint16_t vendor_id;
+uint16_t device_id;
+uint16_t revision_id;
+uint16_t sub_vendor_id;
+uint16_t sub_device_id;
+uint16_t sub_revision_id;
+uint8_t reserved[6];
+uint32_t serial_number;
+uint16_t fic;
+uint16_t num_bcw;
+uint64_t bcw_size;
+uint64_t cmd_offset;
+uint64_t cmd_size;
+uint64_t status_offset;
+uint64_t status_size;
+uint16_t flags;
+uint8_t reserved2[6];
+} QEMU_PACK

[Qemu-devel] [PATCH v6 23/33] nvdimm acpi: init the resource used by NVDIMM ACPI

2015-10-29 Thread Xiao Guangrong
A page staring from 0xFF0 and IO port 0x0a18 - 0xa1b in guest are
reserved for NVDIMM ACPI emulation, refer to docs/specs/acpi_nvdimm.txt
for detailed design

A parameter, 'nvdimm-support', is introduced for PIIX4_PM and ICH9-LPC
that controls if nvdimm support is enabled, it is true on default and
it is false on 2.4 and its earlier version to keep compatibility

Signed-off-by: Xiao Guangrong 
---
 default-configs/i386-softmmu.mak |  1 +
 default-configs/mips-softmmu.mak |  1 +
 default-configs/mips64-softmmu.mak   |  1 +
 default-configs/mips64el-softmmu.mak |  1 +
 default-configs/mipsel-softmmu.mak   |  1 +
 default-configs/x86_64-softmmu.mak   |  1 +
 hw/acpi/Makefile.objs|  1 +
 hw/acpi/ich9.c   | 24 ++
 hw/acpi/nvdimm.c | 63 
 hw/acpi/piix4.c  | 27 
 include/hw/acpi/ich9.h   |  3 ++
 include/hw/i386/pc.h | 10 ++
 include/hw/mem/nvdimm.h  | 34 +++
 13 files changed, 161 insertions(+), 7 deletions(-)
 create mode 100644 hw/acpi/nvdimm.c

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 4e84a1c..51e71d4 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -48,6 +48,7 @@ CONFIG_IOAPIC=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
 CONFIG_NVDIMM=y
+CONFIG_ACPI_NVDIMM=y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index 44467c3..6b8b70e 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -17,6 +17,7 @@ CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_ACPI_X86=y
 CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_NVDIMM=y
 CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
diff --git a/default-configs/mips64-softmmu.mak 
b/default-configs/mips64-softmmu.mak
index 66ed5f9..ea820f6 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -17,6 +17,7 @@ CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_ACPI_X86=y
 CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_NVDIMM=y
 CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index bfca2b2..8993851 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -17,6 +17,7 @@ CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_ACPI_X86=y
 CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_NVDIMM=y
 CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
diff --git a/default-configs/mipsel-softmmu.mak 
b/default-configs/mipsel-softmmu.mak
index 0162ef0..87ab964 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -17,6 +17,7 @@ CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_ACPI_X86=y
 CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_NVDIMM=y
 CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index e877a86..0a7dc10 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -48,6 +48,7 @@ CONFIG_IOAPIC=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
 CONFIG_NVDIMM=y
+CONFIG_ACPI_NVDIMM=y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 7d3230c..84c082d 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -2,6 +2,7 @@ common-obj-$(CONFIG_ACPI_X86) += core.o piix4.o pcihp.o
 common-obj-$(CONFIG_ACPI_X86_ICH) += ich9.o tco.o
 common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o
 common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
+obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
 common-obj-$(CONFIG_ACPI) += acpi_interface.o
 common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
 common-obj-$(CONFIG_ACPI) += aml-build.o
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 1e9ae20..603c1bd 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -280,6 +280,12 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
  &pm->acpi_memory_hotplug);
 }
+
+if (pm->acpi_nvdimm_state.is_enabled) {
+nvdimm_init_acpi_state(pci_address_space(lpc_pci),
+   pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
+   &pm->acpi_nvdimm_state);
+}
 }
 
 static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v,
@@ -307,6 +313,20 @@ static void ich9_pm_set_memory_hotplug_support(Object 
*obj, bool value,
 s->pm.acpi_memory_hotplug.is_enabled = value;
 }
 
+static bool ich9_pm_get_nvdimm_support(Object *obj, Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+return s->pm.acpi_nvdimm_state.is_enabled;
+}
+
+static void ich9_pm_set_nvdimm_support(Object *obj, bool value, Error **

[Qemu-devel] [PATCH v6 26/33] nvdimm acpi: save arg3 for NVDIMM device _DSM method

2015-10-29 Thread Xiao Guangrong
Check if the input Arg3 is valid then store it into dsm_in if needed

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/nvdimm.c | 27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 53ed675..e179a72 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -524,13 +524,38 @@ static void nvdimm_build_acpi_devices(GSList 
*device_list, Aml *sb_scope)
 
 method = aml_method_serialized("NCAL", 4);
 {
-Aml *buffer_size = aml_local(0);
+Aml *ifctx, *pckg, *buffer_size = aml_local(0);
 
 aml_append(method, aml_store(aml_arg(0), aml_name("HDLE")));
 aml_append(method, aml_store(aml_arg(1), aml_name("REVS")));
 aml_append(method, aml_store(aml_arg(2), aml_name("FUNC")));
 
 /*
+ * The fourth parameter (Arg3) of _DSM is a package which contains
+ * a buffer, the layout of the buffer is specified by UUID (Arg0),
+ * Revision ID (Arg1) and Function Index (Arg2) which are documented
+ * in the DSM Spec.
+ */
+pckg = aml_arg(3);
+ifctx = aml_if(aml_and(aml_equal(aml_object_type(pckg),
+ aml_int(4 /* Package */)),
+   aml_equal(aml_sizeof(pckg),
+ aml_int(1;
+{
+Aml *pckg_index, *pckg_buf;
+
+pckg_index = aml_local(2);
+pckg_buf = aml_local(3);
+
+aml_append(ifctx, aml_store(aml_index(pckg, aml_int(0)),
+pckg_index));
+aml_append(ifctx, aml_store(aml_derefof(pckg_index),
+pckg_buf));
+aml_append(ifctx, aml_store(pckg_buf, aml_name("ARG3")));
+}
+aml_append(method, ifctx);
+
+/*
  * transfer control to QEMU and the buffer size filled by
  * QEMU is returned.
  */
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 31/33] nvdimm: allow using whole backend memory as pmem

2015-10-29 Thread Xiao Guangrong
Introduce a parameter, named "reserve-label-data", if it is
false which indicates that QEMU does not reserve any region
on the backend memory to support label data. It is a
'label-less' NVDIMM device mode that linux will use whole
memory on the device as a single namesapce

This is useful for the users who want to pass whole nvdimm
device and make its data completely be visible to guest

The parameter is false on default

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/nvdimm.c| 12 
 hw/mem/nvdimm.c | 43 ---
 include/hw/mem/nvdimm.h |  6 ++
 3 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 5c8be41..f8d7d19 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -531,6 +531,12 @@ static void nvdimm_dsm_func_label_size(NVDIMMDevice 
*nvdimm, GArray *out)
 static uint32_t nvdimm_rw_label_data_check(NVDIMMDevice *nvdimm,
uint32_t offset, uint32_t length)
 {
+if (!nvdimm->reserve_label_data) {
+nvdimm_debug("read/write label request on the device without "
+ "label data reserved.\n");
+return NVDIMM_DSM_STATUS_NOT_SUPPORTED;
+}
+
 if (offset + length < offset) {
 nvdimm_debug("offset %#x + length %#x is overflow.\n", offset,
  length);
@@ -637,6 +643,12 @@ static void nvdimm_dsm_device(NvdimmDsmIn *in, GArray *out)
1 << 4 /* Get Namespace Label Size */ |
1 << 5 /* Get Namespace Label Data */ |
1 << 6 /* Set Namespace Label Data */);
+
+/* no function support if the device does not have label data. */
+if (!nvdimm->reserve_label_data) {
+cmd_list = cpu_to_le64(0);
+}
+
 build_append_int_noprefix(out, cmd_list, sizeof(cmd_list));
 goto free;
 case 0x4 /* Get Namespace Label Size */:
diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index 185aa1a..1d89165 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -36,14 +36,15 @@ static void nvdimm_realize(DIMMDevice *dimm, Error **errp)
 {
 MemoryRegion *mr;
 NVDIMMDevice *nvdimm = NVDIMM(dimm);
-uint64_t size;
+uint64_t reserved_label_size, size;
 
 nvdimm->label_size = MIN_NAMESPACE_LABEL_SIZE;
+reserved_label_size = nvdimm->reserve_label_data ? nvdimm->label_size : 0;
 
 mr = host_memory_backend_get_memory(dimm->hostmem, errp);
 size = memory_region_size(mr);
 
-if (size <= nvdimm->label_size) {
+if (size <= reserved_label_size) {
 char *path = 
object_get_canonical_path_component(OBJECT(dimm->hostmem));
 error_setg(errp, "the size of memdev %s (0x%" PRIx64 ") is too small"
" to contain nvdimm namespace label (0x%" PRIx64 ")", path,
@@ -52,15 +53,19 @@ static void nvdimm_realize(DIMMDevice *dimm, Error **errp)
 }
 
 memory_region_init_alias(&nvdimm->nvdimm_mr, OBJECT(dimm), "nvdimm-memory",
- mr, 0, size - nvdimm->label_size);
-nvdimm->label_data = memory_region_get_ram_ptr(mr) +
- memory_region_size(&nvdimm->nvdimm_mr);
+ mr, 0, size - reserved_label_size);
+
+if (reserved_label_size) {
+nvdimm->label_data = memory_region_get_ram_ptr(mr) +
+ memory_region_size(&nvdimm->nvdimm_mr);
+}
 }
 
 static void nvdimm_read_label_data(NVDIMMDevice *nvdimm, void *buf,
uint64_t size, uint64_t offset)
 {
-assert((nvdimm->label_size >= size + offset) && (offset + size > offset));
+assert(nvdimm->reserve_label_data &&
+   (nvdimm->label_size >= size + offset) && (offset + size > offset));
 
 memcpy(buf, nvdimm->label_data + offset, size);
 }
@@ -72,7 +77,8 @@ static void nvdimm_write_label_data(NVDIMMDevice *nvdimm, 
const void *buf,
 DIMMDevice *dimm = DIMM(nvdimm);
 uint64_t backend_offset;
 
-assert((nvdimm->label_size >= size + offset) && (offset + size > offset));
+assert(nvdimm->reserve_label_data &&
+   (nvdimm->label_size >= size + offset) && (offset + size > offset));
 
 memcpy(nvdimm->label_data + offset, buf, size);
 
@@ -97,10 +103,33 @@ static void nvdimm_class_init(ObjectClass *oc, void *data)
 nvc->write_label_data = nvdimm_write_label_data;
 }
 
+static bool nvdimm_get_reserve_label_data(Object *obj, Error **errp)
+{
+NVDIMMDevice *nvdimm = NVDIMM(obj);
+
+return nvdimm->reserve_label_data;
+}
+
+static void
+nvdimm_set_reserve_label_data(Object *obj, bool value, Error **errp)
+{
+NVDIMMDevice *nvdimm = NVDIMM(obj);
+
+nvdimm->reserve_label_data = value;
+}
+
+static void nvdimm_init(Object *obj)
+{
+object_property_add_bool(obj, "reserve-label-data",
+ nvdimm_get_reserve_label_data,
+ nvdimm_set_reserve_labe

[Qemu-devel] [PATCH v6 22/33] docs: add NVDIMM ACPI documentation

2015-10-29 Thread Xiao Guangrong
It describes the basic concepts of NVDIMM ACPI and the interface
between QEMU and the ACPI BIOS

Signed-off-by: Xiao Guangrong 
---
 docs/specs/acpi_nvdimm.txt | 179 +
 1 file changed, 179 insertions(+)
 create mode 100644 docs/specs/acpi_nvdimm.txt

diff --git a/docs/specs/acpi_nvdimm.txt b/docs/specs/acpi_nvdimm.txt
new file mode 100644
index 000..cc5db2c
--- /dev/null
+++ b/docs/specs/acpi_nvdimm.txt
@@ -0,0 +1,179 @@
+QEMU<->ACPI BIOS NVDIMM interface
+-
+
+QEMU supports NVDIMM via ACPI. This document describes the basic concepts of
+NVDIMM ACPI and the interface between QEMU and the ACPI BIOS.
+
+NVDIMM ACPI Background
+--
+NVDIMM is introduced in ACPI 6.0 which defines an NVDIMM root device under
+_SB scope with a _HID of “ACPI0012”. For each NVDIMM present or intended
+to be supported by platform, platform firmware also exposes an ACPI
+Namespace Device under the root device.
+
+The NVDIMM child devices under the NVDIMM root device are defined with _ADR
+corresponding to the NFIT device handle. The NVDIMM root device and the
+NVDIMM devices can have device specific methods (_DSM) to provide additional
+functions specific to a particular NVDIMM implementation.
+
+This is an example from ACPI 6.0, a platform contains one NVDIMM:
+
+Scope (\_SB){
+   Device (NVDR) // Root device
+   {
+  Name (_HID, “ACPI0012”)
+  Method (_STA) {...}
+  Method (_FIT) {...}
+  Method (_DSM, ...) {...}
+  Device (NVD)
+  {
+ Name(_ADR, h) //where h is NFIT Device Handle for this NVDIMM
+ Method (_DSM, ...) {...}
+  }
+   }
+}
+
+Methods supported on both NVDIMM root device and NVDIMM device are
+1) _STA(Status)
+   It returns the current status of a device, which can be one of the
+   following: enabled, disabled, or removed.
+
+   Arguments: None
+
+   Return Value:
+   It returns an An Integer which is defined as followings:
+   Bit [0] – Set if the device is present.
+   Bit [1] – Set if the device is enabled and decoding its resources.
+   Bit [2] – Set if the device should be shown in the UI.
+   Bit [3] – Set if the device is functioning properly (cleared if device
+ failed its diagnostics).
+   Bit [4] – Set if the battery is present.
+   Bits [31:5] – Reserved (must be cleared).
+
+2) _DSM (Device Specific Method)
+   It is a control method that enables devices to provide device specific
+   control functions that are consumed by the device driver.
+   The NVDIMM DSM specification can be found at:
+http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf
+
+   Arguments:
+   Arg0 – A Buffer containing a UUID (16 Bytes)
+   Arg1 – An Integer containing the Revision ID (4 Bytes)
+   Arg2 – An Integer containing the Function Index (4 Bytes)
+   Arg3 – A package containing parameters for the function specified by the
+  UUID, Revision ID, and Function Index
+
+   Return Value:
+   If Function Index = 0, a Buffer containing a function index bitfield.
+   Otherwise, the return value and type depends on the UUID, revision ID
+   and function index which are described in the DSM specification.
+
+Methods on NVDIMM ROOT Device
+_FIT(Firmware Interface Table)
+   It evaluates to a buffer returning data in the format of a series of NFIT
+   Type Structure.
+
+   Arguments: None
+
+   Return Value:
+   A Buffer containing a list of NFIT Type structure entries.
+
+   The detailed definition of the structure can be found at ACPI 6.0: 5.2.25
+   NVDIMM Firmware Interface Table (NFIT).
+
+QEMU NVDIMM Implemention
+
+QEMU reserves a page starting from 0xFF0 and 4 bytes IO Port starting
+from 0x0a18 for NVDIMM ACPI.
+
+Memory 0xFF0 - 0xFF00FFF:
+   This page is RAM-based and it is used to transfer data between _DSM
+   method and QEMU. If ACPI has control, this pages is owned by ACPI which
+   writes _DSM input data to it, otherwise, it is owned by QEMU which
+   emulates _DSM access and writes the output data to it.
+
+   ACPI Writes _DSM Input Data:
+   [0xFF0 - 0xFF3]: 4 bytes, NVDIMM Devcie Handle, 0 is reserved
+for NVDIMM Root device.
+   [0xFF4 - 0xFF7]: 4 bytes, Revision ID, that is the Arg1 of _DSM
+method.
+   [0xFF8 - 0xFFB]: 4 bytes. Function Index, that is the Arg2 of
+_DSM method.
+   [0xFFC - 0xFF00FFF]: 4084 bytes, the Arg3 of _DSM method
+
+   QEMU Writes Output Data:
+   [0xFF0 - 0xFF00FFF]: the DSM return result filled by QEMU
+
+IO Port 0x0a18 - 0xa1b:
+   ACPI uses it to transfer control from guest to QEMU and read the size
+   of return result filled by QEMU
+
+   Read Access:
+   [0x0a18 - 0xa1b]: 4 bytes, the buffer size of _DSM output data.
+
+_DSM process diagram:
+-
+The page, 0xFF0 - 0xFF00FFF, is used by _DSM Virtualization.
+
+ +--+  +

[Qemu-devel] [PATCH v6 21/33] nvdimm: implement NVDIMM device abstract

2015-10-29 Thread Xiao Guangrong
Introduce "nvdimm" device which is based on dimm device type

128K memory region which is the minimum namespace label size
required by NVDIMM Namespace Spec locates at the end of
backend memory device is reserved for label data

We can use "-m 1G,maxmem=100G,slots=10 -object memory-backend-file,
id=mem1,size=1G,mem-path=/dev/pmem0 -device nvdimm,memdev=mem1" to
create NVDIMM device for guest

Signed-off-by: Xiao Guangrong 
---
 default-configs/i386-softmmu.mak   |   1 +
 default-configs/x86_64-softmmu.mak |   1 +
 hw/acpi/memory_hotplug.c   |   6 ++
 hw/mem/Makefile.objs   |   1 +
 hw/mem/nvdimm.c| 113 +
 include/hw/mem/nvdimm.h|  83 +++
 6 files changed, 205 insertions(+)
 create mode 100644 hw/mem/nvdimm.c
 create mode 100644 include/hw/mem/nvdimm.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 3ece8bb..4e84a1c 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -47,6 +47,7 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_NVDIMM=y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index 92ea7c1..e877a86 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -47,6 +47,7 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_NVDIMM=y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 20d3093..bb5a29f 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -1,6 +1,7 @@
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/pc-hotplug.h"
 #include "hw/mem/dimm.h"
+#include "hw/mem/nvdimm.h"
 #include "hw/boards.h"
 #include "hw/qdev-core.h"
 #include "trace.h"
@@ -231,6 +232,11 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, 
MemHotplugState *mem_st,
 {
 MemStatus *mdev;
 
+/* Currently, NVDIMM hotplug has not been supported yet. */
+if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
+return;
+}
+
 mdev = acpi_memory_slot_status(mem_st, dev, errp);
 if (!mdev) {
 return;
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index cebb4b1..12d9b72 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1,2 +1,3 @@
 common-obj-$(CONFIG_DIMM) += dimm.o
 common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
+common-obj-$(CONFIG_NVDIMM) += nvdimm.o
diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
new file mode 100644
index 000..185aa1a
--- /dev/null
+++ b/hw/mem/nvdimm.c
@@ -0,0 +1,113 @@
+/*
+ * Non-Volatile Dual In-line Memory Module Virtualization Implementation
+ *
+ * Copyright(C) 2015 Intel Corporation.
+ *
+ * Author:
+ *  Xiao Guangrong 
+ *
+ * Currently, it only supports PMEM Virtualization.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qapi/visitor.h"
+#include "hw/mem/nvdimm.h"
+
+static MemoryRegion *nvdimm_get_memory_region(DIMMDevice *dimm)
+{
+NVDIMMDevice *nvdimm = NVDIMM(dimm);
+
+return memory_region_size(&nvdimm->nvdimm_mr) ? &nvdimm->nvdimm_mr : NULL;
+}
+
+static void nvdimm_realize(DIMMDevice *dimm, Error **errp)
+{
+MemoryRegion *mr;
+NVDIMMDevice *nvdimm = NVDIMM(dimm);
+uint64_t size;
+
+nvdimm->label_size = MIN_NAMESPACE_LABEL_SIZE;
+
+mr = host_memory_backend_get_memory(dimm->hostmem, errp);
+size = memory_region_size(mr);
+
+if (size <= nvdimm->label_size) {
+char *path = 
object_get_canonical_path_component(OBJECT(dimm->hostmem));
+error_setg(errp, "the size of memdev %s (0x%" PRIx64 ") is too small"
+   " to contain nvdimm namespace label (0x%" PRIx64 ")", path,
+   memory_region_size(mr), nvdimm->label_size);
+return;
+}
+
+memory_region_init_alias(&nvdimm->nvdimm_mr, OBJECT(dimm), "nvdimm-memory",
+ mr, 0, size - nvdimm->label_size);
+nvdimm->label_data = memory_region_get_ram_ptr(mr) +
+ memory_region_size(&nvdimm->nvdimm_mr);
+}
+
+static void nvdimm_read_label_data(NVDIMMDevice *nvdimm, void *buf,
+   uint64_t size, uint64_t offset)
+{

[Qemu-devel] [PATCH v6 18/33] dimm: get mapped memory region from DIMMDeviceClass->get_memory_region

2015-10-29 Thread Xiao Guangrong
Curretly, the memory region of backed memory is directly mapped to
guest's address space, however, it is not true for nvdimm device

This patch let dimm device realize this fact and use
DIMMDeviceClass->get_memory_region method to get the mapped memory
region

Signed-off-by: Xiao Guangrong 
---
 hw/mem/dimm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 4a63409..498d380 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -377,8 +377,9 @@ static void dimm_get_size(Object *obj, Visitor *v, void 
*opaque,
 int64_t value;
 MemoryRegion *mr;
 DIMMDevice *dimm = DIMM(obj);
+DIMMDeviceClass *ddc = DIMM_GET_CLASS(obj);
 
-mr = host_memory_backend_get_memory(dimm->hostmem, errp);
+mr = ddc->get_memory_region(dimm);
 value = memory_region_size(mr);
 
 visit_type_int(v, &value, name, errp);
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 14/33] pc-dimm: drop the prefix of pc-dimm

2015-10-29 Thread Xiao Guangrong
This patch is generated by this script:

find ./ -name "*.[ch]" -o -name "*.json" -o -name "trace-events" -type f \
| xargs sed -i "s/PC_DIMM/DIMM/g"

find ./ -name "*.[ch]" -o -name "*.json" -o -name "trace-events" -type f \
| xargs sed -i "s/PCDIMM/DIMM/g"

find ./ -name "*.[ch]" -o -name "*.json" -o -name "trace-events" -type f \
| xargs sed -i "s/pc_dimm/dimm/g"

find ./ -name "trace-events" -type f | xargs sed -i "s/pc-dimm/dimm/g"

It prepares the work which abstracts dimm device type for both pc-dimm and
nvdimm

Signed-off-by: Xiao Guangrong 
---
 hmp.c   |   2 +-
 hw/acpi/ich9.c  |   6 +-
 hw/acpi/memory_hotplug.c|  16 ++---
 hw/acpi/piix4.c |   6 +-
 hw/i386/pc.c|  32 -
 hw/mem/pc-dimm.c| 148 
 hw/ppc/spapr.c  |  18 ++---
 include/hw/mem/pc-dimm.h|  62 -
 numa.c  |   2 +-
 qapi-schema.json|   8 +--
 qmp.c   |   2 +-
 stubs/qmp_pc_dimm_device_list.c |   2 +-
 trace-events|   8 +--
 13 files changed, 156 insertions(+), 156 deletions(-)

diff --git a/hmp.c b/hmp.c
index 5048eee..5c617d2 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1952,7 +1952,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict 
*qdict)
 MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
 MemoryDeviceInfoList *info;
 MemoryDeviceInfo *value;
-PCDIMMDeviceInfo *di;
+DIMMDeviceInfo *di;
 
 for (info = info_list; info; info = info->next) {
 value = info->value;
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 1c7fcfa..b0d6a67 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -440,7 +440,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, 
Error **errp)
 void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
 {
 if (pm->acpi_memory_hotplug.is_enabled &&
-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
 acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
 dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
@@ -455,7 +455,7 @@ void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, 
DeviceState *dev,
   Error **errp)
 {
 if (pm->acpi_memory_hotplug.is_enabled &&
-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
 acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq,
   &pm->acpi_memory_hotplug, dev, errp);
 } else {
@@ -468,7 +468,7 @@ void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, 
DeviceState *dev,
   Error **errp)
 {
 if (pm->acpi_memory_hotplug.is_enabled &&
-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
 acpi_memory_unplug_cb(&pm->acpi_memory_hotplug, dev, errp);
 } else {
 error_setg(errp, "acpi: device unplug for not supported device"
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index ce428df..e687852 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -54,23 +54,23 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, 
hwaddr addr,
 o = OBJECT(mdev->dimm);
 switch (addr) {
 case 0x0: /* Lo part of phys address where DIMM is mapped */
-val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) : 0;
+val = o ? object_property_get_int(o, DIMM_ADDR_PROP, NULL) : 0;
 trace_mhp_acpi_read_addr_lo(mem_st->selector, val);
 break;
 case 0x4: /* Hi part of phys address where DIMM is mapped */
-val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 
0;
+val = o ? object_property_get_int(o, DIMM_ADDR_PROP, NULL) >> 32 : 0;
 trace_mhp_acpi_read_addr_hi(mem_st->selector, val);
 break;
 case 0x8: /* Lo part of DIMM size */
-val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) : 0;
+val = o ? object_property_get_int(o, DIMM_SIZE_PROP, NULL) : 0;
 trace_mhp_acpi_read_size_lo(mem_st->selector, val);
 break;
 case 0xc: /* Hi part of DIMM size */
-val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 
0;
+val = o ? object_property_get_int(o, DIMM_SIZE_PROP, NULL) >> 32 : 0;
 trace_mhp_acpi_read_size_hi(mem_st->selector, val);
 break;
 case 0x10: /* node proximity for _PXM method */
-val = o ? object_property_get_int(o, PC_DIMM_NODE_PROP, NULL) : 0;
+val = o ? object_property_get_int(o, DIMM_NODE_PROP, NULL) : 0;
 trace_mhp_acpi_read_pxm(mem_st->selector, val);
 break;
 case 0x14: /* pack and return is_* fields */

[Qemu-devel] [PATCH v6 19/33] dimm: keep the state of the whole backend memory

2015-10-29 Thread Xiao Guangrong
QEMU keeps the state of memory of dimm device during live migration,
however, it is not enough for nvdimm device as its memory does not
contain its label data, so that we should protect the whole backend
memory instead

Signed-off-by: Xiao Guangrong 
---
 hw/mem/dimm.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 498d380..7d1 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -134,9 +134,16 @@ void dimm_memory_plug(DeviceState *dev, MemoryHotplugState 
*hpms,
 }
 
 memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
-vmstate_register_ram(mr, dev);
 numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
 
+/*
+ * save the state only for @mr is not enough as it does not contain
+ * the label data of NVDIMM device, so that we keep the state of
+ * whole hostmem instead.
+ */
+vmstate_register_ram(host_memory_backend_get_memory(dimm->hostmem, errp),
+ dev);
+
 out:
 error_propagate(errp, local_err);
 }
@@ -145,10 +152,13 @@ void dimm_memory_unplug(DeviceState *dev, 
MemoryHotplugState *hpms,
MemoryRegion *mr)
 {
 DIMMDevice *dimm = DIMM(dev);
+MemoryRegion *backend_mr;
+
+backend_mr = host_memory_backend_get_memory(dimm->hostmem, &error_abort);
 
 numa_unset_mem_node_id(dimm->addr, memory_region_size(mr), dimm->node);
 memory_region_del_subregion(&hpms->mr, mr);
-vmstate_unregister_ram(mr, dev);
+vmstate_unregister_ram(backend_mr, dev);
 }
 
 int qmp_dimm_device_list(Object *obj, void *opaque)
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 20/33] dimm: introduce realize callback

2015-10-29 Thread Xiao Guangrong
nvdimm need check if the backend memory is large enough to contain label
data and init its memory region when the device is realized, so introduce
realize callback which is called after common dimm has been realize

Signed-off-by: Xiao Guangrong 
---
 hw/mem/dimm.c | 5 +
 include/hw/mem/dimm.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 7d1..0ae23ce 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -426,6 +426,7 @@ static void dimm_init(Object *obj)
 static void dimm_realize(DeviceState *dev, Error **errp)
 {
 DIMMDevice *dimm = DIMM(dev);
+DIMMDeviceClass *ddc = DIMM_GET_CLASS(dimm);
 
 if (!dimm->hostmem) {
 error_setg(errp, "'" DIMM_MEMDEV_PROP "' property is not set");
@@ -438,6 +439,10 @@ static void dimm_realize(DeviceState *dev, Error **errp)
dimm->node, nb_numa_nodes ? nb_numa_nodes : 1);
 return;
 }
+
+if (ddc->realize) {
+ddc->realize(dimm, errp);
+}
 }
 
 static void dimm_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 50f768a..72ec24c 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -65,6 +65,7 @@ typedef struct DIMMDeviceClass {
 DeviceClass parent_class;
 
 /* public */
+void (*realize)(DIMMDevice *dimm, Error **errp);
 MemoryRegion *(*get_memory_region)(DIMMDevice *dimm);
 } DIMMDeviceClass;
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 15/33] stubs: rename qmp_pc_dimm_device_list.c

2015-10-29 Thread Xiao Guangrong
Rename qmp_pc_dimm_device_list.c to qmp_dimm_device_list.c

Signed-off-by: Xiao Guangrong 
---
 stubs/Makefile.objs | 2 +-
 stubs/{qmp_pc_dimm_device_list.c => qmp_dimm_device_list.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename stubs/{qmp_pc_dimm_device_list.c => qmp_dimm_device_list.c} (100%)

diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 251443b..d5c862a 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -32,6 +32,6 @@ stub-obj-y += vmstate.o
 stub-obj-$(CONFIG_WIN32) += fd-register.o
 stub-obj-y += cpus.o
 stub-obj-y += kvm.o
-stub-obj-y += qmp_pc_dimm_device_list.o
+stub-obj-y += qmp_dimm_device_list.o
 stub-obj-y += target-monitor-defs.o
 stub-obj-y += vhost.o
diff --git a/stubs/qmp_pc_dimm_device_list.c b/stubs/qmp_dimm_device_list.c
similarity index 100%
rename from stubs/qmp_pc_dimm_device_list.c
rename to stubs/qmp_dimm_device_list.c
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 13/33] pc-dimm: make pc_existing_dimms_capacity static and rename it

2015-10-29 Thread Xiao Guangrong
pc_existing_dimms_capacity() can be static since it is not used out of
pc-dimm.c and drop the pc_ prefix to prepare the work which abstracts
dimm device type from pc-dimm

Signed-off-by: Xiao Guangrong 
---
 hw/mem/pc-dimm.c | 73 
 include/hw/mem/pc-dimm.h |  1 -
 2 files changed, 36 insertions(+), 38 deletions(-)

diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 80f424b..2dcbbcd 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -32,6 +32,38 @@ typedef struct pc_dimms_capacity {
  Error**errp;
 } pc_dimms_capacity;
 
+static int existing_dimms_capacity_internal(Object *obj, void *opaque)
+{
+pc_dimms_capacity *cap = opaque;
+uint64_t *size = &cap->size;
+
+if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
+DeviceState *dev = DEVICE(obj);
+
+if (dev->realized) {
+(*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
+cap->errp);
+}
+
+if (cap->errp && *cap->errp) {
+return 1;
+}
+}
+object_child_foreach(obj, existing_dimms_capacity_internal, opaque);
+return 0;
+}
+
+static uint64_t existing_dimms_capacity(Error **errp)
+{
+pc_dimms_capacity cap;
+
+cap.size = 0;
+cap.errp = errp;
+
+existing_dimms_capacity_internal(qdev_get_machine(), &cap);
+return cap.size;
+}
+
 void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
  MemoryRegion *mr, uint64_t align, Error **errp)
 {
@@ -39,7 +71,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState 
*hpms,
 MachineState *machine = MACHINE(qdev_get_machine());
 PCDIMMDevice *dimm = PC_DIMM(dev);
 Error *local_err = NULL;
-uint64_t existing_dimms_capacity = 0;
+uint64_t dimms_capacity = 0;
 uint64_t addr;
 
 addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, 
&local_err);
@@ -55,17 +87,16 @@ void pc_dimm_memory_plug(DeviceState *dev, 
MemoryHotplugState *hpms,
 goto out;
 }
 
-existing_dimms_capacity = pc_existing_dimms_capacity(&local_err);
+dimms_capacity = existing_dimms_capacity(&local_err);
 if (local_err) {
 goto out;
 }
 
-if (existing_dimms_capacity + memory_region_size(mr) >
+if (dimms_capacity + memory_region_size(mr) >
 machine->maxram_size - machine->ram_size) {
 error_setg(&local_err, "not enough space, currently 0x%" PRIx64
" in use of total hot pluggable 0x" RAM_ADDR_FMT,
-   existing_dimms_capacity,
-   machine->maxram_size - machine->ram_size);
+   dimms_capacity, machine->maxram_size - machine->ram_size);
 goto out;
 }
 
@@ -120,38 +151,6 @@ void pc_dimm_memory_unplug(DeviceState *dev, 
MemoryHotplugState *hpms,
 vmstate_unregister_ram(mr, dev);
 }
 
-static int pc_existing_dimms_capacity_internal(Object *obj, void *opaque)
-{
-pc_dimms_capacity *cap = opaque;
-uint64_t *size = &cap->size;
-
-if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
-DeviceState *dev = DEVICE(obj);
-
-if (dev->realized) {
-(*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
-cap->errp);
-}
-
-if (cap->errp && *cap->errp) {
-return 1;
-}
-}
-object_child_foreach(obj, pc_existing_dimms_capacity_internal, opaque);
-return 0;
-}
-
-uint64_t pc_existing_dimms_capacity(Error **errp)
-{
-pc_dimms_capacity cap;
-
-cap.size = 0;
-cap.errp = errp;
-
-pc_existing_dimms_capacity_internal(qdev_get_machine(), &cap);
-return cap.size;
-}
-
 int qmp_pc_dimm_device_list(Object *obj, void *opaque)
 {
 MemoryDeviceInfoList ***prev = opaque;
diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index 11a8937..8a43548 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -87,7 +87,6 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
 int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
 
 int qmp_pc_dimm_device_list(Object *obj, void *opaque);
-uint64_t pc_existing_dimms_capacity(Error **errp);
 void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
  MemoryRegion *mr, uint64_t align, Error **errp);
 void pc_dimm_memory_unplug(DeviceState *dev, MemoryHotplugState *hpms,
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 17/33] dimm: abstract dimm device from pc-dimm

2015-10-29 Thread Xiao Guangrong
A base device, dimm, is abstracted from pc-dimm, so that we can
build nvdimm device based on dimm in the later patch

Signed-off-by: Xiao Guangrong 
---
 default-configs/i386-softmmu.mak   |  1 +
 default-configs/ppc64-softmmu.mak  |  1 +
 default-configs/x86_64-softmmu.mak |  1 +
 hw/mem/Makefile.objs   |  3 ++-
 hw/mem/dimm.c  | 11 ++---
 hw/mem/pc-dimm.c   | 46 ++
 include/hw/mem/dimm.h  |  4 ++--
 include/hw/mem/pc-dimm.h   |  7 ++
 8 files changed, 62 insertions(+), 12 deletions(-)
 create mode 100644 hw/mem/pc-dimm.c
 create mode 100644 include/hw/mem/pc-dimm.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 43c96d1..3ece8bb 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -18,6 +18,7 @@ CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_ACPI_X86=y
 CONFIG_ACPI_X86_ICH=y
+CONFIG_DIMM=y
 CONFIG_ACPI_MEMORY_HOTPLUG=y
 CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
diff --git a/default-configs/ppc64-softmmu.mak 
b/default-configs/ppc64-softmmu.mak
index bb71b23..482b8a1 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -54,3 +54,4 @@ CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
 CONFIG_MC146818RTC=y
 CONFIG_ISA_TESTDEV=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_DIMM=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index dfb8095..92ea7c1 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -18,6 +18,7 @@ CONFIG_FDC=y
 CONFIG_ACPI=y
 CONFIG_ACPI_X86=y
 CONFIG_ACPI_X86_ICH=y
+CONFIG_DIMM=y
 CONFIG_ACPI_MEMORY_HOTPLUG=y
 CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index 7563ef5..cebb4b1 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1 +1,2 @@
-common-obj-$(CONFIG_MEM_HOTPLUG) += dimm.o
+common-obj-$(CONFIG_DIMM) += dimm.o
+common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 9f55cee..4a63409 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -1,5 +1,5 @@
 /*
- * Dimm device for Memory Hotplug
+ * Dimm device abstraction
  *
  * Copyright ProfitBricks GmbH 2012
  * Copyright (C) 2014 Red Hat Inc
@@ -429,21 +429,13 @@ static void dimm_realize(DeviceState *dev, Error **errp)
 }
 }
 
-static MemoryRegion *dimm_get_memory_region(DIMMDevice *dimm)
-{
-return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
-}
-
 static void dimm_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
-DIMMDeviceClass *ddc = DIMM_CLASS(oc);
 
 dc->realize = dimm_realize;
 dc->props = dimm_properties;
 dc->desc = "DIMM memory module";
-
-ddc->get_memory_region = dimm_get_memory_region;
 }
 
 static TypeInfo dimm_info = {
@@ -453,6 +445,7 @@ static TypeInfo dimm_info = {
 .instance_init = dimm_init,
 .class_init= dimm_class_init,
 .class_size= sizeof(DIMMDeviceClass),
+.abstract  = true,
 };
 
 static void dimm_register_types(void)
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
new file mode 100644
index 000..38323e9
--- /dev/null
+++ b/hw/mem/pc-dimm.c
@@ -0,0 +1,46 @@
+/*
+ * Dimm device for Memory Hotplug
+ *
+ * Copyright ProfitBricks GmbH 2012
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "hw/mem/pc-dimm.h"
+
+static MemoryRegion *pc_dimm_get_memory_region(DIMMDevice *dimm)
+{
+return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
+}
+
+static void pc_dimm_class_init(ObjectClass *oc, void *data)
+{
+DIMMDeviceClass *ddc = DIMM_CLASS(oc);
+
+ddc->get_memory_region = pc_dimm_get_memory_region;
+}
+
+static TypeInfo pc_dimm_info = {
+.name  = TYPE_PC_DIMM,
+.parent= TYPE_DIMM,
+.class_init= pc_dimm_class_init,
+};
+
+static void pc_dimm_register_types(void)
+{
+type_register_static(&pc_dimm_info);
+}
+
+type_init(pc_dimm_register_types)
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index ece8786..50f768a 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -1,5 +1,5 @@
 /*
- * PC DIMM device
+ * Dimm device abstraction
  *
  * Copyright ProfitBricks GmbH 2012
  * Copyright (C) 201

[Qemu-devel] [PATCH v6 12/33] pc-dimm: remove DEFAULT_PC_DIMMSIZE

2015-10-29 Thread Xiao Guangrong
It's not used any more

Signed-off-by: Xiao Guangrong 
---
 include/hw/mem/pc-dimm.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index d83bf30..11a8937 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -20,8 +20,6 @@
 #include "sysemu/hostmem.h"
 #include "hw/qdev.h"
 
-#define DEFAULT_PC_DIMMSIZE (1024*1024*1024)
-
 #define TYPE_PC_DIMM "pc-dimm"
 #define PC_DIMM(obj) \
 OBJECT_CHECK(PCDIMMDevice, (obj), TYPE_PC_DIMM)
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 10/33] hostmem-file: clean up memory allocation

2015-10-29 Thread Xiao Guangrong
- hostmem-file.c is compiled only if CONFIG_LINUX is enabled so that is
  unnecessary to do the same check in the source file

- the interface, HostMemoryBackendClass->alloc(), is not called many
  times, do not need to check if the memory-region is initialized

Signed-off-by: Xiao Guangrong 
---
 backends/hostmem-file.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index e9b6d21..9097a57 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -46,17 +46,12 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 error_setg(errp, "mem-path property not set");
 return;
 }
-#ifndef CONFIG_LINUX
-error_setg(errp, "-mem-path not supported on this host");
-#else
-if (!memory_region_size(&backend->mr)) {
-backend->force_prealloc = mem_prealloc;
-memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
+
+backend->force_prealloc = mem_prealloc;
+memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
  object_get_canonical_path(OBJECT(backend)),
  backend->size, fb->share,
  fb->mem_path, errp);
-}
-#endif
 }
 
 static void
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 09/33] exec: allow file_ram_alloc to work on file

2015-10-29 Thread Xiao Guangrong
Currently, file_ram_alloc() only works on directory - it creates a file
under @path and do mmap on it

This patch tries to allow it to work on file directly, if @path is a
directory it works as before, otherwise it treats @path as the target
file then directly allocate memory from it

Signed-off-by: Xiao Guangrong 
---
 exec.c | 80 ++
 1 file changed, 51 insertions(+), 29 deletions(-)

diff --git a/exec.c b/exec.c
index 3ca7e50..f219010 100644
--- a/exec.c
+++ b/exec.c
@@ -1174,14 +1174,60 @@ void qemu_mutex_unlock_ramlist(void)
 }
 
 #ifdef __linux__
+static bool path_is_dir(const char *path)
+{
+struct stat fs;
+
+return stat(path, &fs) == 0 && S_ISDIR(fs.st_mode);
+}
+
+static int open_file_path(RAMBlock *block, const char *path, size_t size)
+{
+char *filename;
+char *sanitized_name;
+char *c;
+int fd;
+
+if (!path_is_dir(path)) {
+int flags = (block->flags & RAM_SHARED) ? O_RDWR : O_RDONLY;
+
+flags |= O_EXCL;
+return open(path, flags);
+}
+
+/* Make name safe to use with mkstemp by replacing '/' with '_'. */
+sanitized_name = g_strdup(memory_region_name(block->mr));
+for (c = sanitized_name; *c != '\0'; c++) {
+if (*c == '/') {
+*c = '_';
+}
+}
+filename = g_strdup_printf("%s/qemu_back_mem.%s.XX", path,
+   sanitized_name);
+g_free(sanitized_name);
+fd = mkstemp(filename);
+if (fd >= 0) {
+unlink(filename);
+/*
+ * ftruncate is not supported by hugetlbfs in older
+ * hosts, so don't bother bailing out on errors.
+ * If anything goes wrong with it under other filesystems,
+ * mmap will fail.
+ */
+if (ftruncate(fd, size)) {
+perror("ftruncate");
+}
+}
+g_free(filename);
+
+return fd;
+}
+
 static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
 const char *path,
 Error **errp)
 {
-char *filename;
-char *sanitized_name;
-char *c;
 void *area;
 int fd;
 uint64_t pagesize;
@@ -1211,38 +1257,14 @@ static void *file_ram_alloc(RAMBlock *block,
 goto error;
 }
 
-/* Make name safe to use with mkstemp by replacing '/' with '_'. */
-sanitized_name = g_strdup(memory_region_name(block->mr));
-for (c = sanitized_name; *c != '\0'; c++) {
-if (*c == '/')
-*c = '_';
-}
-
-filename = g_strdup_printf("%s/qemu_back_mem.%s.XX", path,
-   sanitized_name);
-g_free(sanitized_name);
+memory = ROUND_UP(memory, pagesize);
 
-fd = mkstemp(filename);
+fd = open_file_path(block, path, memory);
 if (fd < 0) {
 error_setg_errno(errp, errno,
  "unable to create backing store for path %s", path);
-g_free(filename);
 goto error;
 }
-unlink(filename);
-g_free(filename);
-
-memory = ROUND_UP(memory, pagesize);
-
-/*
- * ftruncate is not supported by hugetlbfs in older
- * hosts, so don't bother bailing out on errors.
- * If anything goes wrong with it under other filesystems,
- * mmap will fail.
- */
-if (ftruncate(fd, memory)) {
-perror("ftruncate");
-}
 
 area = qemu_ram_mmap(fd, memory, pagesize, block->flags & RAM_SHARED);
 if (area == MAP_FAILED) {
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 16/33] pc-dimm: rename pc-dimm.c and pc-dimm.h

2015-10-29 Thread Xiao Guangrong
Rename:
   pc-dimm.c => dimm.c
   pc-dimm.h => dimm.h

It prepares the work which abstracts dimm device type for both pc-dimm and
nvdimm

Signed-off-by: Xiao Guangrong 
---
 hw/Makefile.objs | 2 +-
 hw/acpi/ich9.c   | 2 +-
 hw/acpi/memory_hotplug.c | 4 ++--
 hw/acpi/piix4.c  | 2 +-
 hw/i386/pc.c | 2 +-
 hw/mem/Makefile.objs | 2 +-
 hw/mem/{pc-dimm.c => dimm.c} | 2 +-
 hw/ppc/spapr.c   | 2 +-
 include/hw/i386/pc.h | 2 +-
 include/hw/mem/{pc-dimm.h => dimm.h} | 0
 include/hw/ppc/spapr.h   | 2 +-
 numa.c   | 2 +-
 qmp.c| 2 +-
 stubs/qmp_dimm_device_list.c | 2 +-
 14 files changed, 14 insertions(+), 14 deletions(-)
 rename hw/mem/{pc-dimm.c => dimm.c} (99%)
 rename include/hw/mem/{pc-dimm.h => dimm.h} (100%)

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 7e7c241..12ecda9 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -30,8 +30,8 @@ devices-dirs-$(CONFIG_SOFTMMU) += vfio/
 devices-dirs-$(CONFIG_VIRTIO) += virtio/
 devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
 devices-dirs-$(CONFIG_SOFTMMU) += xen/
-devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
 devices-dirs-$(CONFIG_SMBIOS) += smbios/
+devices-dirs-y += mem/
 devices-dirs-y += core/
 common-obj-y += $(devices-dirs-y)
 obj-y += $(devices-dirs-y)
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index b0d6a67..1e9ae20 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -35,7 +35,7 @@
 #include "exec/address-spaces.h"
 
 #include "hw/i386/ich9.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 
 //#define DEBUG
 
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index e687852..20d3093 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -1,6 +1,6 @@
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/pc-hotplug.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 #include "hw/boards.h"
 #include "hw/qdev-core.h"
 #include "trace.h"
@@ -148,7 +148,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr 
addr, uint64_t data,
 
 dev = DEVICE(mdev->dimm);
 hotplug_ctrl = qdev_get_hotplug_handler(dev);
-/* call pc-dimm unplug cb */
+/* call dimm unplug cb */
 hotplug_handler_unplug(hotplug_ctrl, dev, &local_err);
 if (local_err) {
 trace_mhp_acpi_dimm_delete_failed(mem_st->selector);
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 0b2cb6e..b2f5b2c 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -33,7 +33,7 @@
 #include "hw/acpi/pcihp.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "hw/hotplug.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/xen/xen.h"
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 67ecc4f..6bf569a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -62,7 +62,7 @@
 #include "hw/boards.h"
 #include "hw/pci/pci_host.h"
 #include "acpi-build.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 #include "qapi/visitor.h"
 #include "qapi-visit.h"
 
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index b000fb4..7563ef5 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1 +1 @@
-common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
+common-obj-$(CONFIG_MEM_HOTPLUG) += dimm.o
diff --git a/hw/mem/pc-dimm.c b/hw/mem/dimm.c
similarity index 99%
rename from hw/mem/pc-dimm.c
rename to hw/mem/dimm.c
index 67afc53..9f55cee 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/dimm.c
@@ -18,7 +18,7 @@
  * License along with this library; if not, see 
  */
 
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 #include "qemu/config-file.h"
 #include "qapi/visitor.h"
 #include "qemu/range.h"
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ab6eb83..9ff24fd 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2199,7 +2199,7 @@ static void spapr_machine_device_plug(HotplugHandler 
*hotplug_dev,
  *
  * - Memory gets hotplugged to a different node than what the user
  *   specified.
- * - Since pc-dimm subsystem in QEMU still thinks that memory belongs
+ * - Since dimm subsystem in QEMU still thinks that memory belongs
  *   to memory-less node, a reboot will set things accordingly
  *   and the previously hotplugged memory now ends in the right node.
  *   This appears as if some memory moved from one node to another.
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 606dbc2..62e8fb5 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -16,7 +16,7 @@
 #include "hw/pci/pci.h"
 #include "hw/boards.h"
 #include "hw/compat.h"
-#include "hw/mem/pc-dimm.h"
+#include "hw/mem/dimm.h"
 
 #define HPET_INTCAP "hpet-intcap"
 
diff --git a/include/hw/mem/pc-dimm.h b

[Qemu-devel] [PATCH v6 06/33] acpi: add aml_method_serialized

2015-10-29 Thread Xiao Guangrong
It avoid explicit Mutex and will be used by NVDIMM ACPI

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 26 --
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 9f792ab..8bee8b2 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -696,14 +696,36 @@ Aml *aml_while(Aml *predicate)
 }
 
 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
-Aml *aml_method(const char *name, int arg_count)
+static Aml *__aml_method(const char *name, int arg_count, bool serialized)
 {
 Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE);
+int methodflags;
+
+/*
+ * MethodFlags:
+ *   bit 0-2: ArgCount (0-7)
+ *   bit 3: SerializeFlag
+ * 0: NotSerialized
+ * 1: Serialized
+ *   bit 4-7: reserved (must be 0)
+ */
+assert(!(arg_count & ~7));
+methodflags = arg_count | (serialized << 3);
 build_append_namestring(var->buf, "%s", name);
-build_append_byte(var->buf, arg_count); /* MethodFlags: ArgCount */
+build_append_byte(var->buf, methodflags);
 return var;
 }
 
+Aml *aml_method(const char *name, int arg_count)
+{
+return __aml_method(name, arg_count, false);
+}
+
+Aml *aml_method_serialized(const char *name, int arg_count)
+{
+return __aml_method(name, arg_count, true);
+}
+
 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */
 Aml *aml_device(const char *name_format, ...)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 5b8a118..00cf40e 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -263,6 +263,7 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
 Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
 Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
 Aml *aml_method(const char *name, int arg_count);
+Aml *aml_method_serialized(const char *name, int arg_count);
 Aml *aml_if(Aml *predicate);
 Aml *aml_else(void);
 Aml *aml_while(Aml *predicate);
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 08/33] exec: allow memory to be allocated from any kind of path

2015-10-29 Thread Xiao Guangrong
Currently file_ram_alloc() is designed for hugetlbfs, however, the memory
of nvdimm can come from either raw pmem device eg, /dev/pmem, or the file
locates at DAX enabled filesystem

So this patch let it work on any kind of path

Signed-off-by: Xiao Guangrong 
---
 exec.c | 56 +---
 1 file changed, 17 insertions(+), 39 deletions(-)

diff --git a/exec.c b/exec.c
index 8af2570..3ca7e50 100644
--- a/exec.c
+++ b/exec.c
@@ -1174,32 +1174,6 @@ void qemu_mutex_unlock_ramlist(void)
 }
 
 #ifdef __linux__
-
-#include 
-
-#define HUGETLBFS_MAGIC   0x958458f6
-
-static long gethugepagesize(const char *path, Error **errp)
-{
-struct statfs fs;
-int ret;
-
-do {
-ret = statfs(path, &fs);
-} while (ret != 0 && errno == EINTR);
-
-if (ret != 0) {
-error_setg_errno(errp, errno, "failed to get page size of file %s",
- path);
-return 0;
-}
-
-if (fs.f_type != HUGETLBFS_MAGIC)
-fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);
-
-return fs.f_bsize;
-}
-
 static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
 const char *path,
@@ -1210,20 +1184,24 @@ static void *file_ram_alloc(RAMBlock *block,
 char *c;
 void *area;
 int fd;
-uint64_t hpagesize;
-Error *local_err = NULL;
+uint64_t pagesize;
 
-hpagesize = gethugepagesize(path, &local_err);
-if (local_err) {
-error_propagate(errp, local_err);
+pagesize = qemu_file_get_page_size(path);
+if (!pagesize) {
+error_setg(errp, "can't get page size for %s", path);
 goto error;
 }
-block->mr->align = hpagesize;
 
-if (memory < hpagesize) {
+if (pagesize == getpagesize()) {
+fprintf(stderr, "Memory is not allocated from HugeTlbfs.\n");
+}
+
+block->mr->align = pagesize;
+
+if (memory < pagesize) {
 error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
-   "or larger than huge page size 0x%" PRIx64,
-   memory, hpagesize);
+   "or larger than page size 0x%" PRIx64,
+   memory, pagesize);
 goto error;
 }
 
@@ -1247,14 +1225,14 @@ static void *file_ram_alloc(RAMBlock *block,
 fd = mkstemp(filename);
 if (fd < 0) {
 error_setg_errno(errp, errno,
- "unable to create backing store for hugepages");
+ "unable to create backing store for path %s", path);
 g_free(filename);
 goto error;
 }
 unlink(filename);
 g_free(filename);
 
-memory = ROUND_UP(memory, hpagesize);
+memory = ROUND_UP(memory, pagesize);
 
 /*
  * ftruncate is not supported by hugetlbfs in older
@@ -1266,10 +1244,10 @@ static void *file_ram_alloc(RAMBlock *block,
 perror("ftruncate");
 }
 
-area = qemu_ram_mmap(fd, memory, hpagesize, block->flags & RAM_SHARED);
+area = qemu_ram_mmap(fd, memory, pagesize, block->flags & RAM_SHARED);
 if (area == MAP_FAILED) {
 error_setg_errno(errp, errno,
- "unable to map backing store for hugepages");
+ "unable to map backing store for path %s", path);
 close(fd);
 goto error;
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 05/33] acpi: add aml_object_type

2015-10-29 Thread Xiao Guangrong
Implement ObjectType which is used by NVDIMM _DSM method in
later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 8 
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index efc06ab..9f792ab 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1178,6 +1178,14 @@ Aml *aml_concatenate(Aml *source1, Aml *source2, Aml 
*target)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefObjectType */
+Aml *aml_object_type(Aml *object)
+{
+Aml *var = aml_opcode(0x8E /* ObjectTypeOp */);
+aml_append(var, object);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 325782d..5b8a118 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -278,6 +278,7 @@ Aml *aml_derefof(Aml *arg);
 Aml *aml_sizeof(Aml *arg);
 Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, const char *name);
 Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target);
+Aml *aml_object_type(Aml *object);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 04/33] acpi: add aml_concatenate

2015-10-29 Thread Xiao Guangrong
Implement Concatenate term which is used by NVDIMM _DSM method
in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 14 ++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 9fe5e7b..efc06ab 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1164,6 +1164,20 @@ Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, 
const char *name)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
+Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
+{
+Aml *var = aml_opcode(0x73 /* ConcatOp */);
+aml_append(var, source1);
+aml_append(var, source2);
+
+if (target) {
+aml_append(var, target);
+}
+
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 7e1c43b..325782d 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -277,6 +277,7 @@ Aml *aml_unicode(const char *str);
 Aml *aml_derefof(Aml *arg);
 Aml *aml_sizeof(Aml *arg);
 Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, const char *name);
+Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 11/33] hostmem-file: use whole file size if possible

2015-10-29 Thread Xiao Guangrong
Use the whole file size if @size is not specified which is useful
if we want to directly pass a file to guest

Signed-off-by: Xiao Guangrong 
---
 backends/hostmem-file.c | 48 
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 9097a57..e1bc9ff 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -9,6 +9,9 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
+#include 
+#include 
+
 #include "qemu-common.h"
 #include "sysemu/hostmem.h"
 #include "sysemu/sysemu.h"
@@ -33,20 +36,57 @@ struct HostMemoryBackendFile {
 char *mem_path;
 };
 
+static uint64_t get_file_size(const char *file)
+{
+struct stat stat_buf;
+uint64_t size = 0;
+int fd;
+
+fd = open(file, O_RDONLY);
+if (fd < 0) {
+return 0;
+}
+
+if (stat(file, &stat_buf) < 0) {
+goto exit;
+}
+
+if ((S_ISBLK(stat_buf.st_mode)) && !ioctl(fd, BLKGETSIZE64, &size)) {
+goto exit;
+}
+
+size = lseek(fd, 0, SEEK_END);
+if (size == -1) {
+size = 0;
+}
+exit:
+close(fd);
+return size;
+}
+
 static void
 file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 {
 HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
 
-if (!backend->size) {
-error_setg(errp, "can't create backend with size 0");
-return;
-}
 if (!fb->mem_path) {
 error_setg(errp, "mem-path property not set");
 return;
 }
 
+if (!backend->size) {
+/*
+ * use the whole file size if @size is not specified.
+ */
+backend->size = get_file_size(fb->mem_path);
+}
+
+if (!backend->size) {
+error_setg(errp, "failed to get file size for %s, can't create "
+ "backend on it", mem_path);
+return;
+}
+
 backend->force_prealloc = mem_prealloc;
 memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
  object_get_canonical_path(OBJECT(backend)),
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 07/33] util: introduce qemu_file_get_page_size()

2015-10-29 Thread Xiao Guangrong
There are three places use the some logic to get the page size on
the file path or file fd

This patch introduces qemu_file_get_page_size() to unify the code

Signed-off-by: Xiao Guangrong 
---
 include/qemu/osdep.h |  1 +
 target-ppc/kvm.c | 21 +++--
 util/oslib-posix.c   | 16 
 util/oslib-win32.c   |  5 +
 4 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index b568424..d4dde02 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -302,4 +302,5 @@ int qemu_read_password(char *buf, int buf_size);
  */
 pid_t qemu_fork(Error **errp);
 
+size_t qemu_file_get_page_size(const char *mem_path);
 #endif
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index ac70f08..c661f1c 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -308,28 +308,13 @@ static void kvm_get_smmu_info(PowerPCCPU *cpu, struct 
kvm_ppc_smmu_info *info)
 
 static long gethugepagesize(const char *mem_path)
 {
-struct statfs fs;
-int ret;
-
-do {
-ret = statfs(mem_path, &fs);
-} while (ret != 0 && errno == EINTR);
+long size = qemu_file_get_page_size(mem_path);
 
-if (ret != 0) {
-fprintf(stderr, "Couldn't statfs() memory path: %s\n",
-strerror(errno));
+if (!size) {
 exit(1);
 }
 
-#define HUGETLBFS_MAGIC   0x958458f6
-
-if (fs.f_type != HUGETLBFS_MAGIC) {
-/* Explicit mempath, but it's ordinary pages */
-return getpagesize();
-}
-
-/* It's hugepage, return the huge page size */
-return fs.f_bsize;
+return size;
 }
 
 static int find_max_supported_pagesize(Object *obj, void *opaque)
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 914cef5..ad94c5a 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -360,6 +360,22 @@ static size_t fd_getpagesize(int fd)
 return getpagesize();
 }
 
+size_t qemu_file_get_page_size(const char *path)
+{
+size_t size = 0;
+int fd = qemu_open(path, O_RDONLY);
+
+if (fd < 0) {
+fprintf(stderr, "Could not open %s.\n", path);
+goto exit;
+}
+
+size = fd_getpagesize(fd);
+qemu_close(fd);
+exit:
+return size;
+}
+
 void os_mem_prealloc(int fd, char *area, size_t memory)
 {
 int ret;
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 09f9e98..a18aa87 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -462,6 +462,11 @@ size_t getpagesize(void)
 return system_info.dwPageSize;
 }
 
+size_t qemu_file_get_page_size(const char *path)
+{
+return getpagesize();
+}
+
 void os_mem_prealloc(int fd, char *area, size_t memory)
 {
 int i;
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 01/33] acpi: add aml_derefof

2015-10-29 Thread Xiao Guangrong
Implement DeRefOf term which is used by NVDIMM _DSM method in later patch

Reviewed-by: Igor Mammedov 
Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 8 
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 0d4b324..cbd53f4 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1135,6 +1135,14 @@ Aml *aml_unicode(const char *str)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
+Aml *aml_derefof(Aml *arg)
+{
+Aml *var = aml_opcode(0x83 /* DerefOfOp */);
+aml_append(var, arg);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 1b632dc..5a03d33 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -274,6 +274,7 @@ Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const 
char *name);
 Aml *aml_varpackage(uint32_t num_elements);
 Aml *aml_touuid(const char *uuid);
 Aml *aml_unicode(const char *str);
+Aml *aml_derefof(Aml *arg);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 00/33] implement vNVDIMM

2015-10-29 Thread Xiao Guangrong
This patchset can be found at:
  https://github.com/xiaogr/qemu.git nvdimm-v6

It is based on pci branch on Michael's tree and the top commit is:
commit 6f96a31a06c2a1 (tests: re-enable vhost-user-test).

Changelog in v6:
- changes from Stefan's comments:
  1) fix code style of struct naming by CamelCase way
  2) fix offset + length overflow when read/write label data
  3) compile hw/acpi/nvdimm.c for per target so that TARGET_PAGE_SIZE can
 be used to replace getpagesize()

Changelog in v5:
- changes from Michael's comments:
  1) prefix nvdimm_ to everything in NVDIMM source files
  2) make parsing _DSM Arg3 more clear
  3) comment style fix
  5) drop single used definition
  6) fix dirty dsm buffer lost due to memory write happened on host
  7) check dsm buffer if it is big enough to contain input data
  8) use build_append_int_noprefix to store single value to GArray

- changes from Michael's and Igor's comments:
  1) introduce 'nvdimm-support' parameter to control nvdimm
 enablement and it is disabled for 2.4 and its earlier versions
 to make live migration compatible
  2) only reserve 1 RAM page and 4 bytes IO Port for NVDIMM ACPI
 virtualization

- changes from Stefan's comments:
  1) do endian adjustment for the buffer length

- changes from Bharata B Rao's comments:
  1) fix compile on ppc

- others:
  1) the buffer length is directly got from IO read rather than got
 from dsm memory
  2) fix dirty label data lost due to memory write happened on host

Changelog in v4:
- changes from Michael's comments:
  1) show the message, "Memory is not allocated from HugeTlbfs", if file
 based memory is not allocated from hugetlbfs.
  2) introduce function, acpi_get_nvdimm_state(), to get NVDIMMState
 from Machine.
  3) statically define UUID and make its operation more clear
  4) use GArray to build device structures to avoid potential buffer
 overflow
  4) improve comments in the code
  5) improve code style

- changes from Igor's comments:
  1) add NVDIMM ACPI spec document
  2) use serialized method to avoid Mutex
  3) move NVDIMM ACPI's code to hw/acpi/nvdimm.c
  4) introduce a common ASL method used by _DSM for all devices to reduce
 ACPI size
  5) handle UUID in ACPI AML code. BTW, i'd keep handling revision in QEMU
 it's better to upgrade QEMU to support Rev2 in the future

- changes from Stefan's comments:
  1) copy input data from DSM memory to local buffer to avoid potential
 issues as DSM memory is visible to guest. Output data is handled
 in a similar way

- changes from Dan's comments:
  1) drop static namespace as Linux has already supported label-less
 nvdimm devices

- changes from Vladimir's comments:
  1) print better message, "failed to get file size for %s, can't create
 backend on it", if any file operation filed to obtain file size

- others:
  create a git repo on github.com for better review/test

Also, thanks for Eric Blake's review on QAPI's side.

Thank all of you to review this patchset.

Changelog in v3:
There is huge change in this version, thank Igor, Stefan, Paolo, Eduardo,
Michael for their valuable comments, the patchset finally gets better shape.
- changes from Igor's comments:
  1) abstract dimm device type from pc-dimm and create nvdimm device based on
 dimm, then it uses memory backend device as nvdimm's memory and NUMA has
 easily been implemented.
  2) let file-backend device support any kind of filesystem not only for
 hugetlbfs and let it work on file not only for directory which is
 achieved by extending 'mem-path' - if it's a directory then it works as
 current behavior, otherwise if it's file then directly allocates memory
 from it.
  3) we figure out a unused memory hole below 4G that is 0xFF0 ~ 
 0xFFF0, this range is large enough for NVDIMM ACPI as build 64-bit
 ACPI SSDT/DSDT table will break windows XP.
 BTW, only make SSDT.rev = 2 can not work since the width is only depended
 on DSDT.rev based on 19.6.28 DefinitionBlock (Declare Definition Block)
 in ACPI spec:
| Note: For compatibility with ACPI versions before ACPI 2.0, the bit 
| width of Integer objects is dependent on the ComplianceRevision of the DSDT.
| If the ComplianceRevision is less than 2, all integers are restricted to 32 
| bits. Otherwise, full 64-bit integers are used. The version of the DSDT sets 
| the global integer width for all integers, including integers in SSDTs.
  4) use the lowest ACPI spec version to document AML terms.
  5) use "nvdimm" as nvdimm device name instead of "pc-nvdimm"

- changes from Stefan's comments:
  1) do not do endian adjustment in-place since _DSM memory is visible to guest
  2) use target platform's target page size instead of fixed PAGE_SIZE
 definition
  3) lots of code style improvement and typo fixes.
  4) live migration fix
- changes from Paolo's comments:
  1) improve the name of memory region
  
- other changes:
  1) return exact buffer siz

[Qemu-devel] [PATCH v6 02/33] acpi: add aml_sizeof

2015-10-29 Thread Xiao Guangrong
Implement SizeOf term which is used by NVDIMM _DSM method in later patch

Reviewed-by: Igor Mammedov 
Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 8 
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index cbd53f4..a72214d 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1143,6 +1143,14 @@ Aml *aml_derefof(Aml *arg)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSizeOf */
+Aml *aml_sizeof(Aml *arg)
+{
+Aml *var = aml_opcode(0x87 /* SizeOfOp */);
+aml_append(var, arg);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 5a03d33..7296efb 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -275,6 +275,7 @@ Aml *aml_varpackage(uint32_t num_elements);
 Aml *aml_touuid(const char *uuid);
 Aml *aml_unicode(const char *str);
 Aml *aml_derefof(Aml *arg);
+Aml *aml_sizeof(Aml *arg);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 03/33] acpi: add aml_create_field

2015-10-29 Thread Xiao Guangrong
Implement CreateField term which is used by NVDIMM _DSM method in later patch

Signed-off-by: Xiao Guangrong 
---
 hw/acpi/aml-build.c | 13 +
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 14 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index a72214d..9fe5e7b 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1151,6 +1151,19 @@ Aml *aml_sizeof(Aml *arg)
 return var;
 }
 
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
+Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, const char *name)
+{
+Aml *var = aml_alloc();
+build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
+build_append_byte(var->buf, 0x13); /* CreateFieldOp */
+aml_append(var, srcbuf);
+aml_append(var, index);
+aml_append(var, len);
+build_append_namestring(var->buf, "%s", name);
+return var;
+}
+
 void
 build_header(GArray *linker, GArray *table_data,
  AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 7296efb..7e1c43b 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -276,6 +276,7 @@ Aml *aml_touuid(const char *uuid);
 Aml *aml_unicode(const char *str);
 Aml *aml_derefof(Aml *arg);
 Aml *aml_sizeof(Aml *arg);
+Aml *aml_create_field(Aml *srcbuf, Aml *index, Aml *len, const char *name);
 
 void
 build_header(GArray *linker, GArray *table_data,
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v10 01/10] allow writing to the backing file

2015-10-29 Thread Wen Congyang
On 10/10/2015 03:07 AM, Eric Blake wrote:
> On 09/25/2015 12:17 AM, Wen Congyang wrote:
>> For block replication, we have such backing chain:
>> secondary disk <-- hidden disk <-- active disk
>> secondary disk is top BDS(use bacing reference), so it can be opened in
> 
> s/BDS(use bacing/BDS (use backing/
> 
>> read-write mode. But hidden disk is read only, and we need to write to
>> hidden disk(backup job will write data to it).
> 
> s/disk(/disk (/
> 
>>
>> TODO: support opening backing file in read-write mode if the BDS is
>> created by QMP command blockdev-add.
>>
>> Signed-off-by: Wen Congyang 
>> Signed-off-by: zhanghailiang 
>> Signed-off-by: Gonglei 
>> ---
>>  block.c | 41 -
>>  1 file changed, 40 insertions(+), 1 deletion(-)
>>
> 
> I really don't like this patch.  We are able to automatically (re-)open
> backing files for write during block-commit, without having to expose a
> knob to the user then, so exposing a knob to the user here feels wrong.

I try to reopen the backing files for write when starting block replication.
I tested it, and it doesn't work.
Here is my usage:
command line:
-drive 
if=none,id=colo-disk1,file.filename=/data/images/kvm/suse/temp.img,driver=raw
-drive 
if=virtio,id=active-disk1,driver=replication,mode=secondary,file.driver=qcow2,file.file.filename=/mnt/ramfs/active_disk.img,file.backing.driver=qcow2,file.backing.file.filename=/mnt/ramfs/hidden_disk.img,file.backing.backing.file.filename=/data/images/kvm/suse/suse11_3.img,file.backing.backing.driver=raw,file.backing.backing.node-name=sdisk

{'execute': 'blockdev-remove-medium', 'arguments': {'device': 'colo-disk1'} }
{'execute': 'blockdev-insert-medium', 'arguments': {'device': 'colo-disk1', 
'node-name': 'sdisk'} }
{'execute': 'nbd-server-start', 'arguments': {'addr': {'type': 'inet', 'data': 
{'host': '192.168.3.1', 'port': '8889'} } } }
{'execute': 'nbd-server-add', 'arguments': {'device': 'colo-disk1', 'writable': 
true } }

All qmp command success, but the disk exported to nbd server is readonly even 
if I specify 
'writable': true in the QMP commad. The reason is that the BDS is readonly.

> 
>> +#define ALLOW_WRITE_BACKING_FILE"allow-write-backing-file"
>> +static QemuOptsList backing_file_opts = {
>> +.name = "backing_file",
>> +.head = QTAILQ_HEAD_INITIALIZER(backing_file_opts.head),
>> +.desc = {
>> +{
>> +.name = ALLOW_WRITE_BACKING_FILE,
>> +.type = QEMU_OPT_BOOL,
>> +.help = "allow writes to backing file",
>> +},
> 
> And even if we DO need this knob (which I doubt), you need corresponding
> documentation of the knob in qapi/block-core.json, since we are trying
> to keep the command line and QMP in sync when it comes to adding new
> options.
> 

Yes, I know it, but I don't know how to do it. Update BlockdevOptions?

Thanks
Wen Congyang




[Qemu-devel] [PATCH v2 1/5] arm: boot: Adjust indentation of FIXUP comments

2015-10-29 Thread Peter Crosthwaite
These comments start immediately after the current longest name in the
list. Tab them out to the next tab stop to give a little breathing room
and prepare for FIXUP_BOARD_SETUP which will require more indent.

Reviewed-by: Peter Maydell 
Signed-off-by: Peter Crosthwaite 
---
Changed since v1:
s/comment/comments in commit message.

 hw/arm/boot.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index bef451b..2a151e2 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -28,14 +28,14 @@
 #define KERNEL64_LOAD_ADDR 0x0008
 
 typedef enum {
-FIXUP_NONE = 0,   /* do nothing */
-FIXUP_TERMINATOR, /* end of insns */
-FIXUP_BOARDID,/* overwrite with board ID number */
-FIXUP_ARGPTR, /* overwrite with pointer to kernel args */
-FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */
-FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
-FIXUP_BOOTREG,/* overwrite with boot register address */
-FIXUP_DSB,/* overwrite with correct DSB insn for cpu */
+FIXUP_NONE = 0, /* do nothing */
+FIXUP_TERMINATOR,   /* end of insns */
+FIXUP_BOARDID,  /* overwrite with board ID number */
+FIXUP_ARGPTR,   /* overwrite with pointer to kernel args */
+FIXUP_ENTRYPOINT,   /* overwrite with kernel entry point */
+FIXUP_GIC_CPU_IF,   /* overwrite with GIC CPU interface address */
+FIXUP_BOOTREG,  /* overwrite with boot register address */
+FIXUP_DSB,  /* overwrite with correct DSB insn for cpu */
 FIXUP_MAX,
 } FixupType;
 
-- 
1.9.1




[Qemu-devel] [PATCH v2 3/5] arm: xilinx_zynq: Add linux pre-boot

2015-10-29 Thread Peter Crosthwaite
Add a Linux-specific pre-boot routine that matches the device-
specific bootloaders behaviour. This is needed for modern Linux that
expects the ARM PLL in SLCR to be a more even value (not 26).

Cc: Alistair Francis 
Signed-off-by: Peter Crosthwaite 
---
Changed since v1:
Left main loader address unchanged
Added comments for SLCR_WRITE macro (PMM review)
Convert SLCR_WRITE impl. to use movw/movt (PMM review)
Missing "-" for device-specific
Changed since RFC:
Use bootloader callback to load blob.
Change "firmware" to "board-setup" for consistency.

 hw/arm/xilinx_zynq.c | 42 ++
 1 file changed, 42 insertions(+)

diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 9f89483..82a9db8 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -43,6 +43,45 @@ static const int dma_irqs[8] = {
 46, 47, 48, 49, 72, 73, 74, 75
 };
 
+#define BOARD_SETUP_ADDR0x100
+
+#define SLCR_LOCK_OFFSET0x004
+#define SLCR_UNLOCK_OFFSET  0x008
+#define SLCR_ARM_PLL_OFFSET 0x100
+
+#define SLCR_XILINX_UNLOCK_KEY  0xdf0d
+#define SLCR_XILINX_LOCK_KEY0x767b
+
+#define ARMV7_IMM16(x) (extract32((x),  0, 12) | \
+extract32((x), 12,  4) << 16)
+
+/* Write immediate val to address r0 + addr. r0 should contain base offset
+ * of the SLCR block. Clobbers r1.
+ */
+
+#define SLCR_WRITE(addr, val) \
+0xe3001000 + ARMV7_IMM16(extract32((val),  0, 16)), /* movw r1 ... */ \
+0xe3401000 + ARMV7_IMM16(extract32((val), 16, 16)), /* movt r1 ... */ \
+0xe5801000 + (addr)
+
+static void zynq_write_board_setup(ARMCPU *cpu,
+   const struct arm_boot_info *info)
+{
+int n;
+uint32_t board_setup_blob[] = {
+0xe3a004f8, /* mov r0, #0xf800 */
+SLCR_WRITE(SLCR_UNLOCK_OFFSET, SLCR_XILINX_UNLOCK_KEY),
+SLCR_WRITE(SLCR_ARM_PLL_OFFSET, 0x00014008),
+SLCR_WRITE(SLCR_LOCK_OFFSET, SLCR_XILINX_LOCK_KEY),
+0xe12fff1e, /* bx lr */
+};
+for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
+board_setup_blob[n] = tswap32(board_setup_blob[n]);
+}
+rom_add_blob_fixed("board-setup", board_setup_blob,
+   sizeof(board_setup_blob), BOARD_SETUP_ADDR);
+}
+
 static struct arm_boot_info zynq_binfo = {};
 
 static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
@@ -252,6 +291,9 @@ static void zynq_init(MachineState *machine)
 zynq_binfo.nb_cpus = 1;
 zynq_binfo.board_id = 0xd32;
 zynq_binfo.loader_start = 0;
+zynq_binfo.board_setup_addr = BOARD_SETUP_ADDR;
+zynq_binfo.write_board_setup = zynq_write_board_setup;
+
 arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo);
 }
 
-- 
1.9.1




[Qemu-devel] [PATCH v2 2/5] arm: boot: Add board specific setup code API

2015-10-29 Thread Peter Crosthwaite
Add an API for boards to inject their own preboot software (or
firmware) sequence.

The software then returns to the bootloader via the link register. This
allows boards to do their own little bits of firmware setup without
needed to replace the bootloader completely (which is the requirement
for existing firmware support).

The blob is loaded by a callback if and only if doing a linux boot
(similar to the existing write_secondary support).

Rewrite the comment for the primary boot blob.

Reviewed-by: Peter Maydell 
Signed-off-by: Peter Crosthwaite 
---
Changed since v1:
Rewrite boot blob comment (PMM review)
s/setup/set up/ in comment (PMM review)
s/sequeunce/sequence in commit msg
Add missing "the" in commit message
Changed since RFC:
Load blob via firmware.
Remove un-needed 0-word in bootloader sequence.
Remove "blob", just use "board setup" consistently
Remove boolean for (just use a pointer NULL check on write_board_setup)
Adjust comment about functionality of primary bootloader

 hw/arm/boot.c| 20 +++-
 include/hw/arm/arm.h | 10 ++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 2a151e2..b0879a5 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -31,6 +31,7 @@ typedef enum {
 FIXUP_NONE = 0, /* do nothing */
 FIXUP_TERMINATOR,   /* end of insns */
 FIXUP_BOARDID,  /* overwrite with board ID number */
+FIXUP_BOARD_SETUP,  /* overwrite with board specific setup code address */
 FIXUP_ARGPTR,   /* overwrite with pointer to kernel args */
 FIXUP_ENTRYPOINT,   /* overwrite with kernel entry point */
 FIXUP_GIC_CPU_IF,   /* overwrite with GIC CPU interface address */
@@ -58,8 +59,17 @@ static const ARMInsnFixup bootloader_aarch64[] = {
 { 0, FIXUP_TERMINATOR }
 };
 
-/* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
+/* A very small bootloader: call the board-setup code (if needed),
+ * set r0-r2, then jump to the kernel.
+ * If we're not calling boot setup code then we don't copy across
+ * the first BOOTLOADER_NO_BOARD_SETUP_OFFSET insns in this array.
+ */
+
 static const ARMInsnFixup bootloader[] = {
+{ 0xe28fe008 }, /* add lr, pc, #8 */
+{ 0xe51ff004 }, /* ldr pc, [pc, #-4] */
+{ 0, FIXUP_BOARD_SETUP },
+#define BOOTLOADER_NO_BOARD_SETUP_OFFSET 3
 { 0xe3a0 }, /* mov r0, #0 */
 { 0xe59f1004 }, /* ldr r1, [pc, #4] */
 { 0xe59f2004 }, /* ldr r2, [pc, #4] */
@@ -131,6 +141,7 @@ static void write_bootloader(const char *name, hwaddr addr,
 case FIXUP_NONE:
 break;
 case FIXUP_BOARDID:
+case FIXUP_BOARD_SETUP:
 case FIXUP_ARGPTR:
 case FIXUP_ENTRYPOINT:
 case FIXUP_GIC_CPU_IF:
@@ -640,6 +651,9 @@ static void arm_load_kernel_notify(Notifier *notifier, void 
*data)
 elf_machine = EM_AARCH64;
 } else {
 primary_loader = bootloader;
+if (!info->write_board_setup) {
+primary_loader += BOOTLOADER_NO_BOARD_SETUP_OFFSET;
+}
 kernel_load_offset = KERNEL_LOAD_ADDR;
 elf_machine = EM_ARM;
 }
@@ -745,6 +759,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void 
*data)
 info->initrd_size = initrd_size;
 
 fixupcontext[FIXUP_BOARDID] = info->board_id;
+fixupcontext[FIXUP_BOARD_SETUP] = info->board_setup_addr;
 
 /* for device tree boot, we pass the DTB directly in r2. Otherwise
  * we point to the kernel args.
@@ -793,6 +808,9 @@ static void arm_load_kernel_notify(Notifier *notifier, void 
*data)
 if (info->nb_cpus > 1) {
 info->write_secondary_boot(cpu, info);
 }
+if (info->write_board_setup) {
+info->write_board_setup(cpu, info);
+}
 
 /* Notify devices which need to fake up firmware initialization
  * that we're doing a direct kernel boot.
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 4dcd4f9..9217b70 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -87,6 +87,16 @@ struct arm_boot_info {
  * -pflash. It also implies that fw_cfg_find() will succeed.
  */
 bool firmware_loaded;
+
+/* Address at which board specific loader/setup code exists. If enabled,
+ * this code-blob will run before anything else. It must return to the
+ * caller via the link register. There is no stack set up. Enabled by
+ * defining write_board_setup, which is responsible for loading the blob
+ * to the specified address.
+ */
+hwaddr board_setup_addr;
+void (*write_board_setup)(ARMCPU *cpu,
+  const struct arm_boot_info *info);
 };
 
 /**
-- 
1.9.1




[Qemu-devel] [PATCH v2 5/5] arm: highbank: Implement PSCI and dummy monitor

2015-10-29 Thread Peter Crosthwaite
Firstly, enable monitor mode and PSCI, both are which are features of
this board.

In addition to PSCI, this board also uses SMC for cache maintainence
ops. This means we need a secure monitor to catch these and nop them.
Use the ARM boot board-setup feature to implement this. All traps to
monitor mode implement the nop.

Signed-off-by: Peter Crosthwaite 
---
Changed since v1:
fallthrough all of trap table to nop implementation
use movw for table address
leave loader at 0
Move MVBAR (and blob to non-zero)
Split nop implementation from MVBAR setup
set secure boot for board
implement NS switch in blob
Changed since RFC:
Use bootloader callback to load blob.
Change "firmware" to "board-setup" for consistency.
Tweak commit message.

 hw/arm/highbank.c | 66 ++-
 1 file changed, 56 insertions(+), 10 deletions(-)

diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index be04b27..f3578a3 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -32,10 +32,55 @@
 #define SMP_BOOT_REG0x40
 #define MPCORE_PERIPHBASE   0xfff1
 
+#define MVBAR_ADDR  0x200
+
 #define NIRQ_GIC160
 
 /* Board init.  */
 
+/* MVBAR_ADDR is limited by precision of movw */
+
+QEMU_BUILD_BUG_ON(MVBAR_ADDR >= (1 << 16));
+
+#define ARMV7_IMM16(x) (extract32((x),  0, 12) | \
+extract32((x), 12,  4) << 16)
+
+static void hb_write_board_setup(ARMCPU *cpu,
+ const struct arm_boot_info *info)
+{
+int n;
+uint32_t board_setup_blob[] = {
+/* MVBAR_ADDR */
+0xe320f000, /* nop */
+0xe320f000, /* nop */
+0xe320f000, /* nop */
+0xe320f000, /* nop */
+0xe320f000, /* nop */
+0xe320f000, /* nop */
+0xe320f000, /* nop */
+0xe320f000, /* nop */
+#define ERET_ADDR (MVBAR_ADDR + 8 * sizeof(uint32_t))
+0xe58fe008, /* save lr */
+0xe8dfc000, /* exception return */
+0,
+0,
+0, /* exception return link will end up here */
+#define BOARD_SETUP_ADDR (ERET_ADDR + 5 * sizeof(uint32_t))
+0xe300 + ARMV7_IMM16(MVBAR_ADDR), /* movw r0, MVBAR_ADDR */
+0xee0c0f30, /* mcr p15, 0, r0, c12, c0, 1 - set mvbar */
+0xee110f11, /* mrc p15, 0, r0, c1 , c1, 0 - get scr */
+0xe3810001, /* orr r0, #1 - set NS */
+0xee010f11, /* mcr p15, 0, r0, c1 , c1, 0 - set scr */
+0xe1600070, /* smc - go to monitor mode to flush NS change */
+0xe12fff1e, /* bx lr - return to caller */
+};
+for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
+board_setup_blob[n] = tswap32(board_setup_blob[n]);
+}
+rom_add_blob_fixed("board-setup", board_setup_blob,
+   sizeof(board_setup_blob), MVBAR_ADDR);
+}
+
 static void hb_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
 {
 int n;
@@ -248,16 +293,13 @@ static void calxeda_init(MachineState *machine, enum 
cxmachines machine_id)
 cpuobj = object_new(object_class_get_name(oc));
 cpu = ARM_CPU(cpuobj);
 
-/* By default A9 and A15 CPUs have EL3 enabled.  This board does not
- * currently support EL3 so the CPU EL3 property is disabled before
- * realization.
- */
-if (object_property_find(cpuobj, "has_el3", NULL)) {
-object_property_set_bool(cpuobj, false, "has_el3", &err);
-if (err) {
-error_report_err(err);
-exit(1);
-}
+object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_SMC,
+"psci-conduit", &error_abort);
+
+if (n) {
+/* Secondary CPUs start in PSCI powered-down state */
+object_property_set_bool(cpuobj, true,
+ "start-powered-off", &error_abort);
 }
 
 if (object_property_find(cpuobj, "reset-cbar", NULL)) {
@@ -378,6 +420,10 @@ static void calxeda_init(MachineState *machine, enum 
cxmachines machine_id)
 highbank_binfo.loader_start = 0;
 highbank_binfo.write_secondary_boot = hb_write_secondary;
 highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
+highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
+highbank_binfo.write_board_setup = hb_write_board_setup;
+highbank_binfo.secure_board_setup = true;
+
 arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
 }
 
-- 
1.9.1




[Qemu-devel] [PATCH v2 4/5] arm: boot: Add secure_board_setup flag

2015-10-29 Thread Peter Crosthwaite
Add a flag that when set, will cause the primary CPU to start in secure
mode, even if the overall boot in non-secure. This is useful for when
there is a board-setup blob that needs to run from secure mode, but
device and secondary CPU init should still be done as-normal for a non-
secure boot.

Signed-off-by: Peter Crosthwaite 
---

 hw/arm/boot.c| 3 ++-
 include/hw/arm/arm.h | 6 ++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index b0879a5..6680d45 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -495,7 +495,8 @@ static void do_cpu_reset(void *opaque)
 }
 
 /* Set to non-secure if not a secure boot */
-if (!info->secure_boot) {
+if (!info->secure_boot &&
+(cs != first_cpu || !info->secure_board_setup)) {
 /* Linux expects non-secure state */
 env->cp15.scr_el3 |= SCR_NS;
 }
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 9217b70..60dc919 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -97,6 +97,12 @@ struct arm_boot_info {
 hwaddr board_setup_addr;
 void (*write_board_setup)(ARMCPU *cpu,
   const struct arm_boot_info *info);
+
+/* If set, the board specific loader/setup blob will be run from secure
+ * mode, regardless of secure_boot. The blob becomes responsible for
+ * changing to non-secure state if implementing a non-secure boot
+ */
+bool secure_board_setup;
 };
 
 /**
-- 
1.9.1




[Qemu-devel] [PATCH v2 0/5] ARM: Machine specific boot blobs

2015-10-29 Thread Peter Crosthwaite
Hi,

This adds support for machine-specific primary boot blobs. This can be
used to install little bits of firmware or boot code without having
to throw the whole QEMU bootloader out and BYO (with device drivers
and all).

It is then used to fix two boards, Zynq and Highbank, both which have
small but critical expectations of pre-boot software setup.

Regards,
Peter

Changed since v1:
Addressed PMM review.
Added secure_board_setup flag (P4)
Added Zynq patch first, then Highbank
See indiv. patches for detailed change logs.


Peter Crosthwaite (5):
  arm: boot: Adjust indentation of FIXUP comments
  arm: boot: Add board specific setup code API
  arm: xilinx_zynq: Add linux pre-boot
  arm: boot: Add secure_board_setup flag
  arm: highbank: Implement PSCI and dummy monitor

 hw/arm/boot.c| 39 +++
 hw/arm/highbank.c| 66 
 hw/arm/xilinx_zynq.c | 42 +
 include/hw/arm/arm.h | 16 +
 4 files changed, 143 insertions(+), 20 deletions(-)

-- 
1.9.1




Re: [Qemu-devel] [RFC PATCH 0/5] Introduce Intel 82574 GbE Controller Emulation (e1000e)

2015-10-29 Thread Jason Wang


On 10/28/2015 01:44 PM, Jason Wang wrote:
>
> On 10/26/2015 01:00 AM, Leonid Bloch wrote:
>> Hello qemu-devel,
>>
>> This patch series is an RFC for the new networking device emulation
>> we're developing for QEMU.
>>
>> This new device emulates the Intel 82574 GbE Controller and works
>> with unmodified Intel e1000e drivers from the Linux/Windows kernels.
>>
>> The status of the current series is "Functional Device Ready, work
>> on Extended Features in Progress".
>>
>> More precisely, these patches represent a functional device, which
>> is recognized by the standard Intel drivers, and is able to transfer
>> TX/RX packets with CSO/TSO offloads, according to the spec.
>>
>> Extended features not supported yet (work in progress):
>>   1. TX/RX Interrupt moderation mechanisms
>>   2. RSS
>>   3. Full-featured multi-queue (use of multiqueued network backend)
>>
>> Also, there will be some code refactoring and performance
>> optimization efforts.
>>
>> This series was tested on Linux (Fedora 22) and Windows (2012R2)
>> guests, using Iperf, with TX/RX and TCP/UDP streams, and various
>> packet sizes.
>>
>> More thorough testing, including data streams with different MTU
>> sizes, and Microsoft Certification (HLK) tests, are pending missing
>> features' development.
>>
>> See commit messages (esp. "net: Introduce e1000e device emulation")
>> for more information about the development approaches and the
>> architecture options chosen for this device.
>>
>> This series is based upon v2.3.0 tag of the upstream QEMU repository,
>> and it will be rebased to latest before the final submission.
>>
>> Please share your thoughts - any feedback is highly welcomed :)
>>
>> Best Regards,
>> Dmitry Fleytman.
> Thanks for the series. Will go through this in next few days.

Have a quick glance at the series, got the following questions:

- Though e1000e differs from e1000 in many places, I still see lots of
code duplications. We need consider to reuse e1000.c (or at least part
of). I believe we don't want to fix a bug twice in two places in the
future and I expect hundreds of lines could be saved through this way.
- For e1000e it self, since it was a new device, so no need to care
about compatibility stuffs (e.g auto negotiation and mit). We can just
enable them forever.
- And for the generic packet abstraction layer, what's the advantages of
this? If it has lot, maybe we can use it in other nic model (e.g
virtio-net)?

Thanks

>
> Since 2.5 is in soft freeze, this looks a 2.6 material.
>



[Qemu-devel] [PATCH v4 2/3] aio: Introduce aio_context_setup

2015-10-29 Thread Fam Zheng
This is the place to initialize platform specific bits of AioContext.

Signed-off-by: Fam Zheng 
---
 aio-posix.c |  4 
 aio-win32.c |  4 
 async.c | 13 +++--
 include/block/aio.h |  8 
 4 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/aio-posix.c b/aio-posix.c
index 0467f23..5bff3cd 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -302,3 +302,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 
 return progress;
 }
+
+void aio_context_setup(AioContext *ctx, Error **errp)
+{
+}
diff --git a/aio-win32.c b/aio-win32.c
index 43c4c79..cdc4456 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -369,3 +369,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 aio_context_release(ctx);
 return progress;
 }
+
+void aio_context_setup(AioContext *ctx, Error **errp)
+{
+}
diff --git a/async.c b/async.c
index bdc64a3..51ff2eb 100644
--- a/async.c
+++ b/async.c
@@ -320,12 +320,18 @@ AioContext *aio_context_new(Error **errp)
 {
 int ret;
 AioContext *ctx;
+Error *local_err = NULL;
+
 ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));
+aio_context_setup(ctx, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+goto fail;
+}
 ret = event_notifier_init(&ctx->notifier, false);
 if (ret < 0) {
-g_source_destroy(&ctx->source);
 error_setg_errno(errp, -ret, "Failed to initialize event notifier");
-return NULL;
+goto fail;
 }
 g_source_set_can_recurse(&ctx->source, true);
 aio_set_event_notifier(ctx, &ctx->notifier,
@@ -340,6 +346,9 @@ AioContext *aio_context_new(Error **errp)
 ctx->notify_dummy_bh = aio_bh_new(ctx, notify_dummy_bh, NULL);
 
 return ctx;
+fail:
+g_source_destroy(&ctx->source);
+return NULL;
 }
 
 void aio_context_ref(AioContext *ctx)
diff --git a/include/block/aio.h b/include/block/aio.h
index dcf74be..2b1ff4f 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -424,4 +424,12 @@ static inline bool aio_node_check(AioContext *ctx, bool 
is_external)
 return !is_external || !atomic_read(&ctx->external_disable_cnt);
 }
 
+/**
+ * aio_context_setup:
+ * @ctx: the aio context
+ *
+ * Initialize the aio context.
+ */
+void aio_context_setup(AioContext *ctx, Error **errp);
+
 #endif
-- 
2.4.3




[Qemu-devel] [PATCH v4 3/3] aio: Introduce aio-epoll.c

2015-10-29 Thread Fam Zheng
To minimize code duplication, epoll is hooked into aio-posix's
aio_poll() instead of rolling its own. This approach also has both
compile-time and run-time switchability.

1) When QEMU starts with a small number of fds in the event loop, ppoll
is used.

2) When QEMU starts with a big number of fds, or when more devices are
hot plugged, epoll kicks in when the number of fds hits the threshold.

3) Some fds may not support epoll, such as tty based stdio. In this
case, it falls back to ppoll.

A rough benchmark with scsi-disk on virtio-scsi dataplane (epoll gets
enabled from 64 onward). Numbers are in MB/s.

===
 | master | epoll
 ||
scsi disks # | readrandrw | readrandrw
-||
1| 86  36 | 92  45
8| 87  43 | 86  41
64   | 71  32 | 70  38
128  | 48  24 | 58  31
256  | 37  19 | 57  28
===

To comply with aio_{disable,enable}_external, we always use ppoll when
aio_external_disabled() is true.

Signed-off-by: Fam Zheng 
---
 aio-posix.c | 184 +++-
 include/block/aio.h |   5 ++
 2 files changed, 188 insertions(+), 1 deletion(-)

diff --git a/aio-posix.c b/aio-posix.c
index 5bff3cd..06148a9 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -17,6 +17,9 @@
 #include "block/block.h"
 #include "qemu/queue.h"
 #include "qemu/sockets.h"
+#ifdef CONFIG_EPOLL
+#include 
+#endif
 
 struct AioHandler
 {
@@ -29,6 +32,162 @@ struct AioHandler
 QLIST_ENTRY(AioHandler) node;
 };
 
+#ifdef CONFIG_EPOLL
+
+/* The fd number threashold to switch to epoll */
+#define EPOLL_ENABLE_THRESHOLD 64
+
+static void aio_epoll_disable(AioContext *ctx)
+{
+ctx->epoll_available = false;
+if (!ctx->epoll_enabled) {
+return;
+}
+ctx->epoll_enabled = false;
+close(ctx->epollfd);
+}
+
+static inline int epoll_events_from_pfd(int pfd_events)
+{
+return (pfd_events & G_IO_IN ? EPOLLIN : 0) |
+   (pfd_events & G_IO_OUT ? EPOLLOUT : 0) |
+   (pfd_events & G_IO_HUP ? EPOLLHUP : 0) |
+   (pfd_events & G_IO_ERR ? EPOLLERR : 0);
+}
+
+static bool aio_epoll_try_enable(AioContext *ctx)
+{
+AioHandler *node;
+struct epoll_event event;
+
+QLIST_FOREACH(node, &ctx->aio_handlers, node) {
+int r;
+if (node->deleted || !node->pfd.events) {
+continue;
+}
+event.events = epoll_events_from_pfd(node->pfd.events);
+event.data.ptr = node;
+r = epoll_ctl(ctx->epollfd, EPOLL_CTL_ADD, node->pfd.fd, &event);
+if (r) {
+return false;
+}
+}
+ctx->epoll_enabled = true;
+return true;
+}
+
+static void aio_epoll_update(AioContext *ctx, AioHandler *node, bool is_new)
+{
+struct epoll_event event;
+int r;
+
+if (!ctx->epoll_enabled) {
+return;
+}
+if (!node->pfd.events) {
+r = epoll_ctl(ctx->epollfd, EPOLL_CTL_DEL, node->pfd.fd, &event);
+if (r) {
+aio_epoll_disable(ctx);
+}
+} else {
+event.data.ptr = node;
+event.events = epoll_events_from_pfd(node->pfd.events);
+if (is_new) {
+r = epoll_ctl(ctx->epollfd, EPOLL_CTL_ADD, node->pfd.fd, &event);
+if (r) {
+aio_epoll_disable(ctx);
+}
+} else {
+r = epoll_ctl(ctx->epollfd, EPOLL_CTL_MOD, node->pfd.fd, &event);
+if (r) {
+aio_epoll_disable(ctx);
+}
+}
+}
+}
+
+static int aio_epoll(AioContext *ctx, GPollFD *pfds,
+ unsigned npfd, int64_t timeout)
+{
+AioHandler *node;
+int i, ret = 0;
+struct epoll_event events[128];
+
+assert(npfd == 1);
+assert(pfds[0].fd == ctx->epollfd);
+if (timeout > 0) {
+ret = qemu_poll_ns(pfds, npfd, timeout);
+}
+if (timeout <= 0 || ret > 0) {
+ret = epoll_wait(ctx->epollfd, events,
+ sizeof(events) / sizeof(events[0]),
+ timeout);
+if (ret <= 0) {
+goto out;
+}
+for (i = 0; i < ret; i++) {
+int ev = events[i].events;
+node = events[i].data.ptr;
+node->pfd.revents = (ev & EPOLLIN ? G_IO_IN : 0) |
+(ev & EPOLLOUT ? G_IO_OUT : 0) |
+(ev & EPOLLHUP ? G_IO_HUP : 0) |
+(ev & EPOLLERR ? G_IO_ERR : 0);
+}
+}
+out:
+return ret;
+}
+
+static bool aio_epoll_enabled(AioContext *ctx)
+{
+/* Fall back to ppoll when external clients are disabled. */
+return !aio_external_disabled(ctx) && ctx->epoll_enabled;
+}
+
+static bool aio_epoll_check_poll(AioContext *ctx, GPollFD *pfds,
+ unsigned npfd, int64_t timeout)
+{

[Qemu-devel] [PATCH v4 1/3] aio: Introduce aio_external_disabled

2015-10-29 Thread Fam Zheng
This allows AioContext users to check the enable/disable state of
external clients.

Signed-off-by: Fam Zheng 
---
 include/block/aio.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/block/aio.h b/include/block/aio.h
index bcc7d43..dcf74be 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -401,6 +401,17 @@ static inline void aio_enable_external(AioContext *ctx)
 }
 
 /**
+ * aio_external_disabled:
+ * @ctx: the aio context
+ *
+ * Return true if the external clients are disabled.
+ */
+static inline bool aio_external_disabled(AioContext *ctx)
+{
+return atomic_read(&ctx->external_disable_cnt);
+}
+
+/**
  * aio_node_check:
  * @ctx: the aio context
  * @is_external: Whether or not the checked node is an external event source.
-- 
2.4.3




[Qemu-devel] [PATCH v4 0/3] aio: Use epoll in aio_poll()

2015-10-29 Thread Fam Zheng
v4: Rebase onto master (with aio_disable_external):
Don't use epoll if aio_external_disabled(ctx);
Change assert on epoll_ctl return code to disable epoll;
Rerun benchmark;

v3: Remove the redundant check in aio_epoll_try_enable. [Stefan]

v2: Merge aio-epoll.c into aio-posix.c. [Paolo]
Capture some benchmark data in commit log.

This series adds the ability to use epoll in aio_poll() on Linux. It's switched
on in a dynamic way rather than static for two reasons: 1) when the number of
fds is not high enough, using epoll has little advantage; 2) when an epoll
incompatible fd needs to be handled, we need to fall back.  The epoll is
enabled when a fd number threshold is met.


Fam Zheng (3):
  aio: Introduce aio_external_disabled
  aio: Introduce aio_context_setup
  aio: Introduce aio-epoll.c

 aio-posix.c | 188 +++-
 aio-win32.c |   4 ++
 async.c |  13 +++-
 include/block/aio.h |  24 +++
 4 files changed, 226 insertions(+), 3 deletions(-)

-- 
2.4.3




Re: [Qemu-devel] [PATCH v3 2/6] e1000: Trivial implementation of various MAC registers

2015-10-29 Thread Jason Wang


On 10/29/2015 06:27 PM, Leonid Bloch wrote:
> On Thu, Oct 29, 2015 at 12:01 PM, Jason Wang  wrote:
>>
>> On 10/29/2015 05:33 PM, Leonid Bloch wrote:
>>> On Thu, Oct 29, 2015 at 5:04 AM, Jason Wang  wrote:
 On 10/28/2015 11:31 PM, Leonid Bloch wrote:
> These registers appear in Intel's specs, but were not implemented.
> These registers are now implemented trivially, i.e. they are initiated
> with zero values, and if they are RW, they can be written or read by the
> driver, or read only if they are R (essentially retaining their zero
> values). For these registers no other procedures are performed.
>
> For the trivially implemented Diagnostic registers, a debug warning is
> produced on read/write attempts.
>
> The registers implemented here are:
>
> Transmit:
> RW: AIT
>
> Management:
> RW: WUC WUS IPAVIP6AT*  IP4AT*  FFLT*   WUPM*   FFMT*   FFVT*
>
> Diagnostic:
> RW: RDFHRDFTRDFHS   RDFTS   RDFPC   PBM*TDFHTDFTTDFHS
> TDFTS   TDFPC
>
> Statistic:
> RW: FCRUC
> R:  RNBCTSCTFC  MGTPRC  MGTPDC  MGTPTC  RFC RJC SCC ECOL
> LATECOL MCC COLCDC  TNCRS   SEC CEXTERR RLECXONRXC
> XONTXC  XOFFRXC XOFFTXC
>
> Signed-off-by: Leonid Bloch 
> Signed-off-by: Dmitry Fleytman 
> ---
>  hw/net/e1000.c  | 154 
> +++-
>  hw/net/e1000_regs.h |   6 ++
>  2 files changed, 157 insertions(+), 3 deletions(-)
>> [...]
>>
> +static bool e1000_extra_trivial_regs_needed(void *opaque)
> +{
> +return true;
> +}
 This reminds me  that we need care the migration compatibility to older
 version here. Probably we need another property for e1000, and only
 migrate and implement the new mac registers for version >= 2.5. An
 example is mit implementation. (see
 e9845f0985f088dd01790f4821026df0afba5795). And need to do the same for
 patch 6.

> +
> +static const VMStateDescription vmstate_e1000_extra_trivial_regs = {
> +.name = "e1000/extra_trivial_regs",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.needed = e1000_extra_trivial_regs_needed,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINT32(mac_reg[AIT], E1000State),
> +VMSTATE_UINT32(mac_reg[SCC], E1000State),
> +VMSTATE_UINT32(mac_reg[ECOL], E1000State),
> +VMSTATE_UINT32(mac_reg[MCC], E1000State),
> +VMSTATE_UINT32(mac_reg[LATECOL], E1000State),
> +VMSTATE_UINT32(mac_reg[COLC], E1000State),
> +VMSTATE_UINT32(mac_reg[DC], E1000State),
> +VMSTATE_UINT32(mac_reg[TNCRS], E1000State),
> +VMSTATE_UINT32(mac_reg[SEC], E1000State),
> +VMSTATE_UINT32(mac_reg[CEXTERR], E1000State),
> +VMSTATE_UINT32(mac_reg[RLEC], E1000State),
> +VMSTATE_UINT32(mac_reg[XONRXC], E1000State),
> +VMSTATE_UINT32(mac_reg[XONTXC], E1000State),
> +VMSTATE_UINT32(mac_reg[XOFFRXC], E1000State),
> +VMSTATE_UINT32(mac_reg[XOFFTXC], E1000State),
> +VMSTATE_UINT32(mac_reg[FCRUC], E1000State),
> +VMSTATE_UINT32(mac_reg[RNBC], E1000State),
> +VMSTATE_UINT32(mac_reg[RFC], E1000State),
> +VMSTATE_UINT32(mac_reg[RJC], E1000State),
> +VMSTATE_UINT32(mac_reg[MGTPRC], E1000State),
> +VMSTATE_UINT32(mac_reg[MGTPDC], E1000State),
> +VMSTATE_UINT32(mac_reg[MGTPTC], E1000State),
> +VMSTATE_UINT32(mac_reg[TSCTFC], E1000State),
> +VMSTATE_UINT32(mac_reg[WUC], E1000State),
> +VMSTATE_UINT32(mac_reg[WUS], E1000State),
> +VMSTATE_UINT32(mac_reg[IPAV], E1000State),
> +VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, IP4AT, 7),
> +VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, IP6AT, 4),
> +VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, WUPM, 32),
> +VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, FFLT, 7),
> +VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, FFMT, 255),
> +VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, FFVT, 255),
> +VMSTATE_UINT32(mac_reg[RDFH], E1000State),
> +VMSTATE_UINT32(mac_reg[RDFT], E1000State),
> +VMSTATE_UINT32(mac_reg[RDFHS], E1000State),
> +VMSTATE_UINT32(mac_reg[RDFTS], E1000State),
> +VMSTATE_UINT32(mac_reg[RDFPC], E1000State),
> +VMSTATE_UINT32(mac_reg[TDFH], E1000State),
> +VMSTATE_UINT32(mac_reg[TDFT], E1000State),
> +VMSTATE_UINT32(mac_reg[TDFHS], E1000State),
> +VMSTATE_UINT32(mac_reg[TDFTS], E1000State),
> +VMSTATE_UINT32(mac_reg[TDFPC], E1000State),
> +VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, PBM, 16384),
> +VMSTATE_END_OF_LIST()
>>

Re: [Qemu-devel] [RFC Patch 00/12] IXGBE: Add live migration support for SRIOV NIC

2015-10-29 Thread Lan Tianyu
On 2015年10月30日 00:17, Alexander Duyck wrote:
> On 10/29/2015 01:33 AM, Lan Tianyu wrote:
>> On 2015年10月29日 14:58, Alexander Duyck wrote:
>>> Your code was having to do a bunch of shuffling in order to get things
>>> set up so that you could bring the interface back up.  I would argue
>>> that it may actually be faster at least on the bring-up to just drop the
>>> old rings and start over since it greatly reduced the complexity and the
>>> amount of device related data that has to be moved.
>> If give up the old ring after migration and keep DMA running before
>> stopping VCPU, it seems we don't need to track Tx/Rx descriptor ring and
>> just make sure that all Rx buffers delivered to stack has been migrated.
>>
>> 1) Dummy write Rx buffer before checking Rx descriptor to ensure packet
>> migrated first.
> 
> Don't dummy write the Rx descriptor.  You should only really need to
> dummy write the Rx buffer and you would do so after checking the
> descriptor, not before.  Otherwise you risk corrupting the Rx buffer
> because it is possible for you to read the Rx buffer, DMA occurs, and
> then you write back the Rx buffer and now you have corrupted the memory.
> 
>> 2) Make a copy of Rx descriptor and then use the copied data to check
>> buffer status. Not use the original descriptor because it won't be
>> migrated and migration may happen between two access of the Rx
>> descriptor.
> 
> Do not just blindly copy the Rx descriptor ring.  That is a recipe for
> disaster.  The problem is DMA has to happen in a very specific order for
> things to function correctly.  The Rx buffer has to be written and then
> the Rx descriptor.  The problem is you will end up getting a read-ahead
> on the Rx descriptor ring regardless of which order you dirty things in.


Sorry, I didn't say clearly.
I meant to copy one Rx descriptor when receive rx irq and handle Rx ring.

Current code in the ixgbevf_clean_rx_irq() checks status of the Rx
descriptor whether its Rx buffer has been populated data and then read
the packet length from Rx descriptor to handle the Rx buffer.

My idea is to do the following three steps when receive Rx buffer in the
ixgbevf_clean_rx_irq().

(1) dummy write the Rx buffer first,
(2) make a copy of its Rx descriptor
(3) Check the buffer status and get length from the copy.

Migration may happen every time.
Happen between (1) and (2). If the Rx buffer has been populated data, VF
driver will not know that on the new machine because the Rx descriptor
isn't migrated. But it's still safe.

Happen between (2) and (3). The copy will be migrated to new machine
and Rx buffer is migrated firstly. If there is data in the Rx buffer,
VF driver still can handle the buffer without migrating Rx descriptor.

The next buffers will be ignored since we don't migrate Rx descriptor
for them. Their status will be not completed on the new machine.

-- 
Best regards
Tianyu Lan



[Qemu-devel] [Bug 1368815] Re: qemu-img convert intermittently corrupts output images

2015-10-29 Thread Eric Harney
Closing based on the assumption that a working qemu-img is available
now.

** Changed in: cinder
   Status: Triaged => Won't Fix

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1368815

Title:
  qemu-img convert intermittently corrupts output images

Status in Cinder:
  Won't Fix
Status in OpenStack Compute (nova):
  Won't Fix
Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Trusty:
  Fix Released
Status in qemu source package in Utopic:
  Fix Released
Status in qemu source package in Vivid:
  Fix Released

Bug description:
  ==
  Impact: occasional image corruption (any format on local filesystem)
  Test case: see the qemu-img command below
  Regression potential: this cherrypicks a patch from upstream to a 
not-insignificantly older qemu source tree.  While the cherrypick seems sane, 
it's possible that there are subtle interactions with the other delta.  I'd 
really like for a full qa-regression-test qemu testcase to be run against this 
package.
  ==

  -- Found in releases qemu-2.0.0, qemu-2.0.2, qemu-2.1.0. Tested on
  Ubuntu 14.04 using Ext4 filesystems.

  The command

    qemu-img convert -O raw inputimage.qcow2 outputimage.raw

  intermittently creates corrupted output images, when the input image
  is not yet fully synchronized to disk. While the issue has actually
  been discovered in operation of of OpenStack nova, it can be
  reproduced "easily" on command line using

    cat $SRC_PATH > $TMP_PATH && $QEMU_IMG_PATH convert -O raw $TMP_PATH
  $DST_PATH && cksum $DST_PATH

  on filesystems exposing this behavior. (The difficult part of this
  exercise is to prepare a filesystem to reliably trigger this race. On
  my test machine some filesystems are affected while other aren't, and
  unfortunately I haven't found the relevant difference between them,
  yet. Possible it's timing issues completely out of userspace control
  ...)

  The root cause, however, is the same as in

    http://lists.gnu.org/archive/html/coreutils/2011-04/msg00069.html

  and it can be solved the same way as suggested in

    http://lists.gnu.org/archive/html/coreutils/2011-04/msg00102.html

  In qemu, file block/raw-posix.c use the FIEMAP_FLAG_SYNC, i.e change

  f.fm.fm_flags = 0;

  to

  f.fm.fm_flags = FIEMAP_FLAG_SYNC;

  As discussed in the thread mentioned above, retrieving a page cache
  coherent map of file extents is possible only after fsync on that
  file.

  See also

    https://bugs.launchpad.net/nova/+bug/1350766

  In that bug report filed against nova, fsync had been suggested to be
  performed by the framework invoking qemu-img. However, as the choice
  of fiemap -- implying this otherwise unneeded fsync of a temporary
  file  -- is not made by the caller but by qemu-img, I agree with the
  nova bug reviewer's objection to put it into nova. The fsync should
  instead be triggered by qemu-img utilizing the FIEMAP_FLAG_SYNC,
  specifically intended for that purpose.

To manage notifications about this bug go to:
https://bugs.launchpad.net/cinder/+bug/1368815/+subscriptions



Re: [Qemu-devel] [PATCH v2 0/8] Add system_powerdown support on ARM for ACPI and DT

2015-10-29 Thread Shannon Zhao


On 2015/10/30 2:17, Wei Huang wrote:
> On 10/29/2015 09:27 AM, Shannon Zhao wrote:
>> ACPI SPEC 5.0 defines GPIO-signaled ACPI Events for Hardware-reduced
>> platforms(like ARM). It uses GPIO pin to trigger an event to the guest.
>> For QEMU, here we add PL061 GPIO controller and use PIN 3 for
>> system_powerdown, reserving PIN 0, 1, 2 for PCI hotplug, CPU hotplug and
>> memory hotplug.
>>
>> This patchset adds system_powerdown support on ARM through both ACPI and
>> DT ways. It adds a GPIO controller(here is PL061) in machine virt and
>> uses GPIO-singled event for ACPI while gpio-keys for DT. It can be
>> fetched from [1] and has been tested for the guests starting by ACPI or
>> DT while guests use systemd or acpid.
>>
>> a) ACPI way. Since Graeme send a patchset to make ACPI on ARM64 support
>> amba device[2], it could use PL061 directly without modification to its
>> kernel driver code. In addition, we should use ACPI to start VM,
>> referring to below script. QEMU_EFI.fd can be fetched from [3]. 
> 
> Hi Shannon,
> 
> Thanks for re-sending it. This is a desired feature because we don't
> want to rely on tricks (such as guest-agent) for external VM power
> management. I have tested V1 recently by back-porting to my in-house
> kernel; it worked well.
> 
> I will help review this new version.
> 
Thanks for your help:)

-- 
Shannon



Re: [Qemu-devel] [PATCH for-2.5 v2 2/4] mips: add Global Config Register block (part)

2015-10-29 Thread James Hogan
Hi Yongbok,

On Tue, Oct 27, 2015 at 05:12:35PM +, Yongbok Kim wrote:
> Add part of GCR Block which Linux Kernel utilises and it is enough
> to bring the GIC up.
> It defines full 32 Kbytes address space allocated for GCR but only few
> registers are implemented such as config, revision, status, L2 config and
> local config registers.
> To support MIPS Coherent Manager, this module would be necessary to be 
> extended

s/Coherent/Coherence/

> further.
> 
> Signed-off-by: Yongbok Kim 
> ---
>  default-configs/mips-softmmu.mak |1 +
>  default-configs/mips64-softmmu.mak   |1 +
>  default-configs/mips64el-softmmu.mak |1 +
>  default-configs/mipsel-softmmu.mak   |1 +
>  hw/misc/Makefile.objs|1 +
>  hw/misc/mips_gcr.c   |  113 
> ++
>  include/hw/misc/mips_gcr.h   |   58 +

would these be better named mips_cmgcr.{h,c}?

>  7 files changed, 176 insertions(+), 0 deletions(-)
>  create mode 100644 hw/misc/mips_gcr.c
>  create mode 100644 include/hw/misc/mips_gcr.h
> 
> diff --git a/default-configs/mips-softmmu.mak 
> b/default-configs/mips-softmmu.mak
> index 44467c3..a784644 100644
> --- a/default-configs/mips-softmmu.mak
> +++ b/default-configs/mips-softmmu.mak
> @@ -30,3 +30,4 @@ CONFIG_I8259=y
>  CONFIG_MC146818RTC=y
>  CONFIG_ISA_TESTDEV=y
>  CONFIG_EMPTY_SLOT=y
> +CONFIG_MIPS_GIC=y
> diff --git a/default-configs/mips64-softmmu.mak 
> b/default-configs/mips64-softmmu.mak
> index 66ed5f9..957508d 100644
> --- a/default-configs/mips64-softmmu.mak
> +++ b/default-configs/mips64-softmmu.mak
> @@ -36,3 +36,4 @@ CONFIG_JAZZ_LED=y
>  CONFIG_MC146818RTC=y
>  CONFIG_ISA_TESTDEV=y
>  CONFIG_EMPTY_SLOT=y
> +CONFIG_MIPS_GIC=y
> diff --git a/default-configs/mips64el-softmmu.mak 
> b/default-configs/mips64el-softmmu.mak
> index bfca2b2..6c1065f 100644
> --- a/default-configs/mips64el-softmmu.mak
> +++ b/default-configs/mips64el-softmmu.mak
> @@ -39,3 +39,4 @@ CONFIG_MC146818RTC=y
>  CONFIG_VT82C686=y
>  CONFIG_ISA_TESTDEV=y
>  CONFIG_EMPTY_SLOT=y
> +CONFIG_MIPS_GIC=y
> diff --git a/default-configs/mipsel-softmmu.mak 
> b/default-configs/mipsel-softmmu.mak
> index 0162ef0..4633b0b 100644
> --- a/default-configs/mipsel-softmmu.mak
> +++ b/default-configs/mipsel-softmmu.mak
> @@ -30,3 +30,4 @@ CONFIG_I8259=y
>  CONFIG_MC146818RTC=y
>  CONFIG_ISA_TESTDEV=y
>  CONFIG_EMPTY_SLOT=y
> +CONFIG_MIPS_GIC=y
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index 4aa76ff..02ac5bb 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -37,6 +37,7 @@ obj-$(CONFIG_OMAP) += omap_tap.o
>  obj-$(CONFIG_SLAVIO) += slavio_misc.o
>  obj-$(CONFIG_ZYNQ) += zynq_slcr.o
>  obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
> +obj-$(CONFIG_MIPS_GIC) += mips_gcr.o

would CONFIG_MIPS_CMGCR be a better name?

>  
>  obj-$(CONFIG_PVPANIC) += pvpanic.o
>  obj-$(CONFIG_EDU) += edu.o
> diff --git a/hw/misc/mips_gcr.c b/hw/misc/mips_gcr.c
> new file mode 100644
> index 000..6db4a9d
> --- /dev/null
> +++ b/hw/misc/mips_gcr.c
> @@ -0,0 +1,113 @@
> +/*
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License.  See the file "COPYING" in the main directory of this archive
> + * for more details.
> + *
> + * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
> + * Authors: Sanjay Lal 
> + *
> + * Copyright (C) 2015 Imagination Technologies
> + */
> +
> +#include "hw/hw.h"
> +#include "hw/sysbus.h"
> +#include "sysemu/sysemu.h"
> +#include "hw/misc/mips_gcr.h"
> +#include "hw/intc/mips_gic.h"

I don't think this header exists yet at this point in the patchset.

> +
> +/* Read GCR registers */
> +static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +MIPSGCRState *gcr = (MIPSGCRState *) opaque;
> +
> +switch (addr) {
> +/* Global Control Block Register */
> +case GCR_CONFIG_OFS:
> +/* Set PCORES to 0 */
> +return 0;
> +case GCR_BASE_OFS:
> +return gcr->gcr_base;
> +case GCR_REV_OFS:
> +return gcr->gcr_rev;
> +case GCR_GIC_BASE_OFS:
> +return gcr->gic_base;
> +case GCR_GIC_STATUS_OFS:
> +return GCR_GIC_STATUS_GICEX_MSK;

well, it doesn't exist yet, does it?

> +case GCR_CPC_STATUS_OFS:
> +return 0;
> +case GCR_L2_CONFIG_OFS:
> +/* L2 BYPASS */
> +return GCR_L2_CONFIG_BYPASS_MSK;
> +/* Core-Local and Core-Other Control Blocks */
> +case MIPS_CLCB_OFS + GCR_CL_CONFIG_OFS:
> +case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS:
> +/* Set PVP to # cores - 1 */
> +return gcr->num_vps - 1;
> +case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
> +return 0;
> +default:
> +qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" PRIx64 
> "\n",
> +  size, addr);
> +return 0;
> +}
> +return 0;
> +}
> +
> +/* Write GCR registers */
> +static void gcr_write(void *opaque, hwaddr a

Re: [Qemu-devel] [PATCH for-2.5] MAINTAINERS: Add new qemu-arm mailing list to ARM related entries

2015-10-29 Thread Alistair Francis
On Thu, Oct 29, 2015 at 7:41 AM, Peter Maydell  wrote:
> We now have a qemu-arm mailing list for ARM patches and discussion,
> so add an L: entry for it to the various ARM related entries in
> MAINTAINERS.
>
> Signed-off-by: Peter Maydell 

Looks fine to me

Reviewed-by: Alistair Francis 

Thanks,

Alistair

> ---
> I basically just added an L: entry for everything that was vaguely
> ARM-ish...it's a shame the MAINTAINERS format doesn't let you say
> "and cc this list for any of the sub-entries under this subsection".
>
>  MAINTAINERS | 23 +++
>  1 file changed, 23 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3144113..fc8abe8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -81,6 +81,7 @@ F: disas/alpha.c
>
>  ARM
>  M: Peter Maydell 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: target-arm/
>  F: hw/arm/
> @@ -216,6 +217,7 @@ F: */kvm.*
>
>  ARM
>  M: Peter Maydell 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: target-arm/kvm.c
>
> @@ -287,6 +289,7 @@ ARM Machines
>  
>  Allwinner-a10
>  M: Beniamino Galvani 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/*/allwinner*
>  F: include/hw/*/allwinner*
> @@ -294,6 +297,7 @@ F: hw/arm/cubieboard.c
>
>  ARM PrimeCell
>  M: Peter Maydell 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/char/pl011.c
>  F: hw/display/pl110*
> @@ -308,6 +312,7 @@ F: include/hw/arm/primecell.h
>
>  ARM cores
>  M: Peter Maydell 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/intc/arm*
>  F: hw/intc/gic_internal.h
> @@ -327,54 +332,64 @@ M: Evgeny Voevodin 
>  M: Maksim Kozlov 
>  M: Igor Mitsyanko 
>  M: Dmitry Solodkiy 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/*/exynos*
>
>  Calxeda Highbank
>  M: Rob Herring 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/highbank.c
>  F: hw/net/xgmac.c
>
>  Canon DIGIC
>  M: Antony Pavlov 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: include/hw/arm/digic.h
>  F: hw/*/digic*
>
>  Gumstix
>  L: qemu-devel@nongnu.org
> +L: qemu-...@nongnu.org
>  S: Orphan
>  F: hw/arm/gumstix.c
>
>  i.MX31
>  M: Peter Chubb 
> +L: qemu-...@nongnu.org
>  S: Odd fixes
>  F: hw/*/imx*
>  F: hw/arm/kzm.c
>
>  Integrator CP
>  M: Peter Maydell 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/integratorcp.c
>
>  Musicpal
>  M: Jan Kiszka 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/musicpal.c
>
>  nSeries
>  M: Andrzej Zaborowski 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/nseries.c
>
>  Palm
>  M: Andrzej Zaborowski 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/palm.c
>
>  Real View
>  M: Peter Maydell 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/realview*
>  F: hw/intc/realview_gic.c
> @@ -382,6 +397,7 @@ F: include/hw/intc/realview_gic.h
>
>  PXA2XX
>  M: Andrzej Zaborowski 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/mainstone.c
>  F: hw/arm/spitz.c
> @@ -391,17 +407,20 @@ F: hw/*/pxa2xx*
>
>  Stellaris
>  M: Peter Maydell 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/*/stellaris*
>
>  Versatile PB
>  M: Peter Maydell 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/*/versatile*
>
>  Xilinx Zynq
>  M: Alistair Francis 
>  M: Peter Crosthwaite 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/xilinx_zynq.c
>  F: hw/misc/zynq_slcr.c
> @@ -411,6 +430,7 @@ F: hw/ssi/xilinx_spips.c
>  Xilinx ZynqMP
>  M: Alistair Francis 
>  M: Peter Crosthwaite 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/xlnx-zynqmp.c
>  F: hw/arm/xlnx-ep108.c
> @@ -419,6 +439,7 @@ F: include/hw/arm/xlnx-zynqmp.h
>  ARM ACPI Subsystem
>  M: Shannon Zhao 
>  M: Shannon Zhao 
> +L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/virt-acpi-build.c
>  F: include/hw/arm/virt-acpi-build.h
> @@ -1235,6 +1256,7 @@ AArch64 target
>  M: Claudio Fontana 
>  M: Claudio Fontana 
>  S: Maintained
> +L: qemu-...@nongnu.org
>  F: tcg/aarch64/
>  F: disas/arm-a64.cc
>  F: disas/libvixl/
> @@ -1242,6 +1264,7 @@ F: disas/libvixl/
>  ARM target
>  M: Andrzej Zaborowski 
>  S: Maintained
> +L: qemu-...@nongnu.org
>  F: tcg/arm/
>  F: disas/arm.c
>
> --
> 1.9.1
>
>



Re: [Qemu-devel] [PATCH for-2.5 v2 1/4] target-mips: add CMGCRBase register

2015-10-29 Thread James Hogan
On Tue, Oct 27, 2015 at 05:12:34PM +, Yongbok Kim wrote:
> Physical base address for the memory-mapped Coherency Manager Global
> Configuration Register space.
> The MIPS default location for the GCR_BASE address is 0x1FBF_8.
> This register only exists if Config3 CMGCR is set to one.
> 
> Signed-off-by: Yongbok Kim 
> ---
>  target-mips/cpu.h|3 ++-
>  target-mips/translate.c  |   18 ++
>  target-mips/translate_init.c |3 ++-
>  3 files changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index c68681d..fdec7b7 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -389,6 +389,7 @@ struct CPUMIPSState {
>  target_ulong CP0_EPC;
>  int32_t CP0_PRid;
>  int32_t CP0_EBase;
> +target_ulong CP0_CMGCRBase;
>  int32_t CP0_Config0;
>  #define CP0C0_M31
>  #define CP0C0_K23  28
> @@ -431,7 +432,7 @@ struct CPUMIPSState {
>  int32_t CP0_Config3;
>  #define CP0C3_M31
>  #define CP0C3_BPG  30
> -#define CP0C3_CMCGR 29
> +#define CP0C3_CMGCR 29
>  #define CP0C3_MSAP  28
>  #define CP0C3_BP 27
>  #define CP0C3_BI 26
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 4cb77de..2f219fa 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -1426,6 +1426,7 @@ typedef struct DisasContext {
>  bool mvh;
>  int CP0_LLAddr_shift;
>  bool ps;
> +bool cmgcr;
>  } DisasContext;
>  
>  enum {
> @@ -5273,6 +5274,13 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>  gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
>  rn = "EBase";
>  break;
> +case 3:
> +check_insn(ctx, ISA_MIPS32R2);
> +CP0_CHECK(ctx->cmgcr);
> +tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, 
> CP0_CMGCRBase));
> +tcg_gen_ext32s_tl(arg, arg);
> +rn = "CMGCRBase";
> +break;
>  default:
>  goto cp0_unimplemented;
> }
> @@ -6527,6 +6535,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int 
> reg, int sel)
>  gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
>  rn = "EBase";
>  break;
> +case 3:
> +check_insn(ctx, ISA_MIPS32R2);
> +CP0_CHECK(ctx->cmgcr);
> +tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, 
> CP0_CMGCRBase));
> +rn = "CMGCRBase";
> +break;
>  default:
>  goto cp0_unimplemented;
>  }
> @@ -19568,6 +19582,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct 
> TranslationBlock *tb)
>  ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
>  ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
>   (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
> +ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
>  restore_cpu_state(env, &ctx);
>  #ifdef CONFIG_USER_ONLY
>  ctx.mem_idx = MIPS_HFLAG_UM;
> @@ -19956,6 +19971,9 @@ void cpu_state_reset(CPUMIPSState *env)
>  } else {
>  env->CP0_EBase |= 0x8000;
>  }
> +if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
> +env->CP0_CMGCRBase = 0x1fbf8000 >> 4;

This is technically hardware configurable, but I'm guessing we can worry
about emulation of platforms that set it to something different later.

> +}
>  env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
>  /* vectored interrupts not implemented, timer on int 7,
> no performance counters. */
> diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
> index 1b45884..a6b8986 100644
> --- a/target-mips/translate_init.c
> +++ b/target-mips/translate_init.c
> @@ -660,7 +660,8 @@ static const mips_def_t mips_defs[] =
> (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
> (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
>  .CP0_Config2 = MIPS_CONFIG2,
> -.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) |
> +.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) |
> +   (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) |

You're enabling the bit to tell the guest that the CMGCRs are present,
but they're not yet, only the cop0 registers. Perhaps this hunk of the
patch should come after those memory mapped registers are implemented,
so as not to break bisection.

Otherwise:
Reviewed-by: James Hogan 

Cheers
James

> (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) 
> |
> (1 << CP0C3_RXI) | (1 << CP0C3_LPA),
>  .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) |
> -- 
> 1.7.1
> 


signature.asc
Description: Digital signature


Re: [Qemu-devel] [PATCH v4] target-mips: fix updating XContext on mmu exception

2015-10-29 Thread James Hogan
On Thu, Oct 29, 2015 at 05:17:52PM +, Yongbok Kim wrote:
> Correct updating XContext.Region field on mmu exceptions.
> If Config3.CTXTC = 0 then the R field of XContext has to be updated
> with the value of bits 63..62 of the virtual address upon a TLB
> exception.

It wouldn't hurt to mention how the existing behaviour is wrong, since
it requires a little staring (and counting of zeros) to see it, i.e.
that the old mask incorrectly selected bits 47:46 of the address, and
shifted them down into the middle of BadVPN2.

> Also fixed the below line which overs 80 characters.
> 
> Signed-off-by: Yongbok Kim 

Reviewed-by: James Hogan 

Cheers
James

> ---
>  target-mips/helper.c |7 ---
>  1 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/target-mips/helper.c b/target-mips/helper.c
> index 2d86323..b3fe816 100644
> --- a/target-mips/helper.c
> +++ b/target-mips/helper.c
> @@ -293,9 +293,10 @@ static void raise_mmu_exception(CPUMIPSState *env, 
> target_ulong address,
>  (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
>  #if defined(TARGET_MIPS64)
>  env->CP0_EntryHi &= env->SEGMask;
> -env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 
> 7))) |
> -((address & 0xC000ULL) >> (55 - 
> env->SEGBITS)) |
> -((address & ((1ULL << env->SEGBITS) - 1) & 
> 0xE000ULL) >> 9);
> +env->CP0_XContext =
> +/* PTEBase */   (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 
> 7))) |
> +/* R */ (extract64(address, 62, 2) << (env->SEGBITS - 9)) |
> +/* BadVPN2 */   (extract64(address, 13, env->SEGBITS - 13) << 4);
>  #endif
>  cs->exception_index = exception;
>  env->error_code = error_code;
> -- 
> 1.7.1
> 
> 


signature.asc
Description: Digital signature


Re: [Qemu-devel] [PATCH 4/4] json-streamer: Limit number of tokens in addition to total size

2015-10-29 Thread Eric Blake
On 10/29/2015 12:27 PM, Markus Armbruster wrote:
>> Sounds like we have some quadratic (or worse) scaling in the parser.
>> Worth fixing some day, but I also agree that we don't have to tackle it
>> in this series.
> 
> I believe it's linear with a criminally negligent constant (several KiB
> per token).  The first hog is actually fairly obvious: we use on QDict
> per token.

Wow.  I just read through the code, and you're right.  We are passing
around QDicts right and left (one per token, with 4 keys, which is
several mallocs per token), and then creating a QList of those tokens.

Prior to commit 65c0f1e9, when we were really incrementing the refcount
of each token on each level of nesting (as part of copying context, for
definite quadratic behavior), the refcounts let us ensure tokens would
be cleaned up at the end.  But I'm hard pressed to see the refcount of
tokens going above one in the current code, which means we aren't
gaining anything by using QDict for reference counting.  For that
matter, JSON is quite linear - the code talks about needing to backtrack
in different contexts, but JSON doesn't have ambiguities that need
backtracking to try multiple different rules.  It seems like the code is
overengineered because it is copied from another language where
backtracking to try several alternate parses actually makes sense.

I suspect that using a C struct per token, and a C array of those
structs, would go a long way towards alleviating memory abuse per token.

Are you tackling that, or would you like me to take a stab at it while
you work on flushing my pending qapi patches?

> 
>> I'm assuming you temporarily patched check-qjson to use larger constants
>> when you hit your ~100K token testing?  Because I am definitely seeing a
>> lot of execution time spent on large_dict when running tests/check-qjson
>> by hand, in relation to all the other tests of that file, but not
>> minutes worth.  Care to post the diff you played with?
> 
> I tested on a slow machine.

I guess it was all the malloc pressure on a low-memory system that would
make it so much slower than what I'm seeing, if you stuck with the
default gen_test_json(gstr, 10, 100).

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 1/1] monitor: correct socket listen port

2015-10-29 Thread Sam Bobroff
On Thu, Oct 29, 2015 at 07:26:14AM +0100, Markus Armbruster wrote:
> Sam Bobroff  writes:
> 
> > Currently when constructing an inet socket monitor (e.g. via "-monitor
> > telent:localhost:12345,server,nowait") the port is ignored and a
> > random one is used instead. It appears this behaviour was accidentally
> > introduced by commit dafd325d "qemu-char: Convert socket backend to
> > QAPI".
> >
> > The cause is that the has_port field is not set in the address, so
> > later it is not copied by qapi_copy_SocketAddress(). This patch simply
> > adds the missing "has_port = true".
> >
> > Signed-off-by: Sam Bobroff 
> > ---
> >
> >  qemu-char.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/qemu-char.c b/qemu-char.c
> > index c4eb4ee..4fb9279 100644
> > --- a/qemu-char.c
> > +++ b/qemu-char.c
> > @@ -3605,6 +3605,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
> > ChardevBackend *backend,
> >  addr->kind = SOCKET_ADDRESS_KIND_INET;
> >  addr->inet = g_new0(InetSocketAddress, 1);
> >  addr->inet->host = g_strdup(host);
> > +addr->inet->has_port = true;
> >  addr->inet->port = g_strdup(port);
> >  addr->inet->has_to = qemu_opt_get(opts, "to");
> >  addr->inet->to = qemu_opt_get_number(opts, "to", 0);
> 
> Please see "[PATCH] qapi-schema: mark InetSocketAddress as mandatory
> again"
> Message-Id: <1445509543-30679-1-git-send-email-berra...@redhat.com>
> http://lists.nongnu.org/archive/html/qemu-devel/2015-10/msg05222.html

Ah thanks, that's obviously the correct fix too.
(Guess I'm one of the ones who got bitten ;-)

Cheers,
Sam.




Re: [Qemu-devel] [PATCH v3 4/5] xlnx-zynqmp: Connect the SPI devices

2015-10-29 Thread Alistair Francis
On Thu, Oct 29, 2015 at 12:04 PM, Peter Crosthwaite
 wrote:
> On Thu, Oct 29, 2015 at 10:45 AM, Alistair Francis
>  wrote:
>> On Thu, Oct 29, 2015 at 1:27 AM, Frederic Konrad
>>  wrote:
>>> On 29/10/2015 03:00, Peter Crosthwaite wrote:
 On Wed, Oct 28, 2015 at 10:32 AM, Alistair Francis <
 alistair.fran...@xilinx.com> wrote:

> Connect the Xilinx SPI device to the ZynqMP model.
>
>
 "devices"


> Signed-off-by: Alistair Francis 
> ---
> V3:
>  - Expose the SPI Bus as part of the SoC device
> V2:
>  - Don't connect the SPI flash to the SoC
>
>  hw/arm/xlnx-zynqmp.c | 37 +
>  include/hw/arm/xlnx-zynqmp.h |  4 
>  2 files changed, 41 insertions(+)
>
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index b36ca3d..5671d7a 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -48,6 +48,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
>  21, 22,
>  };
>
> +static const uint64_t spi_addr[XLNX_ZYNQMP_NUM_SPIS] = {
> +0xFF04, 0xFF05,
> +};
> +
> +static const int spi_intr[XLNX_ZYNQMP_NUM_SPIS] = {
> +19, 20,
> +};
> +
>  typedef struct XlnxZynqMPGICRegion {
>  int region_index;
>  uint32_t address;
> @@ -97,6 +105,12 @@ static void xlnx_zynqmp_init(Object *obj)
>
>  object_initialize(&s->sata, sizeof(s->sata), TYPE_SYSBUS_AHCI);
>  qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
> +
> +for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
> +object_initialize(&s->spi[i], sizeof(s->spi[i]),
> +  TYPE_XILINX_SPIPS);
> +qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
> +}
>  }
>
>  static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
> @@ -258,6 +272,29 @@ static void xlnx_zynqmp_realize(DeviceState *dev,
> Error **errp)
>
>  sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, SATA_ADDR);
>  sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, gic_spi[SATA_INTR]);
> +
> +for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
> +BusState *spi_bus;
> +char bus_name[6];
> +
> +object_property_set_int(OBJECT(&s->spi[i]), XLNX_ZYNQMP_NUM_SPIS,
> +"num-busses", &error_abort);
>
 The number of busses-per-controller is unrelated to the number of
 controllers. Setting num_busses != 1 is primarily a QSPI thing, so should
 this just default to 1? I think you can drop this setter completely.
>>
>> True, but see below for a problem.
>>


> +object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
> &err);
> +if (err) {
> +error_propagate(errp, err);
> +return;
> +}
> +
> +sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_addr[i]);
> +sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
> +   gic_spi[spi_intr[i]]);
> +
> +snprintf(bus_name, 6, "spi%d", i);
> +spi_bus = qdev_get_child_bus(DEVICE(&s->spi), bus_name);
> +
> +/* Add the SPI buses to the SoC child bus */
> +QLIST_INSERT_HEAD(&dev->child_bus, spi_bus, sibling);
>
 Nice! That is pretty simple in the end. One, question though, what happen
 with info qtree? Do you get doubles because the bus is double parented?
>>
>> I don't see the double parent problem, but I do see another problem.
>> I was doing it a little wrong with the multiple buses.
>>
>> When I assign the SPI bus to the SoC, the more recent one replaces the
>> previous one. I didn't notice it before because I had two buses (which
>> meant they had different names) so it ended up working.
>>
>
> I dont thinks this would have functioned though, as it would be 1st
> bus of 1st controller and 2nd bus of 2nd controller.
>
>> Now with only one bus per I2C they both have the same name and conflict.
>>
>> I can't change the name of the bus either, so this is a bit of a problem.
>>
>
> Can we add this renaming capability? I think it is the right solution.

Renaming the bus is pretty easy. There is still a qtree problem though.

For some reason SPI0 gets attached to the second SPI controller and I
can't figure it out.

bus: main-system-bus
  type System
  dev: xlnx.ps7-spi, id ""
gpio-out "sysbus-irq" 5
num-busses = 1 (0x1)
num-ss-bits = 4 (0x4)
num-txrx-bytes = 1 (0x1)
mmio ff05/0100
bus: spi1
  type SSI
  dev: sst25wf080, id ""
gpio-in "ssi-gpio-cs" 1
  dev: sst25wf080, id ""
gpio-in "ssi-gpio-cs" 1
  dev: sst25wf080, id ""
gpio-in "ssi-gpio-cs" 1
  dev: sst25wf080, id ""
gpio-in "ssi-gpio-cs" 1
bus: spi0
  

Re: [Qemu-devel] [PATCH] configure: workaround for Clang 3.5.0

2015-10-29 Thread John Snow


On 10/29/2015 05:25 PM, Peter Maydell wrote:
> On 29 October 2015 at 21:20, Laszlo Ersek  wrote:
>> On 10/29/15 21:29, John Snow wrote:
>>> Here's a good takeaway quote:
>>>
>>> 'Also, _FORTIFY_SOURCE + glibc + clang is not supported and does not
>>> work (for instance, it relies on __builtin_va_pack_len and friends,
>>> which we have no intention of supporting), so glibc compatibility is
>>> unlikely to be a strong motivator for a change here.'
>>
>> this quote would be compelling enough for me to disable _FORTIFY_SOURCE
>> when clang is seen, no questions asked. The above is a public no-support
>> statement from an apparently core clang developer, so "it happens to
>> build without errors with version X.Y.Z." just don't cut it. A positive
>> claim (bugzilla comment, release note, etc) would be necessary.
>>
>> ... As far as I'm concerned, of course. :)
> 
> I think I would agree with that.
> 
> thanks
> -- PMM
> 

OK. I'll spin a new one that disables FORTIFY SOURCE without test if it
detects you are using Clang.

(I am curious as to why it now magically works in later versions of
Clang though, despite such a strong "no support" statement from the
developer above. I might do a little digging.)

--js



Re: [Qemu-devel] [PATCH] configure: workaround for Clang 3.5.0

2015-10-29 Thread Peter Maydell
On 29 October 2015 at 21:20, Laszlo Ersek  wrote:
> On 10/29/15 21:29, John Snow wrote:
>> Here's a good takeaway quote:
>>
>> 'Also, _FORTIFY_SOURCE + glibc + clang is not supported and does not
>> work (for instance, it relies on __builtin_va_pack_len and friends,
>> which we have no intention of supporting), so glibc compatibility is
>> unlikely to be a strong motivator for a change here.'
>
> this quote would be compelling enough for me to disable _FORTIFY_SOURCE
> when clang is seen, no questions asked. The above is a public no-support
> statement from an apparently core clang developer, so "it happens to
> build without errors with version X.Y.Z." just don't cut it. A positive
> claim (bugzilla comment, release note, etc) would be necessary.
>
> ... As far as I'm concerned, of course. :)

I think I would agree with that.

thanks
-- PMM



Re: [Qemu-devel] [PATCH] configure: workaround for Clang 3.5.0

2015-10-29 Thread Laszlo Ersek
Aargh, clicked "Reply" instead of "Reply All". Resending.

On 10/29/15 21:29, John Snow wrote:
> 
> 
> On 10/29/2015 04:22 PM, John Snow wrote:
>> Clang++ 3.5 on Fedora 22 appears to have difficulty tolerating
>> D_FORTIFY_SOURCE for certain glibc headers, such as stdio.
>>
>> This interferes, currently, with any arm target build.
>>
>> Work around this by disabling FORTIFY_SOURCE for clang builds
>> if a problem is observed.
>>
>> Newer versions of clang such as 3.5.2 (As seen in debian-testing)
>> or 3.7.0 (As seen in Fedora 23 Beta) are unaffected and will not
>> trigger this workaround.
>>
>> Signed-off-by: John Snow 
>> ---
> 
> As a meta-cover-letter, this fix is a little weird in that it will
> disable FORTIFY_SOURCE (silently!) for non-debug builds. Not great.
> 
> (Maybe I could have it fail and print a warning encouraging users to
> either use --enable-debug or --disable-fortify-source?)
> 
> Still, It'd be nice to have Clang builds working out of the box for ARM
> builds. It just so happens that ARM is the only target that happens to
> trip this specific unfortunate chain of events.
> 
> Is it sane to check for clang-and-arm-targets only? Maybe it's a moot
> point -- newer (and older, I believe) versions of Clang won't trigger
> this at all.
> 
> Anyway, see these links (Dredged up by Laszlo Ersek, thanks!)

Thanks for the credit.

I didn't notice this patch on the list (and I've been CC'd just now), so
I'm unsure if I'm supposed to (try to) review it. If so, then:

> https://llvm.org/bugs/show_bug.cgi?id=7219
> https://llvm.org/bugs/show_bug.cgi?id=16821
> https://llvm.org/bugs/show_bug.cgi?id=23277#c2
> 
> Here's a good takeaway quote:
> 
> 'Also, _FORTIFY_SOURCE + glibc + clang is not supported and does not
> work (for instance, it relies on __builtin_va_pack_len and friends,
> which we have no intention of supporting), so glibc compatibility is
> unlikely to be a strong motivator for a change here.'

this quote would be compelling enough for me to disable _FORTIFY_SOURCE
when clang is seen, no questions asked. The above is a public no-support
statement from an apparently core clang developer, so "it happens to
build without errors with version X.Y.Z." just don't cut it. A positive
claim (bugzilla comment, release note, etc) would be necessary.

... As far as I'm concerned, of course. :)

Cheers
Laszlo


> 
> So long story short, we have a weird hacky workaround where we disable
> FORTIFY_SOURCE for compilers that don't appear to be able to support it.
> 
> --js
> 
>>  configure | 25 -
>>  1 file changed, 24 insertions(+), 1 deletion(-)
>>
>> diff --git a/configure b/configure
>> index 7a1d08d..7abfcc3 100755
>> --- a/configure
>> +++ b/configure
>> @@ -107,6 +107,11 @@ compile_object() {
>>do_cc $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
>>  }
>>  
>> +compile_cxx_object() {
>> +  local_cflags="$1"
>> +  do_cxx $QEMU_CXXFLAGS $local_cflags -c -o $TMPO $TMPC
>> +}
>> +
>>  compile_prog() {
>>local_cflags="$1"
>>local_ldflags="$2"
>> @@ -4436,13 +4441,31 @@ if ! compile_object "-Werror"; then
>>  fi
>>  
>>  ##
>> +# Test that we can use FORTIFY_SOURCE,
>> +# which might break Clang.
>> +
>> +if test "$debug" = "no"; then
>> +  cat > $TMPC << EOF
>> +#include 
>> +int main(int argc, char*argv[]) {
>> +  fprintf(stdout, "Hello World\n");
>> +  return 0;
>> +}
>> +EOF
>> +
>> +  if ! compile_cxx_object "-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2"; then
>> +  fortify_source="no";
>> +  fi
>> +fi
>> +
>> +##
>>  # End of CC checks
>>  # After here, no more $cc or $ld runs
>>  
>>  if test "$gcov" = "yes" ; then
>>CFLAGS="-fprofile-arcs -ftest-coverage -g $CFLAGS"
>>LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
>> -elif test "$debug" = "no" ; then
>> +elif test "$debug" = "no" && test "$fortify_source" != "no" ; then
>>CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
>>  fi
>>  
>>




Re: [Qemu-devel] [PATCH 00/40] Patch Round-up for stable 2.4.1, freeze on 2015-10-29

2015-10-29 Thread Denis V. Lunev

On 10/21/2015 08:51 PM, Michael Roth wrote:

Hi everyone,

The following new patches are queued for QEMU stable v2.4.1:

   https://github.com/mdroth/qemu/commits/stable-2.4-staging

The release is planned for 2015-11-03:

   http://wiki.qemu.org/Planning/2.4

Please respond here or CC qemu-sta...@nongnu.org on any patches you
think should be included in the release.

Testing/feedback is greatly appreciated.

Thanks!


Alberto Garcia (1):
   gtk: use setlocale() for LC_MESSAGES only

Alexander Graf (1):
   PPC: E500: Update u-boot to commit 79c884d7e4

Aníbal Limón (1):
   cpus.c: qemu_mutex_lock_iothread fix race condition at cpu thread init

Aurelien Jarno (2):
   target-ppc: fix vcipher, vcipherlast, vncipherlast and vpermxor
   target-ppc: fix xscmpodp and xscmpudp decoding

Christian Borntraeger (1):
   s390x/kvm: Fix vector validity bit in device machine checks

Cornelia Huck (2):
   s390x/css: start with cleared cstat/dstat
   virtio: avoid leading underscores for helpers

Dr. David Alan Gilbert (1):
   Migration: Generate the completed event only when we complete

Fam Zheng (2):
   scsi-disk: Fix assertion failure on WRITE SAME
   vmxnet3: Drop net_vmxnet3_info.can_receive

Gerd Hoffmann (1):
   virtio-input: ignore events until the guest driver is ready

Gonglei (1):
   vhost-scsi: fix wrong vhost-scsi firmware path

James Hogan (1):
   tcg/mips: Fix clobbering of qemu_ld inputs

Jason Wang (1):
   virtio-net: unbreak self announcement and guest offloads after migration

John Snow (2):
   ide: fix ATAPI command permissions
   ide: unify io_buffer_offset increments

Kevin Wolf (1):
   mirror: Fix coroutine reentrance

Mark Cave-Ayland (1):
   mac_dbdma: always clear FLUSH bit once DBDMA channel flush is complete

Markus Armbruster (5):
   qom: Do not reuse errp after a possible error
   qom: Fix invalid error check in property_get_str()
   qmp: Fix device-list-properties not to crash for abstract device
   qdev: Protect device-list-properties against broken devices
   Revert "qdev: Use qdev_get_device_class() for -device ,help"

Max Reitz (2):
   qemu-img: Fix crash in amend invocation
   qcow2: Make size_to_clusters() return uint64_t

Michael Roth (1):
   spapr_pci: fix device tree props for MSI/MSI-X

Michael S. Tsirkin (1):
   scripts/dump-guest-memory.py: fix after RAMBlock change

Peter Crosthwaite (2):
   exec-all: Translate TCI return addresses backwards too
   misc: zynq_slcr: Fix MMIO writes

Peter Lieven (2):
   block/iscsi: validate block size returned from target
   block/nfs: fix calculation of allocated file size

Peter Maydell (1):
   target-arm/arm-semi.c: Fix broken SYS_WRITE0 via gdb

Pierre Morel (1):
   virtio dataplane: adapt dataplane for virtio Version 1

Richard Henderson (1):
   target-arm: Share all common TCG temporaries

Stefan Weil (1):
   slirp: Fix non blocking connect for w32

Tony Krowiak (1):
   util/qemu-config: fix missing machine command line options

Vladislav Yasevich (2):
   rtl8139: Fix receive buffer overflow check
   rtl8139: Do not consume the packet during overflow in standard mode.

Wen Congyang (1):
   nbd: release exp->blk after all clients are closed


pls consider this:
[PATCH 4/4] migration: add missed aio_context_acquire into HMP snapshot code
[PULL 08/12] virtio: sync the dataplane vring state to the virtqueue 
before virtio_save


Den



[Qemu-devel] [PATCH 11/11] log: add "-d trace:PATTERN"

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

This is a bit easier to use than "-trace" if you are also enabling
other kinds of logging.  It is also more discoverable for experienced
QEMU users, and accessible from user-mode emulators.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 util/log.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/util/log.c b/util/log.c
index 5c641a0..2bcef95 100644
--- a/util/log.c
+++ b/util/log.c
@@ -19,6 +19,7 @@
 
 #include "qemu-common.h"
 #include "qemu/log.h"
+#include "trace/control.h"
 
 static char *logfilename;
 FILE *qemu_logfile;
@@ -154,6 +155,11 @@ int qemu_str_to_log_mask(const char *str)
 for (item = qemu_log_items; item->mask != 0; item++) {
 mask |= item->mask;
 }
+#ifdef CONFIG_TRACE_LOG
+} else if (strncmp(p, "trace:", 6) == 0 && p + 6 != p1) {
+trace_enable_events(p + 6);
+mask |= LOG_TRACE;
+#endif
 } else {
 for (item = qemu_log_items; item->mask != 0; item++) {
 if (cmp1(p, p1 - p, item->name)) {
@@ -161,9 +167,9 @@ int qemu_str_to_log_mask(const char *str)
 }
 }
 return 0;
+found:
+mask |= item->mask;
 }
-found:
-mask |= item->mask;
 if (*p1 != ',') {
 break;
 }
@@ -177,6 +183,10 @@ void qemu_print_log_usage(FILE *f)
 const QEMULogItem *item;
 fprintf(f, "Log items (comma separated):\n");
 for (item = qemu_log_items; item->mask != 0; item++) {
-fprintf(f, "%-10s %s\n", item->name, item->help);
+fprintf(f, "%-15s %s\n", item->name, item->help);
 }
+#ifdef CONFIG_TRACE_LOG
+fprintf(f, "trace:PATTERN   enable trace events\n");
+fprintf(f, "\nUse \"-d trace:help\" to get a list of trace events.\n\n");
+#endif
 }
-- 
2.1.4




[Qemu-devel] [PATCH v3 00/11] simplify usage of tracepoints, and connect them to logging

2015-10-29 Thread Denis V. Lunev
This series does three things:

1) add a "-trace [enable=]foo" option to enable one or more trace
events, and a "-trace help" option to show the list of tracepoints
(patches 4-5)

2) change the stderr tracing backend so that it prints to the
-D log file, and enable it by default.  "-trace file=..." is
now a synonym of -D if the log backend is enabled (patches 7-8)

3) add a "-d trace:foo" option that is a synonym for "-trace foo";
this makes the new functionality more discoverable to people used
to "-d", makes it available for user-mode emulation (which does
not have -trace), and is somewhat nice if you want to enable both
tracepoints and some other "-d" flag (patch 9).  When globbing
it is also less susceptible to unwanted shell expansion.

For example, you can trace block device I/O and save the result
to a file just by adding "-trace bdrv_aio_*,file=trace.txt", or
correlate it to guest PCs with "-d exec,nochain,trace:bdrv_aio_*".

Opinions?  I would like to have this in 2.5 if there is agreement.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 

Changes from v2:
- compilation fix was extended to patch 2 and 3
- replaced Reviewed-by with Acked-by by request from Christian

Changes from v1:
- small cleanup to vl.c is added as patch (4)
- compilation is fixed in patch (2)
- moved qemu-log.c to util/log.c to fix linking of qemu-io/qemu-nbd

Denis V. Lunev (2):
  trace: no need to call trace_backend_init in different branches now
  log: move qemu-log.c into util/ directory

Paolo Bonzini (9):
  trace: fix documentation
  trace: split trace_init_events out of trace_init_backends
  trace: split trace_init_file out of trace_init_backends
  trace: add "-trace enable=..."
  trace: add "-trace help"
  log: do not unnecessarily include qom/cpu.h
  trace: convert stderr backend to log
  trace: switch default backend to "log"
  log: add "-d trace:PATTERN"

 Makefile.objs   |  1 -
 bsd-user/main.c |  1 +
 configure   |  6 +-
 cpu-exec.c  |  1 +
 exec.c  |  1 +
 hw/acpi/cpu_hotplug.c   |  1 +
 hw/timer/a9gtimer.c |  1 +
 include/exec/log.h  | 60 
 include/qemu/log.h  | 60 +---
 linux-user/main.c   |  1 +
 qemu-io.c   |  2 +-
 qemu-options.hx | 22 --
 qom/cpu.c   |  1 +
 scripts/tracetool/backend/{stderr.py => log.py} |  9 +--
 target-alpha/translate.c|  1 +
 target-arm/translate.c  |  1 +
 target-cris/translate.c |  1 +
 target-i386/seg_helper.c|  1 +
 target-i386/smm_helper.c|  1 +
 target-i386/translate.c |  1 +
 target-lm32/helper.c|  1 +
 target-lm32/translate.c |  1 +
 target-m68k/translate.c |  1 +
 target-microblaze/helper.c  |  1 +
 target-microblaze/translate.c   |  1 +
 target-mips/helper.c|  1 +
 target-mips/translate.c |  1 +
 target-moxie/translate.c|  1 +
 target-openrisc/translate.c |  1 +
 target-ppc/mmu-hash32.c |  1 +
 target-ppc/mmu-hash64.c |  1 +
 target-ppc/mmu_helper.c |  1 +
 target-ppc/translate.c  |  1 +
 target-s390x/translate.c|  1 +
 target-sh4/helper.c |  1 +
 target-sh4/translate.c  |  1 +
 target-sparc/int32_helper.c |  1 +
 target-sparc/int64_helper.c |  1 +
 target-sparc/translate.c|  1 +
 target-tilegx/translate.c   |  1 +
 target-tricore/translate.c  |  1 +
 target-unicore32/translate.c|  1 +
 target-xtensa/translate.c   |  1 +
 tcg/tcg.c   |  1 +
 trace/control.c | 95 ++---
 trace/control.h | 42 ++-
 trace/simple.c  |  6 +-
 trace/simple.h  |  4 +-
 translate-all.c |  1 +
 util/Makefile.objs  |  1 +
 qemu-log.c => util/log.c| 19 -
 vl.c| 38 +-
 52 files changed, 274 insertions(+), 129 deletions(-)
 create mode 100644 include/exec/log.h
 rename script

[Qemu-devel] [PATCH 01/11] trace: fix documentation

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

Mention the ftrace backend too.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 qemu-options.hx | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 949db7f..594cddd 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3485,13 +3485,13 @@ Specify tracing options.
 @table @option
 @item events=@var{file}
 Immediately enable events listed in @var{file}.
-The file must contain one event name (as listed in the @var{trace-events} file)
-per line.
-This option is only available if QEMU has been compiled with
-either @var{simple} or @var{stderr} tracing backend.
+The file must contain one event name (as listed in the @file{trace-events} 
file)
+per line; globbing patterns are accepted too.  This option is only
+available if QEMU has been compiled with the @var{simple}, @var{stderr} or
+@var{ftrace} tracing backend.
+
 @item file=@var{file}
 Log output traces to @var{file}.
-
 This option is only available if QEMU has been compiled with
 the @var{simple} tracing backend.
 @end table
-- 
2.1.4




[Qemu-devel] [PATCH 08/11] log: move qemu-log.c into util/ directory

2015-10-29 Thread Denis V. Lunev
log will become common facility with tracepoints support in next step.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Paolo Bonzini 
---
 Makefile.objs| 1 -
 util/Makefile.objs   | 1 +
 qemu-log.c => util/log.c | 0
 3 files changed, 1 insertion(+), 1 deletion(-)
 rename qemu-log.c => util/log.c (100%)

diff --git a/Makefile.objs b/Makefile.objs
index fe02ee2..cdd7f83 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -81,7 +81,6 @@ endif
 
 ###
 # Target-independent parts used in system and user emulation
-common-obj-y += qemu-log.o
 common-obj-y += tcg-runtime.o
 common-obj-y += hw/
 common-obj-y += qom/
diff --git a/util/Makefile.objs b/util/Makefile.objs
index d7cc399..a11915c 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -29,3 +29,4 @@ util-obj-y += qemu-coroutine.o qemu-coroutine-lock.o 
qemu-coroutine-io.o
 util-obj-y += qemu-coroutine-sleep.o
 util-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o
 util-obj-y += buffer.o
+util-obj-y += log.o
diff --git a/qemu-log.c b/util/log.c
similarity index 100%
rename from qemu-log.c
rename to util/log.c
-- 
2.1.4




[Qemu-devel] [PATCH 07/11] log: do not unnecessarily include qom/cpu.h

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

Split the bits that require it to exec/log.h.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 bsd-user/main.c   |  1 +
 cpu-exec.c|  1 +
 exec.c|  1 +
 hw/acpi/cpu_hotplug.c |  1 +
 hw/timer/a9gtimer.c   |  1 +
 include/exec/log.h| 60 +++
 include/qemu/log.h| 59 --
 linux-user/main.c |  1 +
 qom/cpu.c |  1 +
 target-alpha/translate.c  |  1 +
 target-arm/translate.c|  1 +
 target-cris/translate.c   |  1 +
 target-i386/seg_helper.c  |  1 +
 target-i386/smm_helper.c  |  1 +
 target-i386/translate.c   |  1 +
 target-lm32/helper.c  |  1 +
 target-lm32/translate.c   |  1 +
 target-m68k/translate.c   |  1 +
 target-microblaze/helper.c|  1 +
 target-microblaze/translate.c |  1 +
 target-mips/helper.c  |  1 +
 target-mips/translate.c   |  1 +
 target-moxie/translate.c  |  1 +
 target-openrisc/translate.c   |  1 +
 target-ppc/mmu-hash32.c   |  1 +
 target-ppc/mmu-hash64.c   |  1 +
 target-ppc/mmu_helper.c   |  1 +
 target-ppc/translate.c|  1 +
 target-s390x/translate.c  |  1 +
 target-sh4/helper.c   |  1 +
 target-sh4/translate.c|  1 +
 target-sparc/int32_helper.c   |  1 +
 target-sparc/int64_helper.c   |  1 +
 target-sparc/translate.c  |  1 +
 target-tilegx/translate.c |  1 +
 target-tricore/translate.c|  1 +
 target-unicore32/translate.c  |  1 +
 target-xtensa/translate.c |  1 +
 tcg/tcg.c |  1 +
 translate-all.c   |  1 +
 40 files changed, 98 insertions(+), 59 deletions(-)
 create mode 100644 include/exec/log.h

diff --git a/bsd-user/main.c b/bsd-user/main.c
index adf2de0..520ce99 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -33,6 +33,7 @@
 #include "tcg.h"
 #include "qemu/timer.h"
 #include "qemu/envlist.h"
+#include "exec/log.h"
 
 int singlestep;
 unsigned long mmap_min_addr;
diff --git a/cpu-exec.c b/cpu-exec.c
index 7eef083..564a21d 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -27,6 +27,7 @@
 #include "exec/address-spaces.h"
 #include "qemu/rcu.h"
 #include "exec/tb-hash.h"
+#include "exec/log.h"
 #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
 #include "hw/i386/apic.h"
 #endif
diff --git a/exec.c b/exec.c
index 8af2570..87636a6 100644
--- a/exec.c
+++ b/exec.c
@@ -53,6 +53,7 @@
 
 #include "exec/memory-internal.h"
 #include "exec/ram_addr.h"
+#include "exec/log.h"
 
 #include "qemu/range.h"
 #ifndef _WIN32
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index f5b9972..16bacfc 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -11,6 +11,7 @@
  */
 #include "hw/hw.h"
 #include "hw/acpi/cpu_hotplug.h"
+#include "qom/cpu.h"
 
 static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size)
 {
diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
index dd4aae8..b38c76a 100644
--- a/hw/timer/a9gtimer.c
+++ b/hw/timer/a9gtimer.c
@@ -24,6 +24,7 @@
 #include "qemu/timer.h"
 #include "qemu/bitops.h"
 #include "qemu/log.h"
+#include "qom/cpu.h"
 
 #ifndef A9_GTIMER_ERR_DEBUG
 #define A9_GTIMER_ERR_DEBUG 0
diff --git a/include/exec/log.h b/include/exec/log.h
new file mode 100644
index 000..ba1c9b5
--- /dev/null
+++ b/include/exec/log.h
@@ -0,0 +1,60 @@
+#ifndef QEMU_EXEC_LOG_H
+#define QEMU_EXEC_LOG_H
+
+#include "qemu/log.h"
+#include "qom/cpu.h"
+#include "disas/disas.h"
+
+/* cpu_dump_state() logging functions: */
+/**
+ * log_cpu_state:
+ * @cpu: The CPU whose state is to be logged.
+ * @flags: Flags what to log.
+ *
+ * Logs the output of cpu_dump_state().
+ */
+static inline void log_cpu_state(CPUState *cpu, int flags)
+{
+if (qemu_log_enabled()) {
+cpu_dump_state(cpu, qemu_logfile, fprintf, flags);
+}
+}
+
+/**
+ * log_cpu_state_mask:
+ * @mask: Mask when to log.
+ * @cpu: The CPU whose state is to be logged.
+ * @flags: Flags what to log.
+ *
+ * Logs the output of cpu_dump_state() if loglevel includes @mask.
+ */
+static inline void log_cpu_state_mask(int mask, CPUState *cpu, int flags)
+{
+if (qemu_loglevel & mask) {
+log_cpu_state(cpu, flags);
+}
+}
+
+#ifdef NEED_CPU_H
+/* disas() and target_disas() to qemu_logfile: */
+static inline void log_target_disas(CPUState *cpu, target_ulong start,
+target_ulong len, int flags)
+{
+target_disas(qemu_logfile, cpu, start, len, flags);
+}
+
+static inline void log_disas(void *code, unsigned long size)
+{
+disas(qemu_logfile, code, size);
+}
+
+#if defined(CONFIG_USER_ONLY)
+/* page_dump() output to the log file: */
+static inline void log_page_dump(void)
+{
+page_dump(qemu_logfile);
+}
+#endif
+#endif
+
+#endif
diff --git a/include/qemu/log.h b/include/qemu/log.h
index 7de4500..ed57a3d 100644
--- a/includ

[Qemu-devel] [PATCH 10/11] trace: switch default backend to "log"

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

This enables integration with other QEMU logging facilities.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 5e65dd5..248c4ec 100755
--- a/configure
+++ b/configure
@@ -298,7 +298,7 @@ pkgversion=""
 pie=""
 zero_malloc=""
 qom_cast_debug="yes"
-trace_backends="nop"
+trace_backends="log"
 trace_file="trace"
 spice=""
 rbd=""
-- 
2.1.4




[Qemu-devel] [PATCH 02/11] trace: split trace_init_events out of trace_init_backends

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

This is cleaner and has two advantages.  First, it improves error
reporting with -daemonize.  Second, multiple "-trace events" options
now cumulate.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 qemu-io.c   |  2 +-
 trace/control.c |  5 ++---
 trace/control.h | 15 ---
 vl.c|  8 
 4 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index 269f17c..d6fa11b 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -440,7 +440,7 @@ int main(int argc, char **argv)
 }
 break;
 case 'T':
-if (!trace_init_backends(optarg, NULL)) {
+if (!trace_init_backends(optarg)) {
 exit(1); /* error message will have been printed */
 }
 break;
diff --git a/trace/control.c b/trace/control.c
index 995beb3..ee5fbca 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -85,7 +85,7 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent 
*ev)
 return NULL;
 }
 
-static void trace_init_events(const char *fname)
+void trace_init_events(const char *fname)
 {
 Location loc;
 FILE *fp;
@@ -142,7 +142,7 @@ static void trace_init_events(const char *fname)
 loc_pop(&loc);
 }
 
-bool trace_init_backends(const char *events, const char *file)
+bool trace_init_backends(const char *file)
 {
 #ifdef CONFIG_TRACE_SIMPLE
 if (!st_init(file)) {
@@ -164,6 +164,5 @@ bool trace_init_backends(const char *events, const char 
*file)
 }
 #endif
 
-trace_init_events(events);
 return true;
 }
diff --git a/trace/control.h b/trace/control.h
index da9bb6b..bfbe560 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -150,8 +150,6 @@ static void trace_event_set_state_dynamic(TraceEvent *ev, 
bool state);
 
 /**
  * trace_init_backends:
- * @events: Name of file with events to be enabled at startup; may be NULL.
- *  Corresponds to commandline option "-trace events=...".
  * @file:   Name of trace output file; may be NULL.
  *  Corresponds to commandline option "-trace file=...".
  *
@@ -159,7 +157,18 @@ static void trace_event_set_state_dynamic(TraceEvent *ev, 
bool state);
  *
  * Returns: Whether the backends could be successfully initialized.
  */
-bool trace_init_backends(const char *events, const char *file);
+bool trace_init_backends(const char *file);
+
+/**
+ * trace_init_events:
+ * @events: Name of file with events to be enabled at startup; may be NULL.
+ *  Corresponds to commandline option "-trace events=...".
+ *
+ * Read the list of enabled tracing events.
+ *
+ * Returns: Whether the backends could be successfully initialized.
+ */
+void trace_init_events(const char *file);
 
 
 #include "trace/control-internal.h"
diff --git a/vl.c b/vl.c
index f5f7c3f..129177e 100644
--- a/vl.c
+++ b/vl.c
@@ -2961,7 +2961,6 @@ int main(int argc, char **argv, char **envp)
 bool userconfig = true;
 const char *log_mask = NULL;
 const char *log_file = NULL;
-const char *trace_events = NULL;
 const char *trace_file = NULL;
 ram_addr_t maxram_size;
 uint64_t ram_slots = 0;
@@ -3886,8 +3885,9 @@ int main(int argc, char **argv, char **envp)
 if (!opts) {
 exit(1);
 }
-trace_events = qemu_opt_get(opts, "events");
+trace_init_events(qemu_opt_get(opts, "events"));
 trace_file = qemu_opt_get(opts, "file");
+qemu_opts_del(opts);
 break;
 }
 case QEMU_OPTION_readconfig:
@@ -4084,7 +4084,7 @@ int main(int argc, char **argv, char **envp)
 }
 
 if (!is_daemonized()) {
-if (!trace_init_backends(trace_events, trace_file)) {
+if (!trace_init_backends(trace_file)) {
 exit(1);
 }
 }
@@ -4636,7 +4636,7 @@ int main(int argc, char **argv, char **envp)
 os_setup_post();
 
 if (is_daemonized()) {
-if (!trace_init_backends(trace_events, trace_file)) {
+if (!trace_init_backends(trace_file)) {
 exit(1);
 }
 }
-- 
2.1.4




[Qemu-devel] [PATCH 03/11] trace: split trace_init_file out of trace_init_backends

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

This is cleaner, and improves error reporting with -daemonize.

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 qemu-io.c   |  2 +-
 trace/control.c | 17 -
 trace/control.h | 13 -
 trace/simple.c  |  6 ++
 trace/simple.h  |  4 ++--
 vl.c| 13 +
 6 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index d6fa11b..fbddf82 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -440,7 +440,7 @@ int main(int argc, char **argv)
 }
 break;
 case 'T':
-if (!trace_init_backends(optarg)) {
+if (!trace_init_backends()) {
 exit(1); /* error message will have been printed */
 }
 break;
diff --git a/trace/control.c b/trace/control.c
index ee5fbca..3e33d03 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -142,17 +142,24 @@ void trace_init_events(const char *fname)
 loc_pop(&loc);
 }
 
-bool trace_init_backends(const char *file)
+void trace_init_file(const char *file)
 {
 #ifdef CONFIG_TRACE_SIMPLE
-if (!st_init(file)) {
-fprintf(stderr, "failed to initialize simple tracing backend.\n");
-return false;
-}
+st_set_trace_file(file);
 #else
 if (file) {
 fprintf(stderr, "error: -trace file=...: "
 "option not supported by the selected tracing backends\n");
+exit(1);
+}
+#endif
+}
+
+bool trace_init_backends(void)
+{
+#ifdef CONFIG_TRACE_SIMPLE
+if (!st_init()) {
+fprintf(stderr, "failed to initialize simple tracing backend.\n");
 return false;
 }
 #endif
diff --git a/trace/control.h b/trace/control.h
index bfbe560..d2506d4 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -157,7 +157,7 @@ static void trace_event_set_state_dynamic(TraceEvent *ev, 
bool state);
  *
  * Returns: Whether the backends could be successfully initialized.
  */
-bool trace_init_backends(const char *file);
+bool trace_init_backends(void);
 
 /**
  * trace_init_events:
@@ -170,6 +170,17 @@ bool trace_init_backends(const char *file);
  */
 void trace_init_events(const char *file);
 
+/**
+ * trace_init_file:
+ * @file:   Name of trace output file; may be NULL.
+ *  Corresponds to commandline option "-trace file=...".
+ *
+ * Record the name of the output file for the tracing backend.
+ * Exits if no selected backend does not support specifying the
+ * output file, and a non-NULL file was passed.
+ */
+void trace_init_file(const char *file);
+
 
 #include "trace/control-internal.h"
 
diff --git a/trace/simple.c b/trace/simple.c
index 11ad030..a4bc705 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -322,7 +322,7 @@ void st_set_trace_file_enabled(bool enable)
  * @fileThe trace file name or NULL for the default name- set at
  *  config time
  */
-bool st_set_trace_file(const char *file)
+void st_set_trace_file(const char *file)
 {
 st_set_trace_file_enabled(false);
 
@@ -335,7 +335,6 @@ bool st_set_trace_file(const char *file)
 }
 
 st_set_trace_file_enabled(true);
-return true;
 }
 
 void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE 
*stream, const char *fmt, ...))
@@ -373,7 +372,7 @@ static GThread *trace_thread_create(GThreadFunc fn)
 return thread;
 }
 
-bool st_init(const char *file)
+bool st_init(void)
 {
 GThread *thread;
 
@@ -386,6 +385,5 @@ bool st_init(const char *file)
 }
 
 atexit(st_flush_trace_buffer);
-st_set_trace_file(file);
 return true;
 }
diff --git a/trace/simple.h b/trace/simple.h
index 6997996..8d1a32e 100644
--- a/trace/simple.h
+++ b/trace/simple.h
@@ -20,8 +20,8 @@
 
 void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
 void st_set_trace_file_enabled(bool enable);
-bool st_set_trace_file(const char *file);
-bool st_init(const char *file);
+void st_set_trace_file(const char *file);
+bool st_init(void);
 void st_flush_trace_buffer(void);
 
 typedef struct {
diff --git a/vl.c b/vl.c
index 129177e..0424ce5 100644
--- a/vl.c
+++ b/vl.c
@@ -2961,7 +2961,7 @@ int main(int argc, char **argv, char **envp)
 bool userconfig = true;
 const char *log_mask = NULL;
 const char *log_file = NULL;
-const char *trace_file = NULL;
+char *trace_file = NULL;
 ram_addr_t maxram_size;
 uint64_t ram_slots = 0;
 FILE *vmstate_dump_file = NULL;
@@ -3886,7 +3886,10 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 trace_init_events(qemu_opt_get(opts, "events"));
-trace_file = qemu_opt_get(opts, "file");
+if (trace_file) {
+g_free(trace_file);
+}
+trace_file = g_strdup(qemu_opt_get(opts, "file"));
 qemu_opts_del(opts);
 break;
 }
@@ -4067,6 +4070,8 @@ int main(int argc, ch

[Qemu-devel] [PATCH 09/11] trace: convert stderr backend to log

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 configure   |  4 ++--
 include/qemu/log.h  |  1 +
 scripts/tracetool/backend/{stderr.py => log.py} |  9 +
 trace/control.c | 10 ++
 util/log.c  |  3 +++
 vl.c|  2 ++
 6 files changed, 23 insertions(+), 6 deletions(-)
 rename scripts/tracetool/backend/{stderr.py => log.py} (78%)

diff --git a/configure b/configure
index 7a1d08d..5e65dd5 100755
--- a/configure
+++ b/configure
@@ -5300,8 +5300,8 @@ if have_backend "simple"; then
   # Set the appropriate trace file.
   trace_file="\"$trace_file-\" FMT_pid"
 fi
-if have_backend "stderr"; then
-  echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak
+if have_backend "log"; then
+  echo "CONFIG_TRACE_LOG=y" >> $config_host_mak
 fi
 if have_backend "ust"; then
   echo "CONFIG_TRACE_UST=y" >> $config_host_mak
diff --git a/include/qemu/log.h b/include/qemu/log.h
index ed57a3d..5a0fbe3 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -38,6 +38,7 @@ static inline bool qemu_log_enabled(void)
 #define LOG_GUEST_ERROR(1 << 11)
 #define CPU_LOG_MMU(1 << 12)
 #define CPU_LOG_TB_NOCHAIN (1 << 13)
+#define LOG_TRACE  (1 << 14)
 
 /* Returns true if a bit is set in the current loglevel mask
  */
diff --git a/scripts/tracetool/backend/stderr.py 
b/scripts/tracetool/backend/log.py
similarity index 78%
rename from scripts/tracetool/backend/stderr.py
rename to scripts/tracetool/backend/log.py
index ca58054..a62c310 100644
--- a/scripts/tracetool/backend/stderr.py
+++ b/scripts/tracetool/backend/log.py
@@ -25,6 +25,7 @@ def generate_h_begin(events):
 '#include ',
 '#include ',
 '#include "trace/control.h"',
+'#include "qemu/log.h"',
 '')
 
 
@@ -36,10 +37,10 @@ def generate_h(event):
 out('if (trace_event_get_state(%(event_id)s)) {',
 'struct timeval _now;',
 'gettimeofday(&_now, NULL);',
-'fprintf(stderr, "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",',
-'getpid(),',
-'(size_t)_now.tv_sec, (size_t)_now.tv_usec',
-'%(argnames)s);',
+'qemu_log_mask(LOG_TRACE, "%%d@%%zd.%%06zd:%(name)s " %(fmt)s 
"\\n",',
+'  getpid(),',
+'  (size_t)_now.tv_sec, (size_t)_now.tv_usec',
+'  %(argnames)s);',
 '}',
 event_id="TRACE_" + event.name.upper(),
 name=event.name,
diff --git a/trace/control.c b/trace/control.c
index 7c84795..9a1e381 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -14,6 +14,9 @@
 #ifdef CONFIG_TRACE_FTRACE
 #include "trace/ftrace.h"
 #endif
+#ifdef CONFIG_TRACE_LOG
+#include "qemu/log.h"
+#endif
 #include "qemu/error-report.h"
 
 TraceEvent *trace_event_name(const char *name)
@@ -171,6 +174,13 @@ void trace_init_file(const char *file)
 {
 #ifdef CONFIG_TRACE_SIMPLE
 st_set_trace_file(file);
+#elif defined CONFIG_TRACE_LOG
+/* If both the simple and the log backends are enabled, "-trace file"
+ * only applies to the simple backend; use "-D" for the log backend.
+ */
+if (file) {
+qemu_set_log_filename(file);
+}
 #else
 if (file) {
 fprintf(stderr, "error: -trace file=...: "
diff --git a/util/log.c b/util/log.c
index efd07c8..5c641a0 100644
--- a/util/log.c
+++ b/util/log.c
@@ -51,6 +51,9 @@ void qemu_log_mask(int mask, const char *fmt, ...)
 void do_qemu_set_log(int log_flags, bool use_own_buffers)
 {
 qemu_loglevel = log_flags;
+#ifdef CONFIG_TRACE_LOG
+qemu_loglevel |= LOG_TRACE;
+#endif
 if (qemu_loglevel && !qemu_logfile) {
 if (logfilename) {
 qemu_logfile = fopen(logfilename, log_append ? "a" : "w");
diff --git a/vl.c b/vl.c
index 83ffd92..ca4f7a0 100644
--- a/vl.c
+++ b/vl.c
@@ -4093,6 +4093,8 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 qemu_set_log(mask);
+} else {
+qemu_set_log(0);
 }
 
 if (!trace_init_backends()) {
-- 
2.1.4




[Qemu-devel] [PATCH 04/11] trace: no need to call trace_backend_init in different branches now

2015-10-29 Thread Denis V. Lunev
original idea to split calling locations was to spawn tracing thread
in the final child process according to

commit 8a745f2a9296ad2cf6bda33534ed298f2625a4ad
Author: Michael Mueller
Date:   Mon Sep 23 16:36:54 2013 +0200

os_daemonize is now on top of both locations. Drop unneeded ifs.

Signed-off-by: Denis V. Lunev 
Reviewed-by: Paolo Bonzini 
---
 vl.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/vl.c b/vl.c
index 0424ce5..4261662 100644
--- a/vl.c
+++ b/vl.c
@@ -4088,10 +4088,8 @@ int main(int argc, char **argv, char **envp)
 qemu_set_log(mask);
 }
 
-if (!is_daemonized()) {
-if (!trace_init_backends()) {
-exit(1);
-}
+if (!trace_init_backends()) {
+exit(1);
 }
 
 /* If no data_dir is specified then try to find it relative to the
@@ -4640,12 +4638,6 @@ int main(int argc, char **argv, char **envp)
 
 os_setup_post();
 
-if (is_daemonized()) {
-if (!trace_init_backends()) {
-exit(1);
-}
-}
-
 main_loop();
 bdrv_close_all();
 pause_all_vcpus();
-- 
2.1.4




[Qemu-devel] [PATCH 05/11] trace: add "-trace enable=..."

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

Allow enabling events without going through a file, for example:

   qemu-system-x86_64 -trace bdrv_aio_writev -trace bdrv_aio_readv

or with globbing too:

   qemu-system-x86_64 -trace 'bdrv_aio_*'

if an appropriate backend is enabled (simple, stderr, ftrace).

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 qemu-options.hx | 10 +-
 trace/control.c | 48 +++-
 trace/control.h |  9 +
 vl.c| 11 +--
 4 files changed, 54 insertions(+), 24 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 594cddd..6e8cc0c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3471,7 +3471,7 @@ config files on @var{sysconfdir}, but won't make it skip 
the QEMU-provided confi
 files from @var{datadir}.
 ETEXI
 DEF("trace", HAS_ARG, QEMU_OPTION_trace,
-"-trace [events=][,file=]\n"
+"-trace [[enable=]][,events=][,file=]\n"
 "specify tracing options\n",
 QEMU_ARCH_ALL)
 STEXI
@@ -3483,6 +3483,14 @@ HXCOMM HX does not support conditional compilation of 
text.
 Specify tracing options.
 
 @table @option
+@item [enable=]@var{pattern}
+Immediately enable events matching @var{pattern}.
+The file must contain one event name (as listed in the @file{trace-events} 
file)
+per line; globbing patterns are accepted too.  This option is only
+available if QEMU has been compiled with the @var{simple}, @var{stderr}
+or @var{ftrace} tracing backend.  To specify multiple events or patterns,
+specify the @option{-trace} option multiple times.
+
 @item events=@var{file}
 Immediately enable events listed in @var{file}.
 The file must contain one event name (as listed in the @file{trace-events} 
file)
diff --git a/trace/control.c b/trace/control.c
index 3e33d03..715b5b7 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -85,6 +85,32 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent 
*ev)
 return NULL;
 }
 
+void trace_enable_events(const char *line_buf)
+{
+const bool enable = ('-' != line_buf[0]);
+const char *line_ptr = enable ? line_buf : line_buf + 1;
+
+if (trace_event_is_pattern(line_ptr)) {
+TraceEvent *ev = NULL;
+while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) {
+if (trace_event_get_state_static(ev)) {
+trace_event_set_state_dynamic(ev, enable);
+}
+}
+} else {
+TraceEvent *ev = trace_event_name(line_ptr);
+if (ev == NULL) {
+error_report("WARNING: trace event '%s' does not exist",
+ line_ptr);
+} else if (!trace_event_get_state_static(ev)) {
+error_report("WARNING: trace event '%s' is not traceable",
+ line_ptr);
+} else {
+trace_event_set_state_dynamic(ev, enable);
+}
+}
+}
+
 void trace_init_events(const char *fname)
 {
 Location loc;
@@ -111,27 +137,7 @@ void trace_init_events(const char *fname)
 if ('#' == line_buf[0]) { /* skip commented lines */
 continue;
 }
-const bool enable = ('-' != line_buf[0]);
-char *line_ptr = enable ? line_buf : line_buf + 1;
-if (trace_event_is_pattern(line_ptr)) {
-TraceEvent *ev = NULL;
-while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) {
-if (trace_event_get_state_static(ev)) {
-trace_event_set_state_dynamic(ev, enable);
-}
-}
-} else {
-TraceEvent *ev = trace_event_name(line_ptr);
-if (ev == NULL) {
-error_report("WARNING: trace event '%s' does not exist",
- line_ptr);
-} else if (!trace_event_get_state_static(ev)) {
-error_report("WARNING: trace event '%s' is not traceable",
- line_ptr);
-} else {
-trace_event_set_state_dynamic(ev, enable);
-}
-}
+trace_enable_events(line_buf);
 }
 }
 if (fclose(fp) != 0) {
diff --git a/trace/control.h b/trace/control.h
index d2506d4..32a66ce 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -181,6 +181,15 @@ void trace_init_events(const char *file);
  */
 void trace_init_file(const char *file);
 
+/**
+ * trace_enable_events:
+ * @line_buf: A string with a glob pattern of events to be enabled or,
+ *if the string starts with '-', disabled.
+ *
+ * Enable or disable matching events.
+ */
+void trace_enable_events(const char *line_buf);
+
 
 #include "trace/control-internal.h"
 
diff --git a/vl.c b/vl.c
index 4261662..83ffd92 100644
--- a/vl.c
+++ b/vl.c
@@ -269,10 +269,14 @@ static QemuOptsList qemu_sandbox_opts = {
 
 static QemuOptsList qemu_trace_opts = {
 .name = "trace"

[Qemu-devel] [PATCH 06/11] trace: add "-trace help"

2015-10-29 Thread Denis V. Lunev
From: Paolo Bonzini 

Print a list of trace points

Signed-off-by: Paolo Bonzini 
Signed-off-by: Denis V. Lunev 
Acked-by: Christian Borntraeger 
---
 qemu-options.hx |  2 ++
 trace/control.c | 21 -
 trace/control.h |  7 +++
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 6e8cc0c..b36d8b9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3491,6 +3491,8 @@ available if QEMU has been compiled with the 
@var{simple}, @var{stderr}
 or @var{ftrace} tracing backend.  To specify multiple events or patterns,
 specify the @option{-trace} option multiple times.
 
+Use @code{-trace help} to print a list of names of trace points.
+
 @item events=@var{file}
 Immediately enable events listed in @var{file}.
 The file must contain one event name (as listed in the @file{trace-events} 
file)
diff --git a/trace/control.c b/trace/control.c
index 715b5b7..7c84795 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -85,7 +85,16 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent 
*ev)
 return NULL;
 }
 
-void trace_enable_events(const char *line_buf)
+void trace_list_events(void)
+{
+int i;
+for (i = 0; i < trace_event_count(); i++) {
+TraceEvent *res = trace_event_id(i);
+fprintf(stderr, "%s\n", trace_event_get_name(res));
+}
+}
+
+static void do_trace_enable_events(const char *line_buf)
 {
 const bool enable = ('-' != line_buf[0]);
 const char *line_ptr = enable ? line_buf : line_buf + 1;
@@ -111,6 +120,16 @@ void trace_enable_events(const char *line_buf)
 }
 }
 
+void trace_enable_events(const char *line_buf)
+{
+if (is_help_option(line_buf)) {
+trace_list_events();
+exit(0);
+} else {
+do_trace_enable_events(line_buf);
+}
+}
+
 void trace_init_events(const char *fname)
 {
 Location loc;
diff --git a/trace/control.h b/trace/control.h
index 32a66ce..3707b3b 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -182,6 +182,13 @@ void trace_init_events(const char *file);
 void trace_init_file(const char *file);
 
 /**
+ * trace_list_events:
+ *
+ * List all available events.
+ */
+void trace_list_events(void);
+
+/**
  * trace_enable_events:
  * @line_buf: A string with a glob pattern of events to be enabled or,
  *if the string starts with '-', disabled.
-- 
2.1.4




Re: [Qemu-devel] RFC: Add support for KVM_CAP_SPLIT_IRQCHIP

2015-10-29 Thread Eric Blake
On 10/29/2015 02:25 PM, Matt Gingell wrote:
> Hi,
> 
> The following patch adds support for the new KVM split irqchip
> interface discussed recently on the KVM mailing list.
> 
> [kvm] KVM: x86: Split the APIC from the rest of IRQCHIP.
> http://www.mailbrowse.com/kvm/138252.html
> 
> Our testing found some issues with the implementation of split IRQ
> chip in the kernel, and without changes to address those it will not
> be possible to test this. We've been able to do some preliminary
> testing of the QEMU against our local kernel though and I'm able to
> boot Linux and Windows with KVM_CAP_SPLIT_IRQCHIP enabled.
> 
> While we work on getting the KVM piece ready to submit, I'd appreciate
> any feedback or discussion on the user space portion.
> 
> Thanks,
> Matt Gingell
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index f4db340..3c14e78 100644

Your diff doesn't include the usual '---' separator and diffstat
provided by 'git send-email'; making it a bit harder to see at a glance
what your patch touches.

I'm just doing an interface review, since I happened to notice that it
touched a .json file.

> +++ b/qapi/common.json
> @@ -114,3 +114,19 @@
>  ##
>  { 'enum': 'OnOffAuto',
>'data': [ 'auto', 'on', 'off' ] }
> +
> +##
> +# @OnOffSplit
> +#
> +# An enumeration of three values: on, off, and split
> +#
> +# @on: Enabled
> +#
> +# @off: Disabled
> +#
> +# @split: Mixed
> +#
> +# Since: 2.5 (???)

The question marks should not be in the final patch (but this is an RFC,
so that's okay).  On the other hand, you've missed soft freeze for 2.5,
so it may end up being something we add for 2.6 instead.

> +##
> +{ 'enum': 'OnOffSplit',
> +  'data': [ 'on', 'off', 'split' ] }

Nothing in the user interface seems to use this new enum, so you are
just using it internally.  That's okay; it's not the first time.


> @@ -54,10 +55,15 @@ This is used to enable an accelerator. Depending on the 
> target architecture,
>  kvm, xen, or tcg can be available. By default, tcg is used. If there is more
>  than one accelerator specified, the next one is used if the previous one 
> fails
>  to initialize.
> +<<<
>  @item kernel_irqchip=on|off
>  Enables in-kernel irqchip support for the chosen accelerator when available.
>  @item gfx_passthru=on|off
>  Enables IGD GFX passthrough support for the chosen machine when available.
> +===
> +@item kernel_irqchip=on|off|split
> +Controls in-kernel irqchip support for the chosen accelerator when available.
> +>>>

Umm, you really don't want merge markers in your commit.


> @@ -2799,6 +2805,20 @@ void kvm_arch_init_irq_routing(KVMState *s)
>   */
>  kvm_msi_via_irqfd_allowed = true;
>  kvm_gsi_routing_allowed = true;
> +
> +if (kvm_irqchip_is_split()) {
> +int i;
> +
> +/* If the ioapic is in QEMU and the lapics are in KVM, reserve
> +   MSI routes for signaling interrupts to the local apics. */
> +for (i = 0; i < IOAPIC_NUM_PINS; i++) {
> +struct MSIMessage msg = { 0x0, 0x0 };
> +if (kvm_irqchip_add_msi_route(s, msg) < 0) {
> +fprintf(stderr, "Could not enable split IRQ mode.");
> +exit(-1);

exit(-1) is usually NOT what you want (yes, xargs has a special case
when $? is 255 - but it is seldom used).  You probably want exit(1).

We are trying to avoid the addition of new fprintf(stderr), and instead
use error_report(), in part because it gives more consistent output
(such as the option to prepend timestamps).

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] RFC: Add support for KVM_CAP_SPLIT_IRQCHIP

2015-10-29 Thread Matt Gingell
Hi,

The following patch adds support for the new KVM split irqchip
interface discussed recently on the KVM mailing list.

[kvm] KVM: x86: Split the APIC from the rest of IRQCHIP.
http://www.mailbrowse.com/kvm/138252.html

Our testing found some issues with the implementation of split IRQ
chip in the kernel, and without changes to address those it will not
be possible to test this. We've been able to do some preliminary
testing of the QEMU against our local kernel though and I'm able to
boot Linux and Windows with KVM_CAP_SPLIT_IRQCHIP enabled.

While we work on getting the KVM piece ready to submit, I'd appreciate
any feedback or discussion on the user space portion.

Thanks,
Matt Gingell

diff --git a/hw/core/machine.c b/hw/core/machine.c
index f4db340..3c14e78 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -11,6 +11,7 @@
  */
 
 #include "hw/boards.h"
+#include "qapi-visit.h"
 #include "qapi/visitor.h"
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
@@ -31,12 +32,34 @@ static void machine_set_accel(Object *obj, const char 
*value, Error **errp)
 ms->accel = g_strdup(value);
 }
 
-static void machine_set_kernel_irqchip(Object *obj, bool value, Error **errp)
+static void machine_set_kernel_irqchip(Object *obj, Visitor *v,
+   void *opaque, const char *name,
+   Error **errp)
 {
-MachineState *ms = MACHINE(obj);
-
-ms->kernel_irqchip_allowed = value;
-ms->kernel_irqchip_required = value;
+OnOffSplit mode;
+MachineState *ms = MACHINE(obj);
+
+visit_type_OnOffSplit(v, &mode, name, errp);
+switch (mode) {
+case ON_OFF_SPLIT_ON:
+ms->kernel_irqchip_allowed = true;
+ms->kernel_irqchip_required = true;
+ms->kernel_irqchip_split = false;
+break;
+case ON_OFF_SPLIT_OFF:
+ms->kernel_irqchip_allowed = false;
+ms->kernel_irqchip_required = false;
+ms->kernel_irqchip_split = false;
+break;
+case ON_OFF_SPLIT_SPLIT:
+ms->kernel_irqchip_allowed = true;
+ms->kernel_irqchip_required = true;
+ms->kernel_irqchip_split = true;
+break;
+default:
+error_report("Option 'kernel-irqchip' must be one of on|off|split");
+exit(1);
+}
 }
 
 static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v,
@@ -341,12 +364,12 @@ static void machine_initfn(Object *obj)
 object_property_set_description(obj, "accel",
 "Accelerator list",
 NULL);
-object_property_add_bool(obj, "kernel-irqchip",
- NULL,
- machine_set_kernel_irqchip,
- NULL);
+object_property_add(obj, "kernel-irqchip", "OnOffSplit",
+NULL,
+machine_set_kernel_irqchip,
+NULL, NULL, NULL);
 object_property_set_description(obj, "kernel-irqchip",
-"Use KVM in-kernel irqchip",
+"Configure KVM in-kernel irqchip",
 NULL);
 object_property_add(obj, "kvm-shadow-mem", "int",
 machine_get_kvm_shadow_mem,
@@ -477,6 +500,11 @@ bool machine_kernel_irqchip_required(MachineState *machine)
 return machine->kernel_irqchip_required;
 }
 
+bool machine_kernel_irqchip_split(MachineState *machine)
+{
+return machine->kernel_irqchip_split;
+}
+
 int machine_kvm_shadow_mem(MachineState *machine)
 {
 return machine->kvm_shadow_mem;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index efbd41a..13db224 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -66,6 +66,7 @@
 #include "hw/mem/pc-dimm.h"
 #include "qapi/visitor.h"
 #include "qapi-visit.h"
+#include "qom/cpu.h"
 
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -1530,10 +1531,11 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq 
*gsi,
 qemu_register_boot_set(pc_boot_set, *rtc_state);
 
 if (!xen_enabled()) {
-if (kvm_irqchip_in_kernel()) {
+if (kvm_pit_in_kernel()) {
 pit = kvm_pit_init(isa_bus, 0x40);
 } else {
 pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq);
+DPRINTF("Created software PIT.\n");
 }
 if (hpet) {
 /* connect PIT to output control line of the HPET */
@@ -1605,10 +1607,11 @@ void ioapic_init_gsi(GSIState *gsi_state, const char 
*parent_name)
 SysBusDevice *d;
 unsigned int i;
 
-if (kvm_irqchip_in_kernel()) {
+if (kvm_ioapic_in_kernel()) {
 dev = qdev_create(NULL, "kvm-ioapic");
 } else {
 dev = qdev_create(NULL, "ioapic");
+DPRINTF("Created software ioapic.\n");
 }
 if (parent_name) {
 object_property_add_child(object_resolve_path(parent_name, NULL),
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 4514cd1..95b40d5 100644
--- a/h

[Qemu-devel] [PATCH v9 4/5] qapi: Move duplicate enum value checks to schema check()

2015-10-29 Thread Eric Blake
Similar to the previous commit, move the detection of a collision
in enum values from parse time to QAPISchemaEnumType.check().
This happens to also detect collisions in union branch names
mapping to the same enum value, even when the names do not
collide case-wise.  So for a decent error message, we have to
determine if the enum is implicit (and if so where the real
collision lies).

Testing this showed that the test union-bad-branch wasn't adding
much: union-clash-branches exposes the error message when branches
directly collide, and union-max exposes the error message when
branches cause an enum collision (union-bad-branch basically
causes an enum collision that would not be a C collision).  Maybe
we should require ALL names to be case-insensitively unique, but
that would be the topic for a different patch.

No change to generated code.

Signed-off-by: Eric Blake 

---
v9: rebase to earlier changes, update commit message, break out
helper _describe() method
v8: rebase to earlier changes; better comments
v7: retitle and improve commit message; earlier subclass patches
avoid problem with detecting 'kind' collision
v6: new patch
---
 scripts/qapi.py | 41 -
 tests/Makefile  |  1 -
 tests/qapi-schema/enum-clash-member.err |  2 +-
 tests/qapi-schema/enum-max-member.err   |  2 +-
 tests/qapi-schema/union-bad-branch.err  |  1 -
 tests/qapi-schema/union-bad-branch.exit |  1 -
 tests/qapi-schema/union-bad-branch.json |  8 --
 tests/qapi-schema/union-bad-branch.out  |  0
 tests/qapi-schema/union-clash-branches.err  |  2 +-
 tests/qapi-schema/union-clash-branches.json |  2 +-
 tests/qapi-schema/union-max.err |  2 +-
 11 files changed, 28 insertions(+), 34 deletions(-)
 delete mode 100644 tests/qapi-schema/union-bad-branch.err
 delete mode 100644 tests/qapi-schema/union-bad-branch.exit
 delete mode 100644 tests/qapi-schema/union-bad-branch.json
 delete mode 100644 tests/qapi-schema/union-bad-branch.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 8e927f7..b5a0fde 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -533,7 +533,6 @@ def check_union(expr, expr_info):
 base = expr.get('base')
 discriminator = expr.get('discriminator')
 members = expr['data']
-values = {'MAX': '(automatic)'}

 # Two types of unions, determined by discriminator.

@@ -593,15 +592,6 @@ def check_union(expr, expr_info):
 "enum '%s'" %
 (key, enum_define["enum_name"]))

-# Otherwise, check for conflicts in the generated enum
-else:
-c_key = camel_to_upper(key)
-if c_key in values:
-raise QAPIExprError(expr_info,
-"Union '%s' member '%s' clashes with '%s'"
-% (name, key, values[c_key]))
-values[c_key] = key
-

 def check_alternate(expr, expr_info):
 name = expr['alternate']
@@ -630,7 +620,6 @@ def check_enum(expr, expr_info):
 name = expr['enum']
 members = expr.get('data')
 prefix = expr.get('prefix')
-values = {'MAX': '(automatic)'}

 if not isinstance(members, list):
 raise QAPIExprError(expr_info,
@@ -641,12 +630,6 @@ def check_enum(expr, expr_info):
 for member in members:
 check_name(expr_info, "Member of enum '%s'" % name, member,
enum_member=True)
-key = camel_to_upper(member)
-if key in values:
-raise QAPIExprError(expr_info,
-"Enum '%s' member '%s' clashes with '%s'"
-% (name, member, values[key]))
-values[key] = member


 def check_struct(expr, expr_info):
@@ -873,8 +856,30 @@ class QAPISchemaEnumType(QAPISchemaType):
 self.values = values
 self.prefix = prefix

+def _describe(self, schema):
+# If the enum is implicit, report the error on behalf of
+# the union or alternate that triggered the enum
+if self.is_implicit():
+owner = schema.lookup_type(self.name[:-4])
+assert owner
+if isinstance(owner, QAPISchemaAlternateType):
+return "Alternate '%s' branch" % owner.name
+else:
+return "Union '%s' branch" % owner.name
+else:
+return "Enum '%s' value" % self.name
+
 def check(self, schema):
-assert len(set(self.values)) == len(self.values)
+# Check for collisions on the generated C enum values
+seen = {c_enum_const(self.name, 'MAX'): '(automatic MAX)'}
+for value in self.values:
+c_value = c_enum_const(self.name, value)
+if c_value in seen:
+raise QAPIExprError(self.info,
+"%s '%s' clashes with '%s'"
+% (self._describe(schema), 

[Qemu-devel] [PATCH v9 2/5] qapi: Detect collisions in C member names

2015-10-29 Thread Eric Blake
Detect attempts to declare two object members that would result
in the same C member name, by keying the 'seen' dictionary off
of the C name rather than the qapi name.  It also requires passing
info through some of the check() methods.

This fixes a previously-broken test, and the resulting error
message demonstrates the utility of the .describe() method added
previously.  No change to generated code.

Signed-off-by: Eric Blake 

---
v9 (now in subset D): rebase to earlier changes, now only one test
affected
v8: rebase to earlier changes
v7: split out error reporting prep and member.c_name() addition
v6: rebase to earlier testsuite and info improvements
---
 scripts/qapi.py| 43 +++---
 tests/qapi-schema/args-name-clash.err  |  1 +
 tests/qapi-schema/args-name-clash.exit |  2 +-
 tests/qapi-schema/args-name-clash.json |  6 ++---
 tests/qapi-schema/args-name-clash.out  |  6 -
 5 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2877e44..00e8452 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -976,19 +976,20 @@ class QAPISchemaObjectType(QAPISchemaType):
 seen = OrderedDict()
 if self._base_name:
 self.base = schema.lookup_type(self._base_name)
-self.base.check_qmp(schema, seen)
+self.base.check_qmp(schema, self.info, seen)
 for m in self.local_members:
-m.check(schema, seen)
+m.check(schema, self.info, seen)
 if self.variants:
-self.variants.check(schema, seen)
+self.variants.check(schema, self.info, seen)
 self.members = seen.values()

 # Check that this type does not introduce QMP collisions into seen
-def check_qmp(self, schema, seen):
+# info is the location providing seen, which is not necessarily self.info
+def check_qmp(self, schema, info, seen):
 self.check(schema)
 assert not self.variants   # not implemented
 for m in self.members:
-m.check(schema, seen)
+m.check(schema, info, seen)

 def is_implicit(self):
 # See QAPISchema._make_implicit_object_type()
@@ -1029,15 +1030,19 @@ class QAPISchemaObjectTypeMember(object):
 assert not self.owner
 self.owner = name

-def check(self, schema, seen):
+def check(self, schema, info, seen):
 # seen is a map of names we must not collide with (either QMP
 # names, when called by ObjectType, or case names, when called
 # by Variant). This method is safe to call over multiple 'seen'.
 assert self.owner
-assert self.name not in seen
 self.type = schema.lookup_type(self._type_name)
 assert self.type
-seen[self.name] = self
+name = c_name(self.name)
+if name in seen:
+raise QAPIExprError(info,
+"%s collides with %s"
+% (self.describe(), seen[name].describe()))
+seen[name] = self

 def c_type(self):
 return self.type.c_type()
@@ -1084,21 +1089,21 @@ class QAPISchemaObjectTypeVariants(object):
 for v in self.variants:
 v.set_owner(name)

-def check(self, schema, seen):
+def check(self, schema, info, seen):
 if self.tag_name:# flat union
-self.tag_member = seen[self.tag_name]
-assert self.tag_member
+self.tag_member = seen[c_name(self.tag_name)]
+assert self.tag_name == self.tag_member.name
 elif seen:   # simple union
 assert self.tag_member in seen.itervalues()
 else:# alternate
-self.tag_member.check(schema, seen)
+self.tag_member.check(schema, info, seen)
 if not isinstance(self.tag_member, QAPISchemaAlternateTypeTag):
 assert isinstance(self.tag_member.type, QAPISchemaEnumType)
 cases = OrderedDict()
 for v in self.variants:
 # Reset seen array for each variant, since QMP names from one
 # branch do not affect another branch, nor add to all_members
-v.check(schema, self.tag_member.type, dict(seen), cases)
+v.check(schema, info, self.tag_member.type, dict(seen), cases)


 class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
@@ -1107,13 +1112,13 @@ class 
QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
 def __init__(self, name, typ):
 QAPISchemaObjectTypeMember.__init__(self, name, typ, False)

-def check(self, schema, tag_type, seen, cases):
+def check(self, schema, info, tag_type, seen, cases):
 # cases is case names we must not collide with
-QAPISchemaObjectTypeMember.check(self, schema, cases)
+QAPISchemaObjectTypeMember.check(self, schema, info, cases)
 if tag_type:
 # seen is QMP names our members must not collide with

[Qemu-devel] [PATCH v9 5/5] qapi: Detect base class loops

2015-10-29 Thread Eric Blake
It should be fairly obvious that qapi base classes need to
form an acyclic graph, since QMP cannot specify the same
key more than once, while base classes are included as flat
members alongside other members added by the child.  But the
old check_member_clash() parser function was not prepared to
check for this, and entered an infinite recursion (at least
until python gives up, complaining about nesting too deep).

Now that check_member_clash() has been recently removed,
attempts at self-inheritance trigger an assertion failure
introduced by commit ac88219a.  The obvious fix is to turn
the assertion into a conditional.

This patch includes both the test and the fix, since the .err
file output for the unfixed case is not useful (particularly
when it was warning about unbounded recursion, as that limit
may be platform-specific).

We don't need to worry about cycles in flat unions (neither
the base nor a variant class can be a union) nor in alternates
(alternate branches cannot themselves be an alternate).

Signed-off-by: Eric Blake 

---
v9: no change
v8: improve commit message
v7: improve commit message
v6: rebase to earlier info changes
---
 scripts/qapi.py   | 6 +-
 tests/Makefile| 1 +
 tests/qapi-schema/base-cycle.err  | 1 +
 tests/qapi-schema/base-cycle.exit | 1 +
 tests/qapi-schema/base-cycle.json | 3 +++
 tests/qapi-schema/base-cycle.out  | 0
 6 files changed, 11 insertions(+), 1 deletion(-)
 create mode 100644 tests/qapi-schema/base-cycle.err
 create mode 100644 tests/qapi-schema/base-cycle.exit
 create mode 100644 tests/qapi-schema/base-cycle.json
 create mode 100644 tests/qapi-schema/base-cycle.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index b5a0fde..f2f7c27 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -942,7 +942,11 @@ class QAPISchemaObjectType(QAPISchemaType):

 # Finish construction, and validate that all members are usable
 def check(self, schema):
-assert self.members is not False# not running in cycles
+if self.members is False:   # check for cycles
+assert self._base_name
+raise QAPIExprError(self.info,
+"Object %s cyclically depends on %s"
+% (self.name, self._base_name))
 if self.members:
 return
 self.members = False# mark as being checked
diff --git a/tests/Makefile b/tests/Makefile
index fc6643a..5927e26 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -252,6 +252,7 @@ qapi-schema += bad-ident.json
 qapi-schema += bad-type-bool.json
 qapi-schema += bad-type-dict.json
 qapi-schema += bad-type-int.json
+qapi-schema += base-cycle.json
 qapi-schema += command-int.json
 qapi-schema += comments.json
 qapi-schema += double-data.json
diff --git a/tests/qapi-schema/base-cycle.err b/tests/qapi-schema/base-cycle.err
new file mode 100644
index 000..e0221b5
--- /dev/null
+++ b/tests/qapi-schema/base-cycle.err
@@ -0,0 +1 @@
+tests/qapi-schema/base-cycle.json:2: Object Base1 cyclically depends on Base2
diff --git a/tests/qapi-schema/base-cycle.exit 
b/tests/qapi-schema/base-cycle.exit
new file mode 100644
index 000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/base-cycle.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/base-cycle.json 
b/tests/qapi-schema/base-cycle.json
new file mode 100644
index 000..2866772
--- /dev/null
+++ b/tests/qapi-schema/base-cycle.json
@@ -0,0 +1,3 @@
+# we reject a loop in base classes
+{ 'struct': 'Base1', 'base': 'Base2', 'data': {} }
+{ 'struct': 'Base2', 'base': 'Base1', 'data': {} }
diff --git a/tests/qapi-schema/base-cycle.out b/tests/qapi-schema/base-cycle.out
new file mode 100644
index 000..e69de29
-- 
2.4.3




[Qemu-devel] [PATCH v9 3/5] qapi: Move duplicate member checks to schema check()

2015-10-29 Thread Eric Blake
With the previous commit, we have two different locations for
detecting member name clashes - one at parse time, and another
at QAPISchema*.check() time.  Consolidate some of the checks
into a single place, which is also in line with our TODO to
eventually move all of the parse time semantic checking into
the newer schema code.  The check_member_clash() function is
no longer needed.

The wording of several error messages has changed, but in many
cases feels like an improvement rather than a regression.  The
recent change (commit 7b2a5c2) to avoid an assertion failure
when a flat union branch name collides with its discriminator
name is also handled nicely by this code; but there is more work
needed before we can detect all collisions in the generated enum
associated with simple union branch names.

No change to generated code.

Signed-off-by: Eric Blake 

---
v9: simplify on top of earlier check() improvements
v8: decide whether to inline members based on union vs. alternate,
not on flat vs. simple, and fix logic to avoid breaking
union-clash-data in the process; add comments; assumes
pull-qapi-2015-10-12 will go in without modifying commit ids
v7: comment improvements, retitle subject
v6: rebase to earlier testsuite improvements, fold in cleanup
of flat-union-clash-type
---
 scripts/qapi.py   | 34 +--
 tests/qapi-schema/alternate-clash.err |  2 +-
 tests/qapi-schema/flat-union-clash-member.err |  2 +-
 tests/qapi-schema/struct-base-clash-deep.err  |  2 +-
 tests/qapi-schema/struct-base-clash.err   |  2 +-
 5 files changed, 5 insertions(+), 37 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 00e8452..8e927f7 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -502,21 +502,6 @@ def check_type(expr_info, source, value, allow_array=False,
 'enum'])


-def check_member_clash(expr_info, base_name, data, source=""):
-base = find_struct(base_name)
-assert base
-base_members = base['data']
-for key in data.keys():
-if key.startswith('*'):
-key = key[1:]
-if key in base_members or "*" + key in base_members:
-raise QAPIExprError(expr_info,
-"Member name '%s'%s clashes with base '%s'"
-% (key, source, base_name))
-if base.get('base'):
-check_member_clash(expr_info, base['base'], data, source)
-
-
 def check_command(expr, expr_info):
 name = expr['command']

@@ -595,15 +580,9 @@ def check_union(expr, expr_info):
 for (key, value) in members.items():
 check_name(expr_info, "Member of union '%s'" % name, key)

-# Each value must name a known type; furthermore, in flat unions,
-# branches must be a struct with no overlapping member names
+# Each value must name a known type
 check_type(expr_info, "Member '%s' of union '%s'" % (key, name),
value, allow_array=not base, allow_metas=allow_metas)
-if base:
-branch_struct = find_struct(value)
-assert branch_struct
-check_member_clash(expr_info, base, branch_struct['data'],
-   " of branch '%s'" % key)

 # If the discriminator names an enum type, then all members
 # of 'data' must also be members of the enum type.
@@ -627,21 +606,12 @@ def check_union(expr, expr_info):
 def check_alternate(expr, expr_info):
 name = expr['alternate']
 members = expr['data']
-values = {}
 types_seen = {}

 # Check every branch
 for (key, value) in members.items():
 check_name(expr_info, "Member of alternate '%s'" % name, key)

-# Check for conflicts in the branch names
-c_key = c_name(key)
-if c_key in values:
-raise QAPIExprError(expr_info,
-"Alternate '%s' member '%s' clashes with '%s'"
-% (name, key, values[c_key]))
-values[c_key] = key
-
 # Ensure alternates have no type conflicts.
 check_type(expr_info, "Member '%s' of alternate '%s'" % (key, name),
value,
@@ -687,8 +657,6 @@ def check_struct(expr, expr_info):
allow_dict=True, allow_optional=True)
 check_type(expr_info, "'base' for struct '%s'" % name, expr.get('base'),
allow_metas=['struct'])
-if expr.get('base'):
-check_member_clash(expr_info, expr['base'], expr['data'])


 def check_keys(expr_elem, meta, required, optional=[]):
diff --git a/tests/qapi-schema/alternate-clash.err 
b/tests/qapi-schema/alternate-clash.err
index a475ab6..604d849 100644
--- a/tests/qapi-schema/alternate-clash.err
+++ b/tests/qapi-schema/alternate-clash.err
@@ -1 +1 @@
-tests/qapi-schema/alternate-clash.json:7: Alternate 'Alt1' member 'a_b' 
clashes with 'a-b'
+tests/qapi-schema/alternate-clash.json:7: 'a_b' (branch of Alt1) collides with 
'a-b' 

[Qemu-devel] [PATCH v9 0/5] qapi collision checking (post-introspection cleanups, subset D)

2015-10-29 Thread Eric Blake
Pending prerequisite: Markus' qapi-next branch (subset B)
git://repo.or.cz/qemu/armbru.git qapi-next
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg06417.html

Pending prerequisite: Subset C
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg06674.html

Also available as a tag at this location:
git fetch git://repo.or.cz/qemu/ericb.git qapi-cleanupv9d

as well as part my qapi branch subject to rebasing:
http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi

v9:
Pick up the remaining patches that were part of Subset B v8 but
dropped in later spins of that subset.  Rebase things on top of
the work to redo the layout of unions and alternates.  Definitely
simpler now; here's a comparison to the earlier v8 tree:

001/5:[0024] [FC] 'qapi: Track owner of each object member'
002/5:[0090] [FC] 'qapi: Detect collisions in C member names'
003/5:[0060] [FC] 'qapi: Move duplicate member checks to schema check()'
004/5:[0053] [FC] 'qapi: Move duplicate enum value checks to schema check()'
005/5:[] [-C] 'qapi: Detect base class loops'

v8 notes:
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg02879.html
Address review comments, including fixing a bug with tracking
branch name collisions. Include a few more simple test cleanups
(4-6), and add another patch (11) that will make converting from
kind=>type easier in a later subset.  More details in per-patch
changelogs.

v7 notes:
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg01387.html
Address comments, including a couple of new commits that made
later patches a bit cleaner.  Backport diff gets a bit confused
by a couple of patch titles changing.

v6 notes:
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg00562.html
This is patches 11-16 of my v5 series; it has grown a bit with
splitting some patches and adding some others.  I suspect that
12/12 on this series will be discarded, but am including it because
it was split from v5 content.

Not much review comments other than on the original 11/46, but there
is enough churn due to rebasing that it's now easier to review this
version than plowing through v5.

Subset C (and more?) will come later.

In v5:
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg05410.html
I _did_ rearrange patches to try and group related features:

1-2: Groundwork cleanups
3-5: Add more test cases
6-16: Front-end cleanups
17-18: Introspection output cleanups
19-20: 'alternate' type cleanups
21-29: qapi visitor cleanups
30-45: qapi-ify netdev_add
46: add qapi shorthand for flat unions

Lots of fixes based on additional testing, and rebased to
track other changes that happened in the meantime.  The series
is huge; I can split off smaller portions as requested.

In v4:
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg02580.html
add some more clean up patches
rebase to Markus' recent work
pull in part of Zoltán's work to make netdev_add a flat union,
further enhancing it to be introspectible

I might be able to rearrange some of these patches, or separate
it into smaller independent series, if requested; but I'm
posting now to get review started.

In v3:
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02059.html
redo cleanup of dealloc of partial struct
add patches to make all visit_type_*() avoid leaks on failure
add patches to allow boxed command arguments and events

In v2:
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg00900.html
rebase to Markus' v3 series
rework how comments are emitted for fields inherited from base
additional patches added for deleting colliding 'void *data'
documentation updates to match code changes

v1 was here:
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg05266.html
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg05325.html

Eric Blake (5):
  qapi: Track owner of each object member
  qapi: Detect collisions in C member names
  qapi: Move duplicate member checks to schema check()
  qapi: Move duplicate enum value checks to schema check()
  qapi: Detect base class loops

 scripts/qapi.py| 170 -
 tests/Makefile |   2 +-
 tests/qapi-schema/alternate-clash.err  |   2 +-
 tests/qapi-schema/args-name-clash.err  |   1 +
 tests/qapi-schema/args-name-clash.exit |   2 +-
 tests/qapi-schema/args-name-clash.json |   6 +-
 tests/qapi-schema/args-name-clash.out  |   6 -
 tests/qapi-schema/base-cycle.err   |   1 +
 .../{union-bad-branch.exit => base-cycle.exit} |   0
 tests/qapi-schema/base-cycle.json  |   3 +
 .../{union-bad-branch.out => base-cycle.out}   |   0
 tests/qapi-schema/enum-clash-member.err|   2 +-
 tests/qapi-schema/enum-max-member.err  |   2 +-
 tests/qapi-schema/flat-union-clash-member.err  |   2 +-
 tests/qapi-schema/qapi-schema-test.out |   8 +-
 tests/qapi-schema/struct-base-clash-deep.err

[Qemu-devel] [PATCH v9 1/5] qapi: Track owner of each object member

2015-10-29 Thread Eric Blake
Future commits will migrate semantic checking away from parsing
and over to the various QAPISchema*.check() methods.  But to
report an error message about an incorrect semantic use of a
member of an object type, it helps to know which type, command,
or event owns the member.  In particular, when a member is
inherited from a base type, it is desirable to associate the
member name with the base type (and not the type calling
member.check()).

Rather than packing additional information into the seen array
passed to each member.check() (as in seen[m.name] = {'member':m,
'owner':type}), it is easier to have each member track the name
of the owner type in the first place (keeping things simpler
with the existing seen[m.name] = m).  The new member.owner field
is set via a new set_owner() method, called when registering
the members and variants arrays with an object or variant type.
Track only a name, and not the actual type object, to avoid
creating a circular python reference chain.

Note that the set_owner() method for variants has to know
whether the tag_member field is owned elsewhere (by the base of
flat unions, and the local_members of simple unions) or must be
set directly (for alternates); it decides this based on the
subclass of the tag_member field.

The source information is intended for human consumption in
error messages, and a new describe() method is added to access
the resulting information.  For example, given the qapi:
  { 'command': 'foo', 'data': { 'string': 'str' } }
an implementation of visit_command() that calls
  arg_type.members[0].describe()
will see "'string' (argument of foo)".

To make the human-readable name of implicit types work without
duplicating efforts, the describe() method has to reverse the
name of implicit types, via the helper _pretty_owner(), plus a
tweak to report event data separately from command arguments.

No change to generated code.

Signed-off-by: Eric Blake 

---
v9 (now in subset D): rebase to earlier changes, hoist 'role' to top
of class, split out _pretty_helper(), manage owner when tag_member
appears as part of local_members for unions
v8: don't munge implicit type names [except for event data], and
instead make describe() create nicer messages. Add set_owner(), and
use field 'role' instead of method _describe()
v7: total rewrite: rework implicit object names, assign owner
when initializing owner type rather than when creating member
python object
v6: rebase on new lazy array creation and simple union 'type'
motion; tweak commit message
---
 scripts/qapi.py| 46 +++---
 tests/qapi-schema/qapi-schema-test.out |  8 +++---
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 0eb5d9a..2877e44 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -957,8 +957,10 @@ class QAPISchemaObjectType(QAPISchemaType):
 assert base is None or isinstance(base, str)
 for m in local_members:
 assert isinstance(m, QAPISchemaObjectTypeMember)
-assert (variants is None or
-isinstance(variants, QAPISchemaObjectTypeVariants))
+m.set_owner(name)
+if variants is not None:
+assert isinstance(variants, QAPISchemaObjectTypeVariants)
+variants.set_owner(name)
 self._base_name = base
 self.base = None
 self.local_members = local_members
@@ -1011,6 +1013,8 @@ class QAPISchemaObjectType(QAPISchemaType):


 class QAPISchemaObjectTypeMember(object):
+role = 'member'
+
 def __init__(self, name, typ, optional):
 assert isinstance(name, str)
 assert isinstance(typ, str)
@@ -1019,11 +1023,17 @@ class QAPISchemaObjectTypeMember(object):
 self._type_name = typ
 self.type = None
 self.optional = optional
+self.owner = None
+
+def set_owner(self, name):
+assert not self.owner
+self.owner = name

 def check(self, schema, seen):
 # seen is a map of names we must not collide with (either QMP
 # names, when called by ObjectType, or case names, when called
 # by Variant). This method is safe to call over multiple 'seen'.
+assert self.owner
 assert self.name not in seen
 self.type = schema.lookup_type(self._type_name)
 assert self.type
@@ -1032,6 +1042,25 @@ class QAPISchemaObjectTypeMember(object):
 def c_type(self):
 return self.type.c_type()

+def _pretty_owner(self):
+# See QAPISchema._make_implicit_object_type() - reverse the
+# mapping there to create a nice human-readable description
+owner = self.owner
+if owner.startswith(':obj-'):
+owner = owner[5:]
+if owner.endswith('-arg'):
+return '(argument of %s)' % owner[:-4]
+elif owner.endswith('-data'):
+return '(data of %s)' % owner[:-5]
+else:
+assert owner.en

Re: [Qemu-devel] [PATCH] configure: workaround for Clang 3.5.0

2015-10-29 Thread John Snow


On 10/29/2015 04:22 PM, John Snow wrote:
> Clang++ 3.5 on Fedora 22 appears to have difficulty tolerating
> D_FORTIFY_SOURCE for certain glibc headers, such as stdio.
> 
> This interferes, currently, with any arm target build.
> 
> Work around this by disabling FORTIFY_SOURCE for clang builds
> if a problem is observed.
> 
> Newer versions of clang such as 3.5.2 (As seen in debian-testing)
> or 3.7.0 (As seen in Fedora 23 Beta) are unaffected and will not
> trigger this workaround.
> 
> Signed-off-by: John Snow 
> ---

As a meta-cover-letter, this fix is a little weird in that it will
disable FORTIFY_SOURCE (silently!) for non-debug builds. Not great.

(Maybe I could have it fail and print a warning encouraging users to
either use --enable-debug or --disable-fortify-source?)

Still, It'd be nice to have Clang builds working out of the box for ARM
builds. It just so happens that ARM is the only target that happens to
trip this specific unfortunate chain of events.

Is it sane to check for clang-and-arm-targets only? Maybe it's a moot
point -- newer (and older, I believe) versions of Clang won't trigger
this at all.

Anyway, see these links (Dredged up by Laszlo Ersek, thanks!)
https://llvm.org/bugs/show_bug.cgi?id=7219
https://llvm.org/bugs/show_bug.cgi?id=16821
https://llvm.org/bugs/show_bug.cgi?id=23277#c2

Here's a good takeaway quote:

'Also, _FORTIFY_SOURCE + glibc + clang is not supported and does not
work (for instance, it relies on __builtin_va_pack_len and friends,
which we have no intention of supporting), so glibc compatibility is
unlikely to be a strong motivator for a change here.'

So long story short, we have a weird hacky workaround where we disable
FORTIFY_SOURCE for compilers that don't appear to be able to support it.

--js

>  configure | 25 -
>  1 file changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/configure b/configure
> index 7a1d08d..7abfcc3 100755
> --- a/configure
> +++ b/configure
> @@ -107,6 +107,11 @@ compile_object() {
>do_cc $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
>  }
>  
> +compile_cxx_object() {
> +  local_cflags="$1"
> +  do_cxx $QEMU_CXXFLAGS $local_cflags -c -o $TMPO $TMPC
> +}
> +
>  compile_prog() {
>local_cflags="$1"
>local_ldflags="$2"
> @@ -4436,13 +4441,31 @@ if ! compile_object "-Werror"; then
>  fi
>  
>  ##
> +# Test that we can use FORTIFY_SOURCE,
> +# which might break Clang.
> +
> +if test "$debug" = "no"; then
> +  cat > $TMPC << EOF
> +#include 
> +int main(int argc, char*argv[]) {
> +  fprintf(stdout, "Hello World\n");
> +  return 0;
> +}
> +EOF
> +
> +  if ! compile_cxx_object "-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2"; then
> +  fortify_source="no";
> +  fi
> +fi
> +
> +##
>  # End of CC checks
>  # After here, no more $cc or $ld runs
>  
>  if test "$gcov" = "yes" ; then
>CFLAGS="-fprofile-arcs -ftest-coverage -g $CFLAGS"
>LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
> -elif test "$debug" = "no" ; then
> +elif test "$debug" = "no" && test "$fortify_source" != "no" ; then
>CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
>  fi
>  
> 



[Qemu-devel] [PATCH] configure: workaround for Clang 3.5.0

2015-10-29 Thread John Snow
Clang++ 3.5 on Fedora 22 appears to have difficulty tolerating
D_FORTIFY_SOURCE for certain glibc headers, such as stdio.

This interferes, currently, with any arm target build.

Work around this by disabling FORTIFY_SOURCE for clang builds
if a problem is observed.

Newer versions of clang such as 3.5.2 (As seen in debian-testing)
or 3.7.0 (As seen in Fedora 23 Beta) are unaffected and will not
trigger this workaround.

Signed-off-by: John Snow 
---
 configure | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 7a1d08d..7abfcc3 100755
--- a/configure
+++ b/configure
@@ -107,6 +107,11 @@ compile_object() {
   do_cc $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC
 }
 
+compile_cxx_object() {
+  local_cflags="$1"
+  do_cxx $QEMU_CXXFLAGS $local_cflags -c -o $TMPO $TMPC
+}
+
 compile_prog() {
   local_cflags="$1"
   local_ldflags="$2"
@@ -4436,13 +4441,31 @@ if ! compile_object "-Werror"; then
 fi
 
 ##
+# Test that we can use FORTIFY_SOURCE,
+# which might break Clang.
+
+if test "$debug" = "no"; then
+  cat > $TMPC << EOF
+#include 
+int main(int argc, char*argv[]) {
+  fprintf(stdout, "Hello World\n");
+  return 0;
+}
+EOF
+
+  if ! compile_cxx_object "-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2"; then
+  fortify_source="no";
+  fi
+fi
+
+##
 # End of CC checks
 # After here, no more $cc or $ld runs
 
 if test "$gcov" = "yes" ; then
   CFLAGS="-fprofile-arcs -ftest-coverage -g $CFLAGS"
   LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
-elif test "$debug" = "no" ; then
+elif test "$debug" = "no" && test "$fortify_source" != "no" ; then
   CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
 fi
 
-- 
2.4.3




[Qemu-devel] [RFC v2] target-arm: Add and use symbolic names for register banks

2015-10-29 Thread Soren Brinkmann
Add BANK_ #defines to index banked registers.

Suggested-by: Peter Maydell 
Signed-off-by: Soren Brinkmann 
---
v2:
 - move #defines from cpu.h to internals.h
 - drop ARM_ prefix in #defines
---
 target-arm/helper.c| 37 ++---
 target-arm/internals.h | 16 +---
 target-arm/kvm32.c | 34 +-
 target-arm/op_helper.c |  8 
 4 files changed, 56 insertions(+), 39 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1966f9c04502..4ecae61197c7 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3130,7 +3130,8 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
 { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
   .type = ARM_CP_ALIAS,
   .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
-  .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[1]) },
+  .access = PL1_RW,
+  .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
 /* We rely on the access checks not allowing the guest to write to the
  * state field when SPSel indicates that it's being used as the stack
  * pointer.
@@ -3299,23 +3300,28 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
 { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
   .type = ARM_CP_ALIAS,
   .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
-  .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[6]) },
+  .access = PL2_RW,
+  .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
 { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
   .type = ARM_CP_ALIAS,
   .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
-  .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[4]) },
+  .access = PL2_RW,
+  .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) },
 { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
   .type = ARM_CP_ALIAS,
   .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
-  .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[2]) },
+  .access = PL2_RW,
+  .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) },
 { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
   .type = ARM_CP_ALIAS,
   .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
-  .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[3]) },
+  .access = PL2_RW,
+  .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) },
 { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
   .type = ARM_CP_ALIAS,
   .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
-  .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[5]) },
+  .access = PL2_RW,
+  .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
 { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
   .access = PL2_RW, .writefn = vbar_write,
@@ -3552,7 +3558,8 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
 { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
   .type = ARM_CP_ALIAS,
   .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
-  .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, banked_spsr[7]) },
+  .access = PL3_RW,
+  .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) },
 { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
   .access = PL3_RW, .writefn = vbar_write,
@@ -5183,21 +5190,21 @@ int bank_number(int mode)
 switch (mode) {
 case ARM_CPU_MODE_USR:
 case ARM_CPU_MODE_SYS:
-return 0;
+return BANK_USRSYS;
 case ARM_CPU_MODE_SVC:
-return 1;
+return BANK_SVC;
 case ARM_CPU_MODE_ABT:
-return 2;
+return BANK_ABT;
 case ARM_CPU_MODE_UND:
-return 3;
+return BANK_UND;
 case ARM_CPU_MODE_IRQ:
-return 4;
+return BANK_IRQ;
 case ARM_CPU_MODE_FIQ:
-return 5;
+return BANK_FIQ;
 case ARM_CPU_MODE_HYP:
-return 6;
+return BANK_HYP;
 case ARM_CPU_MODE_MON:
-return 7;
+return BANK_MON;
 }
 g_assert_not_reached();
 }
diff --git a/target-arm/internals.h b/target-arm/internals.h
index 412827bcbf62..347998c8bef9 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -25,6 +25,16 @@
 #ifndef TARGET_ARM_INTERNALS_H
 #define TARGET_ARM_INTERNALS_H
 
+/* register banks for CPU modes */
+#define BANK_USRSYS 0
+#define BANK_SVC1
+#define BANK_ABT2
+#define BANK_UND3
+#define BANK_IRQ4
+#define BANK_FIQ5
+#define BANK_HYP6
+#define BANK_MON7
+
 static inline bool excp_is_internal(int excp)
 {
 /* Return true if this exception number represents a QEMU-internal
@@ -91,9 +101,9 @@ static inline void arm_log_exception(int idx)
 static inline unsigned int aarch64_banked_spsr_index(unsigned int 

Re: [Qemu-devel] [PATCH v4 for 2.5 0/3] qga: non-blocking fd cleanups

2015-10-29 Thread Michael Roth
Quoting Denis V. Lunev (2015-10-28 10:13:54)
> This patchset is reincarnation of one patch discussed in the scope of
> QEMU 2.4 and rejected for that time. Actually we should use
> non-blocking descriptors in QGA on Windows in guest-file-open exactly
> like was done for Posix.
> 
> Changes from v3:
> - handle_set_nonblocking now is local function in qga/commands-win32.c
>   It works only in one way - set handle nonblocking.
> 
> Changes from v2:
> - added fix for wrong argument to CloseHandle
> - switched setting non-block for pipes to use separate function
> 
> Changes from v1:
> - call to qemu_fd_register is moved to a proper place
> - moved declaration of opt to a proper place
> 
> Signed-off-by: Denis V. Lunev 
> Signed-off-by: Olga Krishtal 
> CC: Yuri Pudgorodskiy 
> CC: Michael Roth 
> 
> Denis V. Lunev (1):
>   qga: drop hand-made guest_file_toggle_flags helper
> 
> Olga Krishtal (2):
>   qga: fixed CloseHandle in qmp_guest_file_open
>   qga: set file descriptor in qmp_guest_file_open non-blocking on Win32

Thanks, applied to qga tree:

  https://github.com/mdroth/qemu/commits/qga

> 
>  qga/commands-posix.c | 27 ++-
>  qga/commands-win32.c | 29 -
>  2 files changed, 30 insertions(+), 26 deletions(-)
> 
> -- 
> 2.1.4
> 




Re: [Qemu-devel] [PATCH 00/40] Patch Round-up for stable 2.4.1, freeze on 2015-10-29

2015-10-29 Thread Michael Roth
Quoting Markus Armbruster (2015-10-22 03:01:32)
> I'm afraid
> 
> 2d0583f qmp: Fix device-list-properties not to crash for abstract device
> 2874c65 qdev: Protect device-list-properties against broken devices
> 55b4efb Revert "qdev: Use qdev_get_device_class() for -device ,help"
> 
> unmask a bunch of device model bugs, so you need to pick their fixes,
> too:
> 
> ac98fa8 update-linux-headers: Rename SW_MAX to SW_MAX_
> c6047e9 virtio-input: Fix device introspection on non-Linux hosts
> 2e2b8eb memory: allow destroying a non-empty MemoryRegion
> 81e0ab4 hw: do not pass NULL to memory_region_init from instance_init
> c710440 macio: move DBDMA_init from instance_init to realize
> 
> To check everything's sane, you can pick
> 
> e253c28 tests: Fix how qom-test is run
> 5fb48d9 libqtest: New hmp() & friends
> 2d1abb8 device-introspect-test: New, covering device introspection
> 
> and run make check.
> 
> I apologize for not communicating this better in the commit messages.
> 

Thanks for the heads up, all suggested patches applied and passing unit test.




Re: [Qemu-devel] [PULL v3 00/14] QMP and QObject patches

2015-10-29 Thread Eric Blake
On 10/29/2015 12:33 PM, Markus Armbruster wrote:

>> Still doesn't build with old glib:
>>
>> In file included from /Users/pm215/src/qemu-for-merges/qga/commands.c:14:
>> In file included from
>> /Users/pm215/src/qemu-for-merges/qga/guest-agent-core.h:14:
>> In file included from 
>> /Users/pm215/src/qemu-for-merges/include/qemu-common.h:25:
>> /Users/pm215/src/qemu-for-merges/include/glib-compat.h:172:47: error:
>> expected ';' after expression
>> g_hash_table_replace(hash_table, key, key)
>>   ^
>>   ;
>>
>> I did a trial build with the typo fixed, and that is OK, so this
>> should be the last fix required, I think.
> 
> Hand me the brown paper bag...

And me, for letting that slip by review even when I caught 'add (' on
the line above.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v3 4/5] xlnx-zynqmp: Connect the SPI devices

2015-10-29 Thread Peter Crosthwaite
On Thu, Oct 29, 2015 at 10:45 AM, Alistair Francis
 wrote:
> On Thu, Oct 29, 2015 at 1:27 AM, Frederic Konrad
>  wrote:
>> On 29/10/2015 03:00, Peter Crosthwaite wrote:
>>> On Wed, Oct 28, 2015 at 10:32 AM, Alistair Francis <
>>> alistair.fran...@xilinx.com> wrote:
>>>
 Connect the Xilinx SPI device to the ZynqMP model.


>>> "devices"
>>>
>>>
 Signed-off-by: Alistair Francis 
 ---
 V3:
  - Expose the SPI Bus as part of the SoC device
 V2:
  - Don't connect the SPI flash to the SoC

  hw/arm/xlnx-zynqmp.c | 37 +
  include/hw/arm/xlnx-zynqmp.h |  4 
  2 files changed, 41 insertions(+)

 diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
 index b36ca3d..5671d7a 100644
 --- a/hw/arm/xlnx-zynqmp.c
 +++ b/hw/arm/xlnx-zynqmp.c
 @@ -48,6 +48,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
  21, 22,
  };

 +static const uint64_t spi_addr[XLNX_ZYNQMP_NUM_SPIS] = {
 +0xFF04, 0xFF05,
 +};
 +
 +static const int spi_intr[XLNX_ZYNQMP_NUM_SPIS] = {
 +19, 20,
 +};
 +
  typedef struct XlnxZynqMPGICRegion {
  int region_index;
  uint32_t address;
 @@ -97,6 +105,12 @@ static void xlnx_zynqmp_init(Object *obj)

  object_initialize(&s->sata, sizeof(s->sata), TYPE_SYSBUS_AHCI);
  qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
 +
 +for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
 +object_initialize(&s->spi[i], sizeof(s->spi[i]),
 +  TYPE_XILINX_SPIPS);
 +qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
 +}
  }

  static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
 @@ -258,6 +272,29 @@ static void xlnx_zynqmp_realize(DeviceState *dev,
 Error **errp)

  sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, SATA_ADDR);
  sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, gic_spi[SATA_INTR]);
 +
 +for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
 +BusState *spi_bus;
 +char bus_name[6];
 +
 +object_property_set_int(OBJECT(&s->spi[i]), XLNX_ZYNQMP_NUM_SPIS,
 +"num-busses", &error_abort);

>>> The number of busses-per-controller is unrelated to the number of
>>> controllers. Setting num_busses != 1 is primarily a QSPI thing, so should
>>> this just default to 1? I think you can drop this setter completely.
>
> True, but see below for a problem.
>
>>>
>>>
 +object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
 &err);
 +if (err) {
 +error_propagate(errp, err);
 +return;
 +}
 +
 +sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_addr[i]);
 +sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
 +   gic_spi[spi_intr[i]]);
 +
 +snprintf(bus_name, 6, "spi%d", i);
 +spi_bus = qdev_get_child_bus(DEVICE(&s->spi), bus_name);
 +
 +/* Add the SPI buses to the SoC child bus */
 +QLIST_INSERT_HEAD(&dev->child_bus, spi_bus, sibling);

>>> Nice! That is pretty simple in the end. One, question though, what happen
>>> with info qtree? Do you get doubles because the bus is double parented?
>
> I don't see the double parent problem, but I do see another problem.
> I was doing it a little wrong with the multiple buses.
>
> When I assign the SPI bus to the SoC, the more recent one replaces the
> previous one. I didn't notice it before because I had two buses (which
> meant they had different names) so it ended up working.
>

I dont thinks this would have functioned though, as it would be 1st
bus of 1st controller and 2nd bus of 2nd controller.

> Now with only one bus per I2C they both have the same name and conflict.
>
> I can't change the name of the bus either, so this is a bit of a problem.
>

Can we add this renaming capability? I think it is the right solution.

Regards,
Peter

> I can't see a way around this, while still assigning the buses to the
> SoC. I guess the best option would be to not just take the first match
> when calling qdev_get_child_bus(). Which would mean implementing that
> function manually. How does that sound?
>
> Thanks,
>
> Alistair
>
>>>
>>> I think this concept also might apply to the DP/DPDMA work, where the
>>> display port (or AUX bus?) should be put on the SoC container. Then the
>>> machine model (ep108) is responsible for detecting if the user wants a
>>> display and connecting it. I.e. the DP controller shouldn't be doing the UI
>>> init.
>>
>> You mean get the AUX and I2C bus here and connect the edid and the dpcd?
>> I can take a look.
>>
>> Fred
>>>
 +}
  }

  static Property xlnx_zynqmp_props[] = {
 diff --git a/include/hw/arm/xlnx-z

Re: [Qemu-devel] [PATCH] monitor: Plug memory leak on QMP error

2015-10-29 Thread Luiz Capitulino
On Thu, 29 Oct 2015 17:23:43 +0100
Markus Armbruster  wrote:

> Luiz Capitulino  writes:
> 
> > On Thu, 29 Oct 2015 12:15:09 +0100
> > Markus Armbruster  wrote:
> >
> >> Leak introduced in commit 8a4f501..710aec9, v2.4.0.
> >> 
> >> Signed-off-by: Markus Armbruster 
> >
> > Reviewed-by: Luiz Capitulino 
> 
> Thanks!
> 
> > I think this can go through your tree?
> 
> Yes, along with the json-streamer work.

Do you need my review for that one? It's been ages that I don't
look at that code, I'm not sure it's going to be that worthwhile.



Re: [Qemu-devel] [PULL v3 00/14] QMP and QObject patches

2015-10-29 Thread Markus Armbruster
Peter Maydell  writes:

> On 29 October 2015 at 14:32, Markus Armbruster  wrote:
>> The following changes since commit 7bc8e0c967a4ef77657174d28af775691e18b4ce:
>>
>>   Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into
>> staging (2015-10-29 09:49:52 +)
>>
>> are available in the git repository at:
>>
>>   git://repo.or.cz/qemu/armbru.git tags/pull-monitor-2015-10-29
>>
>> for you to fetch changes up to f6724b5b1b8fb1ca76b3df10d80415c206e2c4b9:
>>
>>   docs: Document QMP event rate limiting (2015-10-29 14:37:34 +0100)
>>
>> 
>> QMP and QObject patches
>>
>
> Still doesn't build with old glib:
>
> In file included from /Users/pm215/src/qemu-for-merges/qga/commands.c:14:
> In file included from
> /Users/pm215/src/qemu-for-merges/qga/guest-agent-core.h:14:
> In file included from 
> /Users/pm215/src/qemu-for-merges/include/qemu-common.h:25:
> /Users/pm215/src/qemu-for-merges/include/glib-compat.h:172:47: error:
> expected ';' after expression
> g_hash_table_replace(hash_table, key, key)
>   ^
>   ;
>
> I did a trial build with the typo fixed, and that is OK, so this
> should be the last fix required, I think.

Hand me the brown paper bag...



Re: [Qemu-devel] [PATCH 3/4] check-qjson: Add test for JSON nesting depth limit

2015-10-29 Thread Markus Armbruster
Eric Blake  writes:

> On 10/29/2015 06:44 AM, Markus Armbruster wrote:
>> This would have prevented the regression mentioned in the previous
>> commit.
>> 
>> Signed-off-by: Markus Armbruster 
>> ---
>>  tests/check-qjson.c | 29 +
>>  1 file changed, 29 insertions(+)
>
> Better late than never.
>
>> +++ b/tests/check-qjson.c
>> @@ -1484,6 +1484,34 @@ static void unterminated_literal(void)
>>  g_assert(obj == NULL);
>>  }
>>  
>> +static char *make_nest(char *buf, size_t cnt)
>> +{
>> +int i;
>> +
>> +for (i = 0; i < cnt - 1; i++) {
>> +buf[i] = '[';
>> +buf[2 * cnt - i - 1] = ']';
>> +}
>> +buf[cnt - 1] = '{';
>> +buf[cnt] = '}';
>> +buf[2 * cnt] = 0;
>> +return buf;
>> +}
>
> So buf must be at least 2*cnt+1 bytes long.  (Function is static, so
> lack of comments don't hurt too badly).  For a cnt of 3 (buffer size at
> least 7), this creates "[[{}]]".  Larger cnt adds more outer [] pairs.
> The mixed content proves that patch 1/4 covers the combined limit of []
> and {} when counting nesting.
>
> Minor optimization - make the for loop bound be 'i < cnt - 2', so you
> aren't writing [] in the middle just to rewrite it to {} after the loop
> (works as long as caller never passes cnt == 1, which happens to be the
> case).

The loop's first assignment fills 0..cnt-2 inclusive, the second one
fills 2*cnt-1..(2*cnt-1)-(cnt-2) = 2*cnt-1..cnt+1 inclusive.

If I need to respin, I'll change to a pair of memset().

>> +static void limits_nesting(void)
>> +{
>> +enum { max_nesting = 1024 }; /* see qobject/json-streamer.c */
>> +char buf[2 * (max_nesting + 1) + 1];
>> +QObject *obj;
>> +
>> +obj = qobject_from_json(make_nest(buf, max_nesting));
>> +g_assert(obj != NULL);
>> +qobject_decref(obj);
>
> Proves that we can hit our max,
>
>> +
>> +obj = qobject_from_json(make_nest(buf, max_nesting + 1));
>> +g_assert(obj == NULL);
>
> and that we gracefully diagnose one beyond max.
>
>> +}
>> +
>>  int main(int argc, char **argv)
>>  {
>>  g_test_init(&argc, &argv, NULL);
>> @@ -1519,6 +1547,7 @@ int main(int argc, char **argv)
>>  g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
>>  g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
>>  g_test_add_func("/errors/unterminated/literal", unterminated_literal);
>> +g_test_add_func("/errors/limits/nesting", limits_nesting);
>>  
>>  return g_test_run();
>>  }
>> 
>
> Reviewed-by: Eric Blake 



Re: [Qemu-devel] [PATCH 4/4] json-streamer: Limit number of tokens in addition to total size

2015-10-29 Thread Markus Armbruster
Eric Blake  writes:

> On 10/29/2015 06:44 AM, Markus Armbruster wrote:
>> Commit 29c75dd "json-streamer: limit the maximum recursion depth and
>> maximum token count" attempts to guard against excessive heap usage by
>> limiting total token size (it says "token count", but that's a lie).
>> 
>> Total token size is a rather imprecise predictor of heap usage: many
>> small tokens use more space than few large tokens with the same input
>> size, because there's a constant per-token overhead.
>> 
>> Tighten this up: limit the token count to 128Ki.
>> 
>> If you think 128Ki is too stingy: check-qjson's large_dict test eats a
>> sweet 500MiB and pegs a core for four minutes on my machine to parse
>> ~100K tokens.  Absurdly wasteful.
>
> Sounds like we have some quadratic (or worse) scaling in the parser.
> Worth fixing some day, but I also agree that we don't have to tackle it
> in this series.

I believe it's linear with a criminally negligent constant (several KiB
per token).  The first hog is actually fairly obvious: we use on QDict
per token.

> I'm assuming you temporarily patched check-qjson to use larger constants
> when you hit your ~100K token testing?  Because I am definitely seeing a
> lot of execution time spent on large_dict when running tests/check-qjson
> by hand, in relation to all the other tests of that file, but not
> minutes worth.  Care to post the diff you played with?

I tested on a slow machine.

>> Signed-off-by: Markus Armbruster 
>> ---
>>  qobject/json-streamer.c | 2 ++
>>  1 file changed, 2 insertions(+)
>
> Reviewed-by: Eric Blake 

Thanks!



[Qemu-devel] [PULL 06/12] virtio-blk: switch off scsi-passthrough by default

2015-10-29 Thread Stefan Hajnoczi
From: Cornelia Huck 

Devices that are compliant with virtio-1 do not support scsi
passthrough any more (and it has not been a recommended setup
anyway for quite some time). To avoid having to switch it off
explicitly in newer qemus that turn on virtio-1 by default, let's
switch the default to scsi=false for 2.5.

Signed-off-by: Cornelia Huck 
Message-id: 1444991154-79217-4-git-send-email-cornelia.h...@de.ibm.com
Signed-off-by: Stefan Hajnoczi 
---
 hw/block/virtio-blk.c | 2 +-
 include/hw/compat.h   | 6 +-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 3e230de..45a24e4 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -972,7 +972,7 @@ static Property virtio_blk_properties[] = {
 DEFINE_PROP_STRING("serial", VirtIOBlock, conf.serial),
 DEFINE_PROP_BIT("config-wce", VirtIOBlock, conf.config_wce, 0, true),
 #ifdef __linux__
-DEFINE_PROP_BIT("scsi", VirtIOBlock, conf.scsi, 0, true),
+DEFINE_PROP_BIT("scsi", VirtIOBlock, conf.scsi, 0, false),
 #endif
 DEFINE_PROP_BIT("request-merging", VirtIOBlock, conf.request_merging, 0,
 true),
diff --git a/include/hw/compat.h b/include/hw/compat.h
index 095de5d..93e71af 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -2,7 +2,11 @@
 #define HW_COMPAT_H
 
 #define HW_COMPAT_2_4 \
-/* empty */
+{\
+.driver   = "virtio-blk-device",\
+.property = "scsi",\
+.value= "true",\
+},
 
 #define HW_COMPAT_2_3 \
 {\
-- 
2.4.3




Re: [Qemu-devel] [PATCH v2 0/8] Add system_powerdown support on ARM for ACPI and DT

2015-10-29 Thread Wei Huang
On 10/29/2015 09:27 AM, Shannon Zhao wrote:
> ACPI SPEC 5.0 defines GPIO-signaled ACPI Events for Hardware-reduced
> platforms(like ARM). It uses GPIO pin to trigger an event to the guest.
> For QEMU, here we add PL061 GPIO controller and use PIN 3 for
> system_powerdown, reserving PIN 0, 1, 2 for PCI hotplug, CPU hotplug and
> memory hotplug.
> 
> This patchset adds system_powerdown support on ARM through both ACPI and
> DT ways. It adds a GPIO controller(here is PL061) in machine virt and
> uses GPIO-singled event for ACPI while gpio-keys for DT. It can be
> fetched from [1] and has been tested for the guests starting by ACPI or
> DT while guests use systemd or acpid.
> 
> a) ACPI way. Since Graeme send a patchset to make ACPI on ARM64 support
> amba device[2], it could use PL061 directly without modification to its
> kernel driver code. In addition, we should use ACPI to start VM,
> referring to below script. QEMU_EFI.fd can be fetched from [3]. 

Hi Shannon,

Thanks for re-sending it. This is a desired feature because we don't
want to rely on tricks (such as guest-agent) for external VM power
management. I have tested V1 recently by back-porting to my in-house
kernel; it worked well.

I will help review this new version.

Thanks,
-Wei

> 
> qemu-system-aarch64 \
> -smp 1 -m 1024 -M virt \
> -cpu cortex-a57 -nographic \
> -monitor telnet::,server,nowait \
> -bios QEMU_EFI.fd \
> -kernel Image \
> -initrd guestfs.cpio.gz \
> -append "rdinit=/sbin/init console=ttyAMA0 mem=512M root=/dev/ram 
> earlycon=pl011,0x900 rw acpi=force"
> 
> b) DT way. Start vm as usual.
> 
> qemu-system-aarch64 \
> -smp 1 -m 1024 -M virt \
> -cpu cortex-a57 -nographic \
> -monitor telnet::,server,nowait \
> -kernel Image \
> -initrd guestfs.cpio.gz \
> -append "rdinit=/sbin/init console=ttyAMA0 mem=512M root=/dev/ram 
> earlycon=pl011,0x900 rw"
> 
> Guest internal setup:
> If your guest FS uses systemd, you should check file
> /lib/udev/rules.d/70-power-switch.rules and add the following line in it
> if it doesn't exist.
> 
> SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="platform",
> ATTRS{keys}=="116", TAG+="power-switch"
> 
> If your guest FS uses acpid, you should check it has
> /etc/acpi/powerbtn.sh and /etc/acpi/events/powerbtn. Refer to [4] for
> the setup of acpid.
> 
> Thanks,
> Shannon
> 
> [1] 
> https://git.linaro.org/people/shannon.zhao/qemu.git/shortlog/refs/heads/PowerButton_v2
> [2] https://lkml.org/lkml/2015/9/30/392
> [3] http://people.linaro.org/~shannon.zhao/ACPI_ARM/QEMU_EFI.fd
> [4] https://wiki.linaro.org/LEG/Engineering/Kernel/ACPI/GPIOPowerButton
> 
> Changes since v1:
> * rewrite GPIO Connection Descriptor (Michael)
> 
> Shannon Zhao (8):
>   hw/arm/virt: Add a GPIO controller
>   hw/arm/virt-acpi-build: Add GPIO controller in ACPI DSDT table
>   hw/arm/virt-acpi-build: Add power button device in ACPI DSDT table
>   hw/acpi/aml-build: Add GPIO Connection Descriptor
>   hw/acpi/aml-build: Add a wrapper for GPIO Interrupt Connection
>   hw/arm/virt-acpi-build: Add _E03 for Power Button
>   hw/arm/virt: Add QEMU powerdown notifier and hook it to GPIO Pin 3
>   hw/arm/virt: Add gpio-keys node for Poweroff using DT
> 
>  hw/acpi/aml-build.c | 79 
> +
>  hw/arm/virt-acpi-build.c| 45 ++
>  hw/arm/virt.c   | 60 ++
>  include/hw/acpi/aml-build.h | 26 +++
>  include/hw/arm/virt.h   |  1 +
>  5 files changed, 211 insertions(+)
> 



[Qemu-devel] RAM backend and guest ABI (was Re: [PATCH v2] pc: memhp: enforce minimal 128Mb) alignment for pc-dimm

2015-10-29 Thread Eduardo Habkost
(CCing Michal and libvir-list, so libvirt team is aware of this
restriction)

On Thu, Oct 29, 2015 at 02:36:37PM +0100, Igor Mammedov wrote:
> On Tue, 27 Oct 2015 14:36:35 -0200
> Eduardo Habkost  wrote:
> 
> > On Tue, Oct 27, 2015 at 10:14:56AM +0100, Igor Mammedov wrote:
> > > On Tue, 27 Oct 2015 10:53:08 +0200
> > > "Michael S. Tsirkin"  wrote:
> > > 
> > > > On Tue, Oct 27, 2015 at 09:48:37AM +0100, Igor Mammedov wrote:
> > > > > On Tue, 27 Oct 2015 10:31:21 +0200
> > > > > "Michael S. Tsirkin"  wrote:
> > > > > 
> > > > > > On Mon, Oct 26, 2015 at 02:24:32PM +0100, Igor Mammedov wrote:
> > > > > > > Yep it's workaround but it works around QEMU's broken virtio
> > > > > > > implementation in a simple way without need for guest side 
> > > > > > > changes.
> > > > > > > 
> > > > > > > Without foreseeable virtio fix it makes memory hotplug unusable 
> > > > > > > and even
> > > > > > > more so if there were a virtio fix it won't fix old guests since 
> > > > > > > you've
> > > > > > > said that virtio fix would require changes of both QEMU and guest 
> > > > > > > sides.
> > > > > > 
> > > > > > What makes it not foreseeable?
> > > > > > Apparently only the fact that we have a work-around in place so no 
> > > > > > one
> > > > > > works on it.  I can code it up pretty quickly, but I'm flat out of 
> > > > > > time
> > > > > > for testing as I'm going on vacation soon, and hard freeze is pretty
> > > > > > close.
> > > > > I can lend a hand for testing part.
> > > > > 
> > > > > > 
> > > > > > GPA space is kind of cheap, but wasting it in chunks of 512M
> > > > > > seems way too aggressive.
> > > > > hotplug region is sized with 1Gb alignment reserve per DIMM so we 
> > > > > aren't
> > > > > actually wasting anything here.
> > > > >
> > > > 
> > > > If I allocate two 1G DIMMs, what will be the gap size? 512M? 1G?
> > > > It's too much either way.
> > > minimum would be 512, and if backend is 1Gb-hugepage gap will be
> > > backend's natural alignment (i.e. 1Gb).
> > 
> > Is backend configuration even allowed to affect the machine ABI? We need
> > to be able to change backend configuration when migrating the VM to
> > another host.
> for now, one has to use the same type of backend on both sides
> i.e. if source uses 1Gb huge pages backend then target also
> need to use it.
> 

The page size of the backend don't even depend on QEMU arguments, but on
the kernel command-line or hugetlbfs mount options. So it's possible to
have exactly the same QEMU command-line on source and destination (with
an explicit versioned machine-type), and get a VM that can't be
migrated? That means we are breaking our guarantees about migration and
guest ABI.


> We could change this for the next machine type to always force
> max alignment (1Gb), then it would be possible to change
> between backends with different alignments.

I'm not sure what's the best solution here. If always using 1GB is too
aggressive, we could require management to ask for an explicit alignment
as a -machine option if they know they will need a specific backend page
size.

BTW, are you talking about the behavior introduced by
aa8580cddf011e8cedcf87f7a0fdea7549fc4704 ("pc: memhp: force gaps between
DIMM's GPA") only, or the backend page size was already affecting GPA
allocation before that commit?

-- 
Eduardo



Re: [Qemu-devel] [PATCH v3 4/5] xlnx-zynqmp: Connect the SPI devices

2015-10-29 Thread Alistair Francis
On Thu, Oct 29, 2015 at 10:45 AM, Alistair Francis
 wrote:
> On Thu, Oct 29, 2015 at 1:27 AM, Frederic Konrad
>  wrote:
>> On 29/10/2015 03:00, Peter Crosthwaite wrote:
>>> On Wed, Oct 28, 2015 at 10:32 AM, Alistair Francis <
>>> alistair.fran...@xilinx.com> wrote:
>>>
 Connect the Xilinx SPI device to the ZynqMP model.


>>> "devices"
>>>
>>>
 Signed-off-by: Alistair Francis 
 ---
 V3:
  - Expose the SPI Bus as part of the SoC device
 V2:
  - Don't connect the SPI flash to the SoC

  hw/arm/xlnx-zynqmp.c | 37 +
  include/hw/arm/xlnx-zynqmp.h |  4 
  2 files changed, 41 insertions(+)

 diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
 index b36ca3d..5671d7a 100644
 --- a/hw/arm/xlnx-zynqmp.c
 +++ b/hw/arm/xlnx-zynqmp.c
 @@ -48,6 +48,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
  21, 22,
  };

 +static const uint64_t spi_addr[XLNX_ZYNQMP_NUM_SPIS] = {
 +0xFF04, 0xFF05,
 +};
 +
 +static const int spi_intr[XLNX_ZYNQMP_NUM_SPIS] = {
 +19, 20,
 +};
 +
  typedef struct XlnxZynqMPGICRegion {
  int region_index;
  uint32_t address;
 @@ -97,6 +105,12 @@ static void xlnx_zynqmp_init(Object *obj)

  object_initialize(&s->sata, sizeof(s->sata), TYPE_SYSBUS_AHCI);
  qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
 +
 +for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
 +object_initialize(&s->spi[i], sizeof(s->spi[i]),
 +  TYPE_XILINX_SPIPS);
 +qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
 +}
  }

  static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
 @@ -258,6 +272,29 @@ static void xlnx_zynqmp_realize(DeviceState *dev,
 Error **errp)

  sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, SATA_ADDR);
  sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, gic_spi[SATA_INTR]);
 +
 +for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
 +BusState *spi_bus;
 +char bus_name[6];
 +
 +object_property_set_int(OBJECT(&s->spi[i]), XLNX_ZYNQMP_NUM_SPIS,
 +"num-busses", &error_abort);

>>> The number of busses-per-controller is unrelated to the number of
>>> controllers. Setting num_busses != 1 is primarily a QSPI thing, so should
>>> this just default to 1? I think you can drop this setter completely.
>
> True, but see below for a problem.
>
>>>
>>>
 +object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
 &err);
 +if (err) {
 +error_propagate(errp, err);
 +return;
 +}
 +
 +sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_addr[i]);
 +sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
 +   gic_spi[spi_intr[i]]);
 +
 +snprintf(bus_name, 6, "spi%d", i);
 +spi_bus = qdev_get_child_bus(DEVICE(&s->spi), bus_name);
 +
 +/* Add the SPI buses to the SoC child bus */
 +QLIST_INSERT_HEAD(&dev->child_bus, spi_bus, sibling);

>>> Nice! That is pretty simple in the end. One, question though, what happen
>>> with info qtree? Do you get doubles because the bus is double parented?
>
> I don't see the double parent problem, but I do see another problem.
> I was doing it a little wrong with the multiple buses.
>
> When I assign the SPI bus to the SoC, the more recent one replaces the
> previous one. I didn't notice it before because I had two buses (which
> meant they had different names) so it ended up working.
>
> Now with only one bus per I2C they both have the same name and conflict.
>
> I can't change the name of the bus either, so this is a bit of a problem.
>
> I can't see a way around this, while still assigning the buses to the
> SoC. I guess the best option would be to not just take the first match
> when calling qdev_get_child_bus(). Which would mean implementing that
> function manually. How does that sound?

Ok, it isn't actually too bad. This is the diff I have (it's still a
little hacky):

diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index 9ac6e6f..d59cec0 100644
--- a/hw/arm/xlnx-ep108.c
+++ b/hw/arm/xlnx-ep108.c
@@ -63,18 +63,17 @@ static void xlnx_ep108_init(MachineState *machine)

 for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
 SSIBus *spi_bus;
-char bus_name[6];

-snprintf(bus_name, 6, "spi%d", i);
-spi_bus = (SSIBus *)qdev_get_child_bus(DEVICE(&s->soc), bus_name);
+fprintf(stderr, "SPI device %d, bus 0\n", i);
+
+spi_bus = (SSIBus *)qdev_get_num_child_bus(DEVICE(&s->soc), "spi0", i);

 for (j = 0; j < XLNX_ZYNQMP_NUM_SPI_FLASHES; ++j) {
 DeviceState *flash_dev = ssi_create_slave(spi_bus, "

[Qemu-devel] [PULL 11/12] target-arm: xlnx-zynqmp: Add sdhci support.

2015-10-29 Thread Stefan Hajnoczi
From: Sai Pavan Boddu 

Add two SYSBUS_SDHCI devices for xlnx-zynqmp

Signed-off-by: Sai Pavan Boddu 
Reviewed-by: Peter Crosthwaite 
Signed-off-by: Stefan Hajnoczi 
---
 hw/arm/xlnx-zynqmp.c | 28 
 include/hw/arm/xlnx-zynqmp.h |  3 +++
 2 files changed, 31 insertions(+)

diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index b36ca3d..87553bb 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -48,6 +48,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
 21, 22,
 };
 
+static const uint64_t sdhci_addr[XLNX_ZYNQMP_NUM_SDHCI] = {
+0xFF16, 0xFF17,
+};
+
+static const int sdhci_intr[XLNX_ZYNQMP_NUM_SDHCI] = {
+48, 49,
+};
+
 typedef struct XlnxZynqMPGICRegion {
 int region_index;
 uint32_t address;
@@ -97,6 +105,13 @@ static void xlnx_zynqmp_init(Object *obj)
 
 object_initialize(&s->sata, sizeof(s->sata), TYPE_SYSBUS_AHCI);
 qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
+
+for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
+object_initialize(&s->sdhci[i], sizeof(s->sdhci[i]),
+  TYPE_SYSBUS_SDHCI);
+qdev_set_parent_bus(DEVICE(&s->sdhci[i]),
+sysbus_get_default());
+}
 }
 
 static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
@@ -258,6 +273,19 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
**errp)
 
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, SATA_ADDR);
 sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, gic_spi[SATA_INTR]);
+
+for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
+object_property_set_bool(OBJECT(&s->sdhci[i]), true,
+ "realized", &err);
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci[i]), 0,
+sdhci_addr[i]);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci[i]), 0,
+   gic_spi[sdhci_intr[i]]);
+}
 }
 
 static Property xlnx_zynqmp_props[] = {
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 4005a99..d116092 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -24,6 +24,7 @@
 #include "hw/char/cadence_uart.h"
 #include "hw/ide/pci.h"
 #include "hw/ide/ahci.h"
+#include "hw/sd/sdhci.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
 #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
@@ -33,6 +34,7 @@
 #define XLNX_ZYNQMP_NUM_RPU_CPUS 2
 #define XLNX_ZYNQMP_NUM_GEMS 4
 #define XLNX_ZYNQMP_NUM_UARTS 2
+#define XLNX_ZYNQMP_NUM_SDHCI 2
 
 #define XLNX_ZYNQMP_NUM_OCM_BANKS 4
 #define XLNX_ZYNQMP_OCM_RAM_0_ADDRESS 0xFFFC
@@ -63,6 +65,7 @@ typedef struct XlnxZynqMPState {
 CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
 CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
 SysbusAHCIState sata;
+SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
 
 char *boot_cpu;
 ARMCPU *boot_cpu_ptr;
-- 
2.4.3




[Qemu-devel] [PULL 12/12] block: Consider all child nodes in bdrv_requests_pending()

2015-10-29 Thread Stefan Hajnoczi
From: Kevin Wolf 

The function manually recursed into bs->file and bs->backing to check
whether there were any requests pending, but it ignored other children.

There's no need to special case file and backing here, so just replace
these two explicit recursions by a loop recursing for all child nodes.

Reported-by: Max Reitz 
Signed-off-by: Kevin Wolf 
Reviewed-by: Alberto Garcia 
Reviewed-by: Jeff Cody 
Message-id: 1446029211-27148-1-git-send-email-kw...@redhat.com
Signed-off-by: Stefan Hajnoczi 
---
 block/io.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/block/io.c b/block/io.c
index 5ac6256..8dcad3b 100644
--- a/block/io.c
+++ b/block/io.c
@@ -216,6 +216,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs)
 /* Check if any requests are in-flight (including throttled requests) */
 bool bdrv_requests_pending(BlockDriverState *bs)
 {
+BdrvChild *child;
+
 if (!QLIST_EMPTY(&bs->tracked_requests)) {
 return true;
 }
@@ -225,12 +227,13 @@ bool bdrv_requests_pending(BlockDriverState *bs)
 if (!qemu_co_queue_empty(&bs->throttled_reqs[1])) {
 return true;
 }
-if (bs->file && bdrv_requests_pending(bs->file->bs)) {
-return true;
-}
-if (bs->backing && bdrv_requests_pending(bs->backing->bs)) {
-return true;
+
+QLIST_FOREACH(child, &bs->children, next) {
+if (bdrv_requests_pending(child->bs)) {
+return true;
+}
 }
+
 return false;
 }
 
-- 
2.4.3




  1   2   3   >