[Qemu-devel] [Bug 1562653] Re: Ubuntu 15.10: QEMU VM hang if memory >= 1T

2019-05-22 Thread Christian Ehrhardt 
I only saw this because it expired now :-/

Anyone affected by this might want to take a look at bug 1776189 where
Ubuntu added a special machine type to more easily set "host-phys-bits"
which is the qemu flag to have more (usually the host has more)
available (at the cost of migratability). That allows <1TB as the
default bits in qemu are chosen on the base of TCG (to be able to
emulate what is virtualized) and that is limited to 1TB.

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

Title:
  Ubuntu 15.10: QEMU VM hang if memory >= 1T

Status in QEMU:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  1. Ubuntu 15.10 x86_64 installed on HP SuperDome X with 8CPUs and 4T
  memory.

  2. Create a VM, install Ubuntu 15.10, if memory >= 1T , VM hang when start. 
If memory < 1T, it is good.
  
u1510-1
39eefe1e-4829-4843-b892-026d143f3ec7
1073741824
1073741824
16

  hvm
  
  


  
  
  


destroy
restart
restart

  /usr/bin/kvm
  




  
  




  
  
  

  
  

  
  





  
  
  
  

  
  


  
  

  

  

  3. The panic stack is
... cannot show
async_page_fault+0x28
ioread32_rep+0x38
ata_sff_data_xfer32+0x8a
ata_pio_sector+0x93
ata_pio_sectors+0x34
ata_sff_hsm_move+0x226
RIP: kthread_data+0x10
CR2: _FFD8

  4. Change the host os to Redhat 7.2 , the vm is good even memory
  >=3.8T.

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



[Qemu-devel] [PATCH 2/8] spapr: Clean up device tree construction for PCI devices

2019-05-22 Thread David Gibson
spapr_create_pci_child_dt() is a trivial wrapper around
spapr_populate_pci_child_dt(), but is the latter's only caller.  So fold
them together into spapr_dt_pci_device(), which closer matches our modern
naming convention.

While there, make a number of cleanups to the function itself.  This is
mostly using more temporary locals to avoid awkwardly long lines, and in
some cases avoiding double reads of PCI config space variables.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 119 +
 1 file changed, 55 insertions(+), 64 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index b2db46ef1d..4075b433fd 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1219,57 +1219,75 @@ static const char *dt_name_from_class(uint8_t class, 
uint8_t subclass,
 static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
 PCIDevice *pdev);
 
-static void spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
-   SpaprPhbState *sphb)
+/* create OF node for pci device and required OF DT properties */
+static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
+   void *fdt, int parent_offset)
 {
+int offset;
+const gchar *basename;
+char *nodename;
+int slot = PCI_SLOT(dev->devfn);
+int func = PCI_FUNC(dev->devfn);
 ResourceProps rp;
-bool is_bridge = false;
-int pci_status;
-char *buf = NULL;
 uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);
+uint32_t header_type = pci_default_read_config(dev, PCI_HEADER_TYPE, 1);
+bool is_bridge = (header_type == PCI_HEADER_TYPE_BRIDGE);
+uint32_t vendor_id = pci_default_read_config(dev, PCI_VENDOR_ID, 2);
+uint32_t device_id = pci_default_read_config(dev, PCI_DEVICE_ID, 2);
+uint32_t revision_id = pci_default_read_config(dev, PCI_REVISION_ID, 1);
 uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
-uint32_t max_msi, max_msix;
+uint32_t irq_pin = pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1);
+uint32_t subsystem_id = pci_default_read_config(dev, PCI_SUBSYSTEM_ID, 2);
+uint32_t subsystem_vendor_id =
+pci_default_read_config(dev, PCI_SUBSYSTEM_VENDOR_ID, 2);
+uint32_t cache_line_size =
+pci_default_read_config(dev, PCI_CACHE_LINE_SIZE, 1);
+uint32_t pci_status = pci_default_read_config(dev, PCI_STATUS, 2);
+gchar *loc_code;
+
+basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
+  ccode & 0xff);
 
-if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) ==
-PCI_HEADER_TYPE_BRIDGE) {
-is_bridge = true;
+if (func != 0) {
+nodename = g_strdup_printf("%s@%x,%x", basename, slot, func);
+} else {
+nodename = g_strdup_printf("%s@%x", basename, slot);
 }
 
+_FDT(offset = fdt_add_subnode(fdt, parent_offset, nodename));
+
+g_free(nodename);
+
 /* in accordance with PAPR+ v2.7 13.6.3, Table 181 */
-_FDT(fdt_setprop_cell(fdt, offset, "vendor-id",
-  pci_default_read_config(dev, PCI_VENDOR_ID, 2)));
-_FDT(fdt_setprop_cell(fdt, offset, "device-id",
-  pci_default_read_config(dev, PCI_DEVICE_ID, 2)));
-_FDT(fdt_setprop_cell(fdt, offset, "revision-id",
-  pci_default_read_config(dev, PCI_REVISION_ID, 1)));
+_FDT(fdt_setprop_cell(fdt, offset, "vendor-id", vendor_id));
+_FDT(fdt_setprop_cell(fdt, offset, "device-id", device_id));
+_FDT(fdt_setprop_cell(fdt, offset, "revision-id", revision_id));
+
 _FDT(fdt_setprop_cell(fdt, offset, "class-code", ccode));
-if (pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)) {
-_FDT(fdt_setprop_cell(fdt, offset, "interrupts",
- pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)));
+if (irq_pin) {
+_FDT(fdt_setprop_cell(fdt, offset, "interrupts", irq_pin));
 }
 
 if (!is_bridge) {
-_FDT(fdt_setprop_cell(fdt, offset, "min-grant",
-pci_default_read_config(dev, PCI_MIN_GNT, 1)));
-_FDT(fdt_setprop_cell(fdt, offset, "max-latency",
-pci_default_read_config(dev, PCI_MAX_LAT, 1)));
+uint32_t min_grant = pci_default_read_config(dev, PCI_MIN_GNT, 1);
+uint32_t max_latency = pci_default_read_config(dev, PCI_MAX_LAT, 1);
+_FDT(fdt_setprop_cell(fdt, offset, "min-grant", min_grant));
+_FDT(fdt_setprop_cell(fdt, offset, "max-latency", max_latency));
 }
 
-if (pci_default_read_config(dev, PCI_SUBSYSTEM_ID, 2)) {
-_FDT(fdt_setprop_cell(fdt, offset, "subsystem-id",
- pci_default_read_config(dev, PCI_SUBSYSTEM_ID, 2)));
+if (subsystem_id) {
+_FDT(fdt_setprop_cell(fdt, offset, "subsystem-id", subsystem_id));
 }
 
-if (pci_default_read_config(dev, PCI_SUBSYSTEM_VENDOR_ID, 

[Qemu-devel] [PATCH 1/8] spapr: Clean up device node name generation for PCI devices

2019-05-22 Thread David Gibson
spapr_populate_pci_child_dt() adds a 'name' property to the device tree
node for PCI devices.  This is never necessary for a flattened device tree,
it is implicit in the name added when the node is constructed.  In fact
anything we do add to a 'name' property will be overwritten with something
derived from the structural name in the guest firmware (but in fact it is
exactly the same bytes).

So, remove that.  In addition, pci_get_node_name() is very simple, so fold
it into its (also simple) sole caller spapr_create_pci_child_dt().

While we're there rename pci_find_device_name() to the shorter and more
accurate dt_name_from_class().

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 43 +--
 1 file changed, 17 insertions(+), 26 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 97961b0128..b2db46ef1d 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1173,8 +1173,8 @@ static const PCIClass pci_classes[] = {
 { "data-processing-controller", spc_subclass },
 };
 
-static const char *pci_find_device_name(uint8_t class, uint8_t subclass,
-uint8_t iface)
+static const char *dt_name_from_class(uint8_t class, uint8_t subclass,
+  uint8_t iface)
 {
 const PCIClass *pclass;
 const PCISubClass *psubclass;
@@ -1216,23 +1216,6 @@ static const char *pci_find_device_name(uint8_t class, 
uint8_t subclass,
 return name;
 }
 
-static gchar *pci_get_node_name(PCIDevice *dev)
-{
-int slot = PCI_SLOT(dev->devfn);
-int func = PCI_FUNC(dev->devfn);
-uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
-const char *name;
-
-name = pci_find_device_name((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
-ccode & 0xff);
-
-if (func != 0) {
-return g_strdup_printf("%s@%x,%x", name, slot, func);
-} else {
-return g_strdup_printf("%s@%x", name, slot);
-}
-}
-
 static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
 PCIDevice *pdev);
 
@@ -1300,11 +1283,6 @@ static void spapr_populate_pci_child_dt(PCIDevice *dev, 
void *fdt, int offset,
 _FDT(fdt_setprop(fdt, offset, "udf-supported", NULL, 0));
 }
 
-_FDT(fdt_setprop_string(fdt, offset, "name",
-pci_find_device_name((ccode >> 16) & 0xff,
- (ccode >> 8) & 0xff,
- ccode & 0xff)));
-
 buf = spapr_phb_get_loc_code(sphb, dev);
 _FDT(fdt_setprop_string(fdt, offset, "ibm,loc-code", buf));
 g_free(buf);
@@ -1348,10 +1326,23 @@ static int spapr_create_pci_child_dt(SpaprPhbState 
*phb, PCIDevice *dev,
  void *fdt, int node_offset)
 {
 int offset;
-gchar *nodename;
+const gchar *basename;
+char *nodename;
+int slot = PCI_SLOT(dev->devfn);
+int func = PCI_FUNC(dev->devfn);
+uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
+
+basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
+  ccode & 0xff);
+
+if (func != 0) {
+nodename = g_strdup_printf("%s@%x,%x", basename, slot, func);
+} else {
+nodename = g_strdup_printf("%s@%x", basename, slot);
+}
 
-nodename = pci_get_node_name(dev);
 _FDT(offset = fdt_add_subnode(fdt, node_offset, nodename));
+
 g_free(nodename);
 
 spapr_populate_pci_child_dt(dev, fdt, offset, phb);
-- 
2.21.0




[Qemu-devel] [PATCH 7/8] spapr: Direct all PCI hotplug to host bridge, rather than P2P bridge

2019-05-22 Thread David Gibson
A P2P bridge will attempt to handle the hotplug with SHPC, which doesn't
work in the PAPR environment.  Instead we want to direct all PCI hotplug
actions to the PAPR specific host bridge which will use the PAPR hotplug
mechanism.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 507fd50dd5..6dd8aaac33 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4094,6 +4094,17 @@ static HotplugHandler 
*spapr_get_hotplug_handler(MachineState *machine,
 object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
 return HOTPLUG_HANDLER(machine);
 }
+if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+PCIDevice *pcidev = PCI_DEVICE(dev);
+PCIBus *root = pci_device_root_bus(pcidev);
+SpaprPhbState *phb =
+(SpaprPhbState *)object_dynamic_cast(OBJECT(BUS(root)->parent),
+ TYPE_SPAPR_PCI_HOST_BRIDGE);
+
+if (phb) {
+return HOTPLUG_HANDLER(phb);
+}
+}
 return NULL;
 }
 
-- 
2.21.0




[Qemu-devel] [PATCH 4/8] spapr: Clean up spapr_drc_populate_dt()

2019-05-22 Thread David Gibson
This makes some minor cleanups to spapr_drc_populate_dt(), renaming it to
the shorter and more idiomatic spapr_dt_drc() along the way.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c |  7 +++
 hw/ppc/spapr_drc.c | 13 ++---
 hw/ppc/spapr_pci.c |  3 +--
 include/hw/ppc/spapr_drc.h |  3 +--
 4 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 44573adce7..507fd50dd5 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1320,13 +1320,12 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
 spapr_populate_cpus_dt_node(fdt, spapr);
 
 if (smc->dr_lmb_enabled) {
-_FDT(spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
+_FDT(spapr_dt_drc(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
 }
 
 if (mc->has_hotpluggable_cpus) {
 int offset = fdt_path_offset(fdt, "/cpus");
-ret = spapr_drc_populate_dt(fdt, offset, NULL,
-SPAPR_DR_CONNECTOR_TYPE_CPU);
+ret = spapr_dt_drc(fdt, offset, NULL, SPAPR_DR_CONNECTOR_TYPE_CPU);
 if (ret < 0) {
 error_report("Couldn't set up CPU DR device tree properties");
 exit(1);
@@ -1363,7 +1362,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
 }
 
 if (smc->dr_phb_enabled) {
-ret = spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_PHB);
+ret = spapr_dt_drc(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_PHB);
 if (ret < 0) {
 error_report("Couldn't set up PHB DR device tree properties");
 exit(1);
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 597f236b9c..bacadfcac5 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -781,7 +781,7 @@ SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id)
 }
 
 /**
- * spapr_drc_populate_dt
+ * spapr_dt_drc
  *
  * @fdt: libfdt device tree
  * @path: path in the DT to generate properties
@@ -794,8 +794,7 @@ SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id)
  *
  * as documented in PAPR+ v2.1, 13.5.2
  */
-int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
-  uint32_t drc_type_mask)
+int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask)
 {
 Object *root_container;
 ObjectProperty *prop;
@@ -873,7 +872,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object 
*owner,
 *(uint32_t *)drc_names->str = cpu_to_be32(drc_count);
 *(uint32_t *)drc_types->str = cpu_to_be32(drc_count);
 
-ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes",
+ret = fdt_setprop(fdt, offset, "ibm,drc-indexes",
   drc_indexes->data,
   drc_indexes->len * sizeof(uint32_t));
 if (ret) {
@@ -881,7 +880,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object 
*owner,
 goto out;
 }
 
-ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains",
+ret = fdt_setprop(fdt, offset, "ibm,drc-power-domains",
   drc_power_domains->data,
   drc_power_domains->len * sizeof(uint32_t));
 if (ret) {
@@ -889,14 +888,14 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, 
Object *owner,
 goto out;
 }
 
-ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names",
+ret = fdt_setprop(fdt, offset, "ibm,drc-names",
   drc_names->str, drc_names->len);
 if (ret) {
 error_report("Couldn't finalize ibm,drc-names property");
 goto out;
 }
 
-ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types",
+ret = fdt_setprop(fdt, offset, "ibm,drc-types",
   drc_types->str, drc_types->len);
 if (ret) {
 error_report("Couldn't finalize ibm,drc-types property");
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index c166df4145..04855d3125 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -2282,8 +2282,7 @@ int spapr_dt_phb(SpaprPhbState *phb, uint32_t 
intc_phandle, void *fdt,
 return ret;
 }
 
-ret = spapr_drc_populate_dt(fdt, bus_off, OBJECT(phb),
-SPAPR_DR_CONNECTOR_TYPE_PCI);
+ret = spapr_dt_drc(fdt, bus_off, OBJECT(phb), SPAPR_DR_CONNECTOR_TYPE_PCI);
 if (ret) {
 return ret;
 }
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index fad0a887f9..c2c543a591 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -266,8 +266,7 @@ SpaprDrc *spapr_dr_connector_new(Object *owner, const char 
*type,
  uint32_t id);
 SpaprDrc *spapr_drc_by_index(uint32_t index);
 SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id);
-int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
-  uint32_t drc_type_mask);
+int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask);
 
 void spapr_drc_attach(SpaprDrc 

[Qemu-devel] [PATCH 6/8] spapr: Don't use bus number for building DRC ids

2019-05-22 Thread David Gibson
DRC ids are more or less arbitrary, as long as they're consistent.  For
PCI, we notionally build them from the phb's index along with PCI bus
number, slot and function number.

Using bus number is broken, however, because it can change if the guest
re-enumerates the PCI topology for whatever reason (e.g. due to hotplug
of a bridge, which we don't support yet but want to).

Fortunately, there's an alternative.  Bridges are required to have a unique
non-zero "chassis number" that we can use instead.  Adjust the code to
use that instead.

This looks like it would introduce a guest visible breaking change, but
in fact it does not because we don't yet ever use non-zero bus numbers.
Both chassis and bus number are always 0 for the root bus, so there's no
change for the existing cases.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 54 ++
 1 file changed, 40 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index f799f8b423..94691fcfc2 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1221,23 +1221,40 @@ static const char *dt_name_from_class(uint8_t class, 
uint8_t subclass,
  */
 
 static uint32_t drc_id_from_devfn(SpaprPhbState *phb,
-  uint32_t busnr,
-  int32_t devfn)
+  uint8_t chassis, int32_t devfn)
 {
-return (phb->index << 16) | (busnr << 8) | devfn;
+return (phb->index << 16) | (chassis << 8) | devfn;
 }
 
 static SpaprDrc *drc_from_devfn(SpaprPhbState *phb,
-uint32_t busnr, int32_t devfn)
+uint8_t chassis, int32_t devfn)
 {
 return spapr_drc_by_id(TYPE_SPAPR_DRC_PCI,
-   drc_id_from_devfn(phb, busnr, devfn));
+   drc_id_from_devfn(phb, chassis, devfn));
+}
+
+static uint8_t chassis_from_bus(PCIBus *bus, Error **errp)
+{
+if (pci_bus_is_root(bus)) {
+return 0;
+} else {
+PCIDevice *bridge = pci_bridge_get_device(bus);
+
+return object_property_get_uint(OBJECT(bridge), "chassis_nr", errp);
+}
 }
 
 static SpaprDrc *drc_from_dev(SpaprPhbState *phb, PCIDevice *dev)
 {
-uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(dev;
-return drc_from_devfn(phb, busnr, dev->devfn);
+Error *local_err = NULL;
+uint8_t chassis = chassis_from_bus(pci_get_bus(dev), _err);
+
+if (local_err) {
+error_report_err(local_err);
+return NULL;
+}
+
+return drc_from_devfn(phb, chassis, dev->devfn);
 }
 
 static void add_drcs(SpaprPhbState *phb)
@@ -1516,14 +1533,19 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
 spapr_drc_reset(drc);
 } else if (PCI_FUNC(pdev->devfn) == 0) {
 int i;
+uint8_t chassis = chassis_from_bus(pci_get_bus(pdev), _err);
+
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
 
 for (i = 0; i < 8; i++) {
 SpaprDrc *func_drc;
 SpaprDrcClass *func_drck;
 SpaprDREntitySense state;
 
-func_drc = drc_from_devfn(phb, pci_bus_num(bus),
-  PCI_DEVFN(slotnr, i));
+func_drc = drc_from_devfn(phb, chassis, PCI_DEVFN(slotnr, i));
 func_drck = SPAPR_DR_CONNECTOR_GET_CLASS(func_drc);
 state = func_drck->dr_entity_sense(func_drc);
 
@@ -1571,18 +1593,23 @@ static void spapr_pci_unplug_request(HotplugHandler 
*plug_handler,
 g_assert(drc->dev == plugged_dev);
 
 if (!spapr_drc_unplug_requested(drc)) {
-PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
 uint32_t slotnr = PCI_SLOT(pdev->devfn);
 SpaprDrc *func_drc;
 SpaprDrcClass *func_drck;
 SpaprDREntitySense state;
 int i;
+Error *local_err = NULL;
+uint8_t chassis = chassis_from_bus(pci_get_bus(pdev), _err);
+
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
 
 /* ensure any other present functions are pending unplug */
 if (PCI_FUNC(pdev->devfn) == 0) {
 for (i = 1; i < 8; i++) {
-func_drc = drc_from_devfn(phb, pci_bus_num(bus),
-  PCI_DEVFN(slotnr, i));
+func_drc = drc_from_devfn(phb, chassis, PCI_DEVFN(slotnr, i));
 func_drck = SPAPR_DR_CONNECTOR_GET_CLASS(func_drc);
 state = func_drck->dr_entity_sense(func_drc);
 if (state == SPAPR_DR_ENTITY_SENSE_PRESENT
@@ -1603,8 +1630,7 @@ static void spapr_pci_unplug_request(HotplugHandler 
*plug_handler,
  */
 if (PCI_FUNC(pdev->devfn) == 0) {
 for (i = 7; i >= 0; i--) {
-func_drc = drc_from_devfn(phb, pci_bus_num(bus),
-  PCI_DEVFN(slotnr, i));

[Qemu-devel] [PATCH 8/8] spapr: Allow hot plug/unplug of PCI bridges and devices under PCI bridges

2019-05-22 Thread David Gibson
The pseries machine type already allows PCI hotplug and unplug via the
PAPR mechanism, but only on the root bus of each PHB.  This patch extends
this to allow PCI to PCI bridges to be hotplugged, and devices to be
hotplugged or unplugged under P2P bridges.

For now we disallow hot unplugging P2P bridges.  I tried doing that, but
haven't managed to get it working, I think due to some guest side problems
that need further investigation.

To do this we dynamically construct DRCs when bridges are hot (or cold)
added, which can in turn be used to hotplug devices under the bridge.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 115 -
 1 file changed, 102 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 94691fcfc2..a4d5e46525 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1257,30 +1257,53 @@ static SpaprDrc *drc_from_dev(SpaprPhbState *phb, 
PCIDevice *dev)
 return drc_from_devfn(phb, chassis, dev->devfn);
 }
 
-static void add_drcs(SpaprPhbState *phb)
+static void add_drcs(SpaprPhbState *phb, PCIBus *bus, Error **errp)
 {
+Object *owner;
 int i;
+uint8_t chassis;
+Error *local_err = NULL;
 
 if (!phb->dr_enabled) {
 return;
 }
 
+chassis = chassis_from_bus(bus, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+if (pci_bus_is_root(bus)) {
+owner = OBJECT(phb);
+} else {
+owner = OBJECT(pci_bridge_get_device(bus));
+}
+
 for (i = 0; i < PCI_SLOT_MAX * PCI_FUNC_MAX; i++) {
-spapr_dr_connector_new(OBJECT(phb), TYPE_SPAPR_DRC_PCI,
-   drc_id_from_devfn(phb, 0, i));
+spapr_dr_connector_new(owner, TYPE_SPAPR_DRC_PCI,
+   drc_id_from_devfn(phb, chassis, i));
 }
 }
 
-static void remove_drcs(SpaprPhbState *phb)
+static void remove_drcs(SpaprPhbState *phb, PCIBus *bus, Error **errp)
 {
 int i;
+uint8_t chassis;
+Error *local_err = NULL;
 
 if (!phb->dr_enabled) {
 return;
 }
 
+chassis = chassis_from_bus(bus, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
 for (i = PCI_SLOT_MAX * PCI_FUNC_MAX - 1; i >= 0; i--) {
-SpaprDrc *drc = drc_from_devfn(phb, 0, i);
+SpaprDrc *drc = drc_from_devfn(phb, chassis, i);
 
 if (drc) {
 object_unparent(OBJECT(drc));
@@ -1325,6 +1348,7 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus 
*bus,
 .sphb = sphb,
 .err = 0,
 };
+int ret;
 
 _FDT(fdt_setprop_cell(fdt, offset, "#address-cells",
   RESOURCE_CELLS_ADDRESS));
@@ -1339,6 +1363,12 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus 
*bus,
 }
 }
 
+ret = spapr_dt_drc(fdt, offset, OBJECT(bus->parent_dev),
+   SPAPR_DR_CONNECTOR_TYPE_PCI);
+if (ret) {
+return ret;
+}
+
 return offset;
 }
 
@@ -1483,11 +1513,26 @@ int spapr_pci_dt_populate(SpaprDrc *drc, 
SpaprMachineState *spapr,
 return 0;
 }
 
+static void spapr_pci_bridge_plug(SpaprPhbState *phb,
+  PCIBridge *bridge,
+  Error **errp)
+{
+Error *local_err = NULL;
+PCIBus *bus = pci_bridge_get_sec_bus(bridge);
+
+add_drcs(phb, bus, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+}
+
 static void spapr_pci_plug(HotplugHandler *plug_handler,
DeviceState *plugged_dev, Error **errp)
 {
 SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
 PCIDevice *pdev = PCI_DEVICE(plugged_dev);
+PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(plugged_dev);
 SpaprDrc *drc = drc_from_dev(phb, pdev);
 Error *local_err = NULL;
 PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
@@ -1509,6 +1554,14 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
 
 g_assert(drc);
 
+if (pc->is_bridge) {
+spapr_pci_bridge_plug(phb, PCI_BRIDGE(plugged_dev), _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+}
+
 /* Following the QEMU convention used for PCIe multifunction
  * hotplug, we do not allow functions to be hotplugged to a
  * slot that already has function 0 present
@@ -1559,9 +1612,26 @@ out:
 error_propagate(errp, local_err);
 }
 
+static void spapr_pci_bridge_unplug(SpaprPhbState *phb,
+PCIBridge *bridge,
+Error **errp)
+{
+Error *local_err = NULL;
+PCIBus *bus = pci_bridge_get_sec_bus(bridge);
+
+remove_drcs(phb, bus, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+}
+
 static void spapr_pci_unplug(HotplugHandler *plug_handler,

[Qemu-devel] [PATCH 5/8] spapr: Clean up DRC index construction

2019-05-22 Thread David Gibson
spapr_pci.c currently has several confusingly similarly named functions for
various conversions between representations of DRCs.  Make things clearer
by renaming things in a more consistent XXX_from_YYY() manner and remove
some called-only-once variants in favour of open coding.

While we're at it, move this code together in the file to avoid some extra
forward references, and split out construction and removal of DRCs for the
host bridge into helper functions.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 124 +
 1 file changed, 68 insertions(+), 56 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 04855d3125..f799f8b423 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1216,8 +1216,60 @@ static const char *dt_name_from_class(uint8_t class, 
uint8_t subclass,
 return name;
 }
 
-static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
-PCIDevice *pdev);
+/*
+ * DRC helper functions
+ */
+
+static uint32_t drc_id_from_devfn(SpaprPhbState *phb,
+  uint32_t busnr,
+  int32_t devfn)
+{
+return (phb->index << 16) | (busnr << 8) | devfn;
+}
+
+static SpaprDrc *drc_from_devfn(SpaprPhbState *phb,
+uint32_t busnr, int32_t devfn)
+{
+return spapr_drc_by_id(TYPE_SPAPR_DRC_PCI,
+   drc_id_from_devfn(phb, busnr, devfn));
+}
+
+static SpaprDrc *drc_from_dev(SpaprPhbState *phb, PCIDevice *dev)
+{
+uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(dev;
+return drc_from_devfn(phb, busnr, dev->devfn);
+}
+
+static void add_drcs(SpaprPhbState *phb)
+{
+int i;
+
+if (!phb->dr_enabled) {
+return;
+}
+
+for (i = 0; i < PCI_SLOT_MAX * PCI_FUNC_MAX; i++) {
+spapr_dr_connector_new(OBJECT(phb), TYPE_SPAPR_DRC_PCI,
+   drc_id_from_devfn(phb, 0, i));
+}
+}
+
+static void remove_drcs(SpaprPhbState *phb)
+{
+int i;
+
+if (!phb->dr_enabled) {
+return;
+}
+
+for (i = PCI_SLOT_MAX * PCI_FUNC_MAX - 1; i >= 0; i--) {
+SpaprDrc *drc = drc_from_devfn(phb, 0, i);
+
+if (drc) {
+object_unparent(OBJECT(drc));
+}
+}
+}
 
 typedef struct PciWalkFdt {
 void *fdt;
@@ -1284,7 +1336,7 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, 
PCIDevice *dev,
 int func = PCI_FUNC(dev->devfn);
 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
 ResourceProps rp;
-uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);
+SpaprDrc *drc = drc_from_dev(sphb, dev);
 uint32_t vendor_id = pci_default_read_config(dev, PCI_VENDOR_ID, 2);
 uint32_t device_id = pci_default_read_config(dev, PCI_DEVICE_ID, 2);
 uint32_t revision_id = pci_default_read_config(dev, PCI_REVISION_ID, 1);
@@ -1351,8 +1403,9 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, 
PCIDevice *dev,
 _FDT(fdt_setprop_string(fdt, offset, "ibm,loc-code", loc_code));
 g_free(loc_code);
 
-if (drc_index) {
-_FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index));
+if (drc) {
+_FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index",
+  spapr_drc_index(drc)));
 }
 
 if (msi_present(dev)) {
@@ -1402,33 +1455,6 @@ void spapr_phb_remove_pci_device_cb(DeviceState *dev)
 object_unparent(OBJECT(dev));
 }
 
-static SpaprDrc *spapr_phb_get_pci_func_drc(SpaprPhbState *phb,
-uint32_t busnr,
-int32_t devfn)
-{
-return spapr_drc_by_id(TYPE_SPAPR_DRC_PCI,
-   (phb->index << 16) | (busnr << 8) | devfn);
-}
-
-static SpaprDrc *spapr_phb_get_pci_drc(SpaprPhbState *phb,
-   PCIDevice *pdev)
-{
-uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(pdev;
-return spapr_phb_get_pci_func_drc(phb, busnr, pdev->devfn);
-}
-
-static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
-PCIDevice *pdev)
-{
-SpaprDrc *drc = spapr_phb_get_pci_drc(phb, pdev);
-
-if (!drc) {
-return 0;
-}
-
-return spapr_drc_index(drc);
-}
-
 int spapr_pci_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
   void *fdt, int *fdt_start_offset, Error **errp)
 {
@@ -1445,7 +1471,7 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
 {
 SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
 PCIDevice *pdev = PCI_DEVICE(plugged_dev);
-SpaprDrc *drc = spapr_phb_get_pci_drc(phb, pdev);
+SpaprDrc *drc = drc_from_dev(phb, pdev);
 Error *local_err = NULL;
 PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
 uint32_t slotnr = PCI_SLOT(pdev->devfn);
@@ -1496,8 +1522,8 @@ static 

[Qemu-devel] [PATCH 3/8] spapr: Clean up dt creation for PCI buses

2019-05-22 Thread David Gibson
Device nodes for PCI bridges (both host and P2P) describe both the bridge
device itself and the bus hanging off it, handling of this is a bit of a
mess.

spapr_dt_pci_device() has a few things it only adds for non-bridges, but
always adds #address-cells and #size-cells which should only appear for
bridges.  But the walking down the subordinate PCI bus is done in one of
its callers spapr_populate_pci_devices_dt().  The PHB dt creation in
spapr_populate_pci_dt() open codes some similar logic to the bridge case.

This patch consolidates things in a bunch of ways:
 * Bus specific dt info is now created in spapr_dt_pci_bus() used for both
   P2P bridges and the host bridge.  This includes walking subordinate
   devices
 * spapr_dt_pci_device() now calls spapr_dt_pci_bus() when called on a
   P2P bridge
 * We do detection of bridges with the is_bridge field of the device class,
   rather than checking PCI config space directly, for consistency with
   qemu's core PCI code.
 * Several things are renamed for brevity and clarity

Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c  |   7 +-
 hw/ppc/spapr_pci.c  | 140 +++-
 include/hw/pci-host/spapr.h |   4 +-
 3 files changed, 79 insertions(+), 72 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e2b33e5890..44573adce7 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1309,8 +1309,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
 }
 
 QLIST_FOREACH(phb, >phbs, list) {
-ret = spapr_populate_pci_dt(phb, PHANDLE_INTC, fdt,
-spapr->irq->nr_msis, NULL);
+ret = spapr_dt_phb(phb, PHANDLE_INTC, fdt, spapr->irq->nr_msis, NULL);
 if (ret < 0) {
 error_report("couldn't setup PCI devices in fdt");
 exit(1);
@@ -3917,8 +3916,8 @@ int spapr_phb_dt_populate(SpaprDrc *drc, 
SpaprMachineState *spapr,
 return -1;
 }
 
-if (spapr_populate_pci_dt(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
-  fdt_start_offset)) {
+if (spapr_dt_phb(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
+ fdt_start_offset)) {
 error_setg(errp, "unable to create FDT node for PHB %d", sphb->index);
 return -1;
 }
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 4075b433fd..c166df4145 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1219,6 +1219,60 @@ static const char *dt_name_from_class(uint8_t class, 
uint8_t subclass,
 static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
 PCIDevice *pdev);
 
+typedef struct PciWalkFdt {
+void *fdt;
+int offset;
+SpaprPhbState *sphb;
+int err;
+} PciWalkFdt;
+
+static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
+   void *fdt, int parent_offset);
+
+static void spapr_dt_pci_device_cb(PCIBus *bus, PCIDevice *pdev,
+   void *opaque)
+{
+PciWalkFdt *p = opaque;
+int err;
+
+if (p->err) {
+/* Something's already broken, don't keep going */
+return;
+}
+
+err = spapr_dt_pci_device(p->sphb, pdev, p->fdt, p->offset);
+if (err < 0) {
+p->err = err;
+}
+}
+
+/* Augment PCI device node with bridge specific information */
+static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus *bus,
+   void *fdt, int offset)
+{
+PciWalkFdt cbinfo = {
+.fdt = fdt,
+.offset = offset,
+.sphb = sphb,
+.err = 0,
+};
+
+_FDT(fdt_setprop_cell(fdt, offset, "#address-cells",
+  RESOURCE_CELLS_ADDRESS));
+_FDT(fdt_setprop_cell(fdt, offset, "#size-cells",
+  RESOURCE_CELLS_SIZE));
+
+if (bus) {
+pci_for_each_device_reverse(bus, pci_bus_num(bus),
+spapr_dt_pci_device_cb, );
+if (cbinfo.err) {
+return cbinfo.err;
+}
+}
+
+return offset;
+}
+
 /* create OF node for pci device and required OF DT properties */
 static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
void *fdt, int parent_offset)
@@ -1228,10 +1282,9 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, 
PCIDevice *dev,
 char *nodename;
 int slot = PCI_SLOT(dev->devfn);
 int func = PCI_FUNC(dev->devfn);
+PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
 ResourceProps rp;
 uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);
-uint32_t header_type = pci_default_read_config(dev, PCI_HEADER_TYPE, 1);
-bool is_bridge = (header_type == PCI_HEADER_TYPE_BRIDGE);
 uint32_t vendor_id = pci_default_read_config(dev, PCI_VENDOR_ID, 2);
 uint32_t device_id = pci_default_read_config(dev, PCI_DEVICE_ID, 2);
 uint32_t revision_id = pci_default_read_config(dev, PCI_REVISION_ID, 1);
@@ -1268,13 +1321,6 

[Qemu-devel] [Bug 1562653] Re: Ubuntu 15.10: QEMU VM hang if memory >= 1T

2019-05-22 Thread Launchpad Bug Tracker
[Expired for qemu (Ubuntu) because there has been no activity for 60
days.]

** Changed in: qemu (Ubuntu)
   Status: Incomplete => Expired

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

Title:
  Ubuntu 15.10: QEMU VM hang if memory >= 1T

Status in QEMU:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  1. Ubuntu 15.10 x86_64 installed on HP SuperDome X with 8CPUs and 4T
  memory.

  2. Create a VM, install Ubuntu 15.10, if memory >= 1T , VM hang when start. 
If memory < 1T, it is good.
  
u1510-1
39eefe1e-4829-4843-b892-026d143f3ec7
1073741824
1073741824
16

  hvm
  
  


  
  
  


destroy
restart
restart

  /usr/bin/kvm
  




  
  




  
  
  

  
  

  
  





  
  
  
  

  
  


  
  

  

  

  3. The panic stack is
... cannot show
async_page_fault+0x28
ioread32_rep+0x38
ata_sff_data_xfer32+0x8a
ata_pio_sector+0x93
ata_pio_sectors+0x34
ata_sff_hsm_move+0x226
RIP: kthread_data+0x10
CR2: _FFD8

  4. Change the host os to Redhat 7.2 , the vm is good even memory
  >=3.8T.

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



[Qemu-devel] [Bug 1562653] Re: Ubuntu 15.10: QEMU VM hang if memory >= 1T

2019-05-22 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

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

Title:
  Ubuntu 15.10: QEMU VM hang if memory >= 1T

Status in QEMU:
  Expired
Status in qemu package in Ubuntu:
  Expired

Bug description:
  1. Ubuntu 15.10 x86_64 installed on HP SuperDome X with 8CPUs and 4T
  memory.

  2. Create a VM, install Ubuntu 15.10, if memory >= 1T , VM hang when start. 
If memory < 1T, it is good.
  
u1510-1
39eefe1e-4829-4843-b892-026d143f3ec7
1073741824
1073741824
16

  hvm
  
  


  
  
  


destroy
restart
restart

  /usr/bin/kvm
  




  
  




  
  
  

  
  

  
  





  
  
  
  

  
  


  
  

  

  

  3. The panic stack is
... cannot show
async_page_fault+0x28
ioread32_rep+0x38
ata_sff_data_xfer32+0x8a
ata_pio_sector+0x93
ata_pio_sectors+0x34
ata_sff_hsm_move+0x226
RIP: kthread_data+0x10
CR2: _FFD8

  4. Change the host os to Redhat 7.2 , the vm is good even memory
  >=3.8T.

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



[Qemu-devel] [PATCH 1/3] capstone: Adjust include of capstone.h

2019-05-22 Thread Richard Henderson
Since v4.0, capstone.h has moved to .

Signed-off-by: Richard Henderson 
---
 include/disas/capstone.h | 4 
 configure| 6 ++
 2 files changed, 10 insertions(+)

diff --git a/include/disas/capstone.h b/include/disas/capstone.h
index e29068dd97..90631d84a9 100644
--- a/include/disas/capstone.h
+++ b/include/disas/capstone.h
@@ -3,7 +3,11 @@
 
 #ifdef CONFIG_CAPSTONE
 
+#ifdef CONFIG_CAPSTONE_CAPSTONE_H
+#include 
+#else
 #include 
+#endif
 
 #else
 
diff --git a/configure b/configure
index d2fc346302..eec7f061c3 100755
--- a/configure
+++ b/configure
@@ -5021,6 +5021,9 @@ case "$capstone" in
   system)
 QEMU_CFLAGS="$QEMU_CFLAGS $($pkg_config --cflags capstone)"
 LIBS="$($pkg_config --libs capstone) $LIBS"
+if check_include capstone/capstone.h; then
+  capstone_capstone_h=yes
+fi
 ;;
 
   no)
@@ -7197,6 +7200,9 @@ if test "$ivshmem" = "yes" ; then
 fi
 if test "$capstone" != "no" ; then
   echo "CONFIG_CAPSTONE=y" >> $config_host_mak
+  if test "$capstone_capstone_h" != "no" ; then
+echo "CONFIG_CAPSTONE_CAPSTONE_H=y" >> $config_host_mak
+  fi
 fi
 if test "$debug_mutex" = "yes" ; then
   echo "CONFIG_DEBUG_MUTEX=y" >> $config_host_mak
-- 
2.17.1




[Qemu-devel] [PATCH 3/3] capstone: Enable disassembly for s390x

2019-05-22 Thread Richard Henderson
Enable s390x, aka SYSZ, in the git submodule build.
Set the capstone parameters for both s390x host and guest.
Install a skipdata hook to keep capstone in sync with the
instruction stream for unknown opcodes.

Signed-off-by: Richard Henderson 
---
 Makefile   |  1 +
 disas.c| 40 
 target/s390x/cpu.c |  4 
 3 files changed, 45 insertions(+)

diff --git a/Makefile b/Makefile
index 155f066a20..a37e872825 100644
--- a/Makefile
+++ b/Makefile
@@ -477,6 +477,7 @@ CAP_CFLAGS += -DCAPSTONE_USE_SYS_DYN_MEM
 CAP_CFLAGS += -DCAPSTONE_HAS_ARM
 CAP_CFLAGS += -DCAPSTONE_HAS_ARM64
 CAP_CFLAGS += -DCAPSTONE_HAS_POWERPC
+CAP_CFLAGS += -DCAPSTONE_HAS_SYSZ
 CAP_CFLAGS += -DCAPSTONE_HAS_X86
 
 subdir-capstone: .git-submodule-status
diff --git a/disas.c b/disas.c
index 41ad0102e2..c1ecd2d769 100644
--- a/disas.c
+++ b/disas.c
@@ -179,6 +179,39 @@ static int print_insn_od_target(bfd_vma pc, 
disassemble_info *info)
to share this across calls and across host vs target disassembly.  */
 static __thread cs_insn *cap_insn;
 
+/*
+ * The capstone library always skips 2 bytes for S390X.
+ * This is less than ideal, since we can tell from the first two bits
+ * the size of the insn and thus stay in sync with the insn stream.
+ */
+static size_t CAPSTONE_API
+cap_skipdata_s390x_cb(const uint8_t *code, size_t code_size,
+  size_t offset, void *user_data)
+{
+size_t ilen;
+
+/* See get_ilen() in target/s390x/internal.h.  */
+switch (code[offset] >> 6) {
+case 0:
+ilen = 2;
+break;
+case 1:
+case 2:
+ilen = 4;
+break;
+default:
+ilen = 6;
+break;
+}
+
+return ilen;
+}
+
+static const cs_opt_skipdata cap_skipdata_s390x = {
+.mnemonic = ".byte",
+.callback = cap_skipdata_s390x_cb
+};
+
 /* Initialize the Capstone library.  */
 /* ??? It would be nice to cache this.  We would need one handle for the
host and one for the target.  For most targets we can reset specific
@@ -209,6 +242,10 @@ static cs_err cap_disas_start(disassemble_info *info, csh 
*handle)
 
 /* "Disassemble" unknown insns as ".byte W,X,Y,Z".  */
 cs_option(*handle, CS_OPT_SKIPDATA, CS_OPT_ON);
+if (info->cap_arch == CS_ARCH_SYSZ) {
+cs_option(*handle, CS_OPT_SKIPDATA_SETUP,
+  (uintptr_t)_skipdata_s390x);
+}
 
 /* Allocate temp space for cs_disasm_iter.  */
 if (cap_insn == NULL) {
@@ -551,6 +588,9 @@ void disas(FILE *out, void *code, unsigned long size)
 print_insn = print_insn_m68k;
 #elif defined(__s390__)
 print_insn = print_insn_s390;
+s.info.cap_arch = CS_ARCH_SYSZ;
+s.info.cap_insn_unit = 2;
+s.info.cap_insn_split = 6;
 #elif defined(__hppa__)
 print_insn = print_insn_hppa;
 #endif
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index b1df63d82c..553571d86b 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -41,6 +41,7 @@
 #include "sysemu/sysemu.h"
 #endif
 #include "fpu/softfloat.h"
+#include "disas/capstone.h"
 
 #define CR0_RESET   0xE0UL
 #define CR14_RESET  0xC200UL;
@@ -175,6 +176,9 @@ static void s390_cpu_disas_set_info(CPUState *cpu, 
disassemble_info *info)
 {
 info->mach = bfd_mach_s390_64;
 info->print_insn = print_insn_s390;
+info->cap_arch = CS_ARCH_SYSZ;
+info->cap_insn_unit = 2;
+info->cap_insn_split = 6;
 }
 
 static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
-- 
2.17.1




[Qemu-devel] [PATCH 0/3] Update capstone module

2019-05-22 Thread Richard Henderson
There has recently been some good progress in the upstream
capstone repository, syncing the instruction sets from the
(further) upstream llvm.

In particular, there are Power9 and System z13 instructions.
Both of which were missing from our current snapshot and from
our (ancient) binutils opcodes snapshots.


r~


Richard Henderson (3):
  capstone: Adjust include of capstone.h
  capstone: Update to master
  capstone: Enable disassembly for s390x

 Makefile |  1 +
 include/disas/capstone.h |  4 
 disas.c  | 40 
 target/s390x/cpu.c   |  4 
 capstone |  2 +-
 configure|  7 +++
 6 files changed, 57 insertions(+), 1 deletion(-)

-- 
2.17.1




[Qemu-devel] [PATCH 2/3] capstone: Update to master

2019-05-22 Thread Richard Henderson
Update to fbb20ea83c5a.  Choose this over the 4.0.1 tag because
master now includes the s390x z13 vector opcodes.

Signed-off-by: Richard Henderson 
---
 capstone  | 2 +-
 configure | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/capstone b/capstone
index 22ead3e0bf..fbb20ea83c 16
--- a/capstone
+++ b/capstone
@@ -1 +1 @@
-Subproject commit 22ead3e0bfdb87516656453336160e0a37b066bf
+Subproject commit fbb20ea83c5af4f29b40c17fbadb1f71b0a08fae
diff --git a/configure b/configure
index eec7f061c3..a2e4636a34 100755
--- a/configure
+++ b/configure
@@ -5016,6 +5016,7 @@ case "$capstone" in
   LIBCAPSTONE=libcapstone.a
 fi
 LIBS="-L\$(BUILD_DIR)/capstone -lcapstone $LIBS"
+capstone_capstone_h=yes
 ;;
 
   system)
-- 
2.17.1




Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests

2019-05-22 Thread Eduardo Habkost
On Wed, May 22, 2019 at 09:04:17PM -0400, Cleber Rosa wrote:
> 
> 
> - Original Message -
> > From: "Eduardo Habkost" 
> > To: "Cleber Rosa" 
> > Cc: "Philippe Mathieu-Daudé" , qemu-devel@nongnu.org, 
> > "Aleksandar Rikalo" ,
> > "Aleksandar Markovic" , "Aleksandar Markovic" 
> > , "Aurelien
> > Jarno" , "Wainer dos Santos Moschetta" 
> > 
> > Sent: Wednesday, May 22, 2019 7:07:05 PM
> > Subject: Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests
> > 
> > On Wed, May 22, 2019 at 05:46:06PM -0400, Cleber Rosa wrote:
> > > 
> > > 
> > > - Original Message -
> > > > From: "Eduardo Habkost" 
> > > > To: "Philippe Mathieu-Daudé" 
> > > > Cc: qemu-devel@nongnu.org, "Aleksandar Rikalo" ,
> > > > "Aleksandar Markovic"
> > > > , "Aleksandar Markovic"
> > > > , "Cleber Rosa" ,
> > > > "Aurelien Jarno" , "Wainer dos Santos Moschetta"
> > > > 
> > > > Sent: Wednesday, May 22, 2019 5:12:30 PM
> > > > Subject: Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests
> > > > 
> > > > On Tue, May 21, 2019 at 01:19:06AM +0200, Philippe Mathieu-Daudé wrote:
> > > > > Hi,
> > > > > 
> > > > > It was a rainy week-end here, so I invested it to automatize some
> > > > > of my MIPS tests.
> > > > > 
> > > > > The BootLinuxSshTest is not Global warming friendly, it is not
> > > > > meant to run on a CI system but rather on a workstation previous
> > > > > to post a pull request.
> > > > > It can surely be improved, but it is a good starting point.
> > > > 
> > > > Until we actually have a mechanism to exclude the test case on
> > > > travis-ci, I will remove patch 4/4 from the queue.  Aleksandar,
> > > > please don't merge patch 4/4 yet or it will break travis-ci.
> > > > 
> > > > Cleber, Wainer, is it already possible to make "avocado run" skip
> > > > tests tagged with "slow"?
> > > > 
> > > 
> > > The mechanism exists, but we haven't tagged any test so far as slow.
> > > 
> > > Should we define/document a criteria for a test to be slow?  Given
> > > that this is highly subjective, we have to think of:
> > > 
> > >  * Will we consider the average or maximum run time (the timeout
> > >definition)?
> > >  
> > >  * For a single test, what is "slow"? Some rough numbers from Travis
> > >CI[1] to help us with guidelines:
> > >- boot_linux_console.py:BootLinuxConsole.test_x86_64_pc:  PASS (6.04 s)
> > >- boot_linux_console.py:BootLinuxConsole.test_arm_virt:  PASS (2.91 s)
> > >-
> > >
> > > linux_initrd.py:LinuxInitrd.test_with_2gib_file_should_work_with_linux_v4_16:
> > >PASS (18.14 s)
> > >- boot_linux.py:BootLinuxAarch64.test_virt:  PASS (396.88 s)
> > 
> > I don't think we need to overthink this.  Whatever objective
> > criteria we choose, I'm sure we'll have to adapt them later due
> > to real world problems.
> > 
> > e.g.: is 396 seconds too slow?  I don't know, it depends: does it
> > break Travis and other CI systems often because of timeouts?  If
> > yes, then we should probably tag it as slow.
> > 
> 
> It's not only that.  We're close to a point where we'll need to
> determine whether "make check-acceptance" will work as a generic
> enough default for most user on their environments and most CI
> systems.
> 
> As an example, this job ran 5 fairly slow tests (which I'm preparing
> to send):
> 
>   https://travis-ci.org/clebergnu/qemu/jobs/535967210#L3518
> 
> Those are justifiably slow, given the fact that they boot a full
> Fedora 30 system using TCG.  The job has a cumulative execution time
> of ~39 minutes.  That leaves only 11 minutes to spare on the Travis
> CI environment.  If they all exercised close to their 600s allowances
> (timeout), the Travis job would have failed. 
> 
> Having said that, if a CI failure is supposed to be a major breakage,
> which I believe it's the right mind set and a worthy goal, we should
> limit the amount of tests we run so that their *maximum* execution
> time does not exceed the maximum job time limit.
> 
> > If having subjective criteria is really a problem (I don't think
> > it is), then we can call the tag "skip_travis", and stop worrying
> > about defining what exactly is "slow".
> > 
> > 
> > > 
> > >  * Do we want to set a maximum job timeout?  This way we can skip
> > >tests after a given amount of time has passed.  Currently we interrupt
> > >the test running when the job timeout is reached, but it's possible
> > >to add a option so that no new tests will be started, but currently
> > >running ones will be waited on.
> > 
> > I'm not sure I understand the suggestion to skip tests.  If we
> > skip tests after a timeout, how would we differentiate a test
> > being expectedly slow from a QEMU hang?
> > 
> > --
> > Eduardo
> > 
> 
> Basically, what I meant is that we could attempt something like:
> 
>  * Job "Brave"
>   - 50 tests, each with 60 seconds timeout = 50 min max
>   - 60 tests, each with 1 second timeout  = 1 min max
> 
> If Job "Brave" is run on a system such as Travis, it *can* fail,
> because it 

Re: [Qemu-devel] [RFC v2 PATCH 3/3] spapr: Add Hcalls to support PAPR NVDIMM device

2019-05-22 Thread David Gibson
On Wed, May 22, 2019 at 03:08:34PM -0300, Fabiano Rosas wrote:
> Shivaprasad G Bhat  writes:
> 
> > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> > index 6c16d2b120..b6e7d04dcf 100644
> > --- a/hw/ppc/spapr_hcall.c
> > +++ b/hw/ppc/spapr_hcall.c
> > @@ -3,11 +3,13 @@
> >  #include "sysemu/hw_accel.h"
> >  #include "sysemu/sysemu.h"
> >  #include "qemu/log.h"
> > +#include "qemu/range.h"
> >  #include "qemu/error-report.h"
> >  #include "cpu.h"
> >  #include "exec/exec-all.h"
> >  #include "helper_regs.h"
> >  #include "hw/ppc/spapr.h"
> > +#include "hw/ppc/spapr_drc.h"
> >  #include "hw/ppc/spapr_cpu_core.h"
> >  #include "mmu-hash64.h"
> >  #include "cpu-models.h"
> > @@ -16,6 +18,7 @@
> >  #include "hw/ppc/spapr_ovec.h"
> >  #include "mmu-book3s-v3.h"
> >  #include "hw/mem/memory-device.h"
> > +#include "hw/mem/nvdimm.h"
> >  
> >  static bool has_spr(PowerPCCPU *cpu, int spr)
> >  {
> > @@ -1795,6 +1798,199 @@ static target_ulong h_update_dt(PowerPCCPU *cpu, 
> > SpaprMachineState *spapr,
> >  return H_SUCCESS;
> >  }
> >  
> > +static target_ulong h_scm_read_metadata(PowerPCCPU *cpu,
> > +SpaprMachineState *spapr,
> > +target_ulong opcode,
> > +target_ulong *args)
> > +{
> > +uint32_t drc_index = args[0];
> > +uint64_t offset = args[1];
> > +uint64_t numBytesToRead = args[2];
> 
> This variable's case is inconsistent with the rest of the file.
> 
> > +SpaprDrc *drc = spapr_drc_by_index(drc_index);
> > +NVDIMMDevice *nvdimm = NULL;
> > +NVDIMMClass *ddc = NULL;
> > +
> > +if (drc && spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PMEM) {
> > +return H_PARAMETER;
> > +}
> > +
> > +if (numBytesToRead != 1 && numBytesToRead != 2 &&
> > +numBytesToRead != 4 && numBytesToRead != 8) {
> > +return H_P3;
> > +}
> > +
> > +nvdimm = NVDIMM(drc->dev);
> > +if ((offset + numBytesToRead < offset) ||
> > +(nvdimm->label_size < numBytesToRead + offset)) {
> > +return H_P2;
> > +}
> 
> Won't the first clause always be false? Considering they're both
> uint64_t.

Generally yes, but that's caleed supplied input, so we need to protect
against 64-bit overflow.

> 
> > +
> > +ddc = NVDIMM_GET_CLASS(nvdimm);
> > +ddc->read_label_data(nvdimm, [0], numBytesToRead, offset);
> > +
> > +return H_SUCCESS;
> > +}
> > +
> > +
> > +static target_ulong h_scm_write_metadata(PowerPCCPU *cpu,
> > + SpaprMachineState *spapr,
> > + target_ulong opcode,
> > + target_ulong *args)
> > +{
> > +uint32_t drc_index = args[0];
> > +uint64_t offset = args[1];
> > +uint64_t data = args[2];
> > +int8_t numBytesToWrite = args[3];
> 
> Likewise.
> 
> > +SpaprDrc *drc = spapr_drc_by_index(drc_index);
> > +NVDIMMDevice *nvdimm = NULL;
> > +DeviceState *dev = NULL;
> > +NVDIMMClass *ddc = NULL;
> > +
> > +if (drc && spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PMEM) {
> > +return H_PARAMETER;
> > +}
> > +
> > +if (numBytesToWrite != 1 && numBytesToWrite != 2 &&
> > +numBytesToWrite != 4 && numBytesToWrite != 8) {
> > +return H_P4;
> > +}
> > +
> > +dev = drc->dev;
> > +nvdimm = NVDIMM(dev);
> > +if ((nvdimm->label_size < numBytesToWrite + offset) ||
> > +(offset + numBytesToWrite < offset)) {
> > +return H_P2;
> > +}
> > +
> > +ddc = NVDIMM_GET_CLASS(nvdimm);
> > +ddc->write_label_data(nvdimm, , numBytesToWrite, offset);
> > +
> > +return H_SUCCESS;
> > +}
> > +
> > +static target_ulong h_scm_bind_mem(PowerPCCPU *cpu, SpaprMachineState 
> > *spapr,
> > +target_ulong opcode,
> > +target_ulong *args)
> > +{
> > +uint32_t drc_index = args[0];
> > +uint64_t starting_idx = args[1];
> > +uint64_t no_of_scm_blocks_to_bind = args[2];
> > +uint64_t target_logical_mem_addr = args[3];
> > +uint64_t continue_token = args[4];
> > +uint64_t size;
> > +uint64_t total_no_of_scm_blocks;
> > +
> > +SpaprDrc *drc = spapr_drc_by_index(drc_index);
> > +hwaddr addr;
> > +DeviceState *dev = NULL;
> > +PCDIMMDevice *dimm = NULL;
> > +Error *local_err = NULL;
> > +
> > +if (drc && spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PMEM) {
> > +return H_PARAMETER;
> > +}
> > +
> > +dev = drc->dev;
> > +dimm = PC_DIMM(dev);
> > +
> > +size = object_property_get_uint(OBJECT(dimm),
> > +PC_DIMM_SIZE_PROP, _err);
> > +if (local_err) {
> > +error_report_err(local_err);
> > +return H_PARAMETER;
> > +}
> > +
> > +total_no_of_scm_blocks = size / SPAPR_MINIMUM_SCM_BLOCK_SIZE;
> > +
> > +if ((starting_idx 

[Qemu-devel] [PATCH] vmstate: Add VMSTATE_OPAQUE to save/load complex data structures

2019-05-22 Thread rkir--- via Qemu-devel
From: Roman Kiryanov 

VMSTATE_OPAQUE allows passing user defined functions to save
and load vmstate for cases when data structures do not fit
into int/struct/array terms.

Signed-off-by: Roman Kiryanov 
---
 include/migration/vmstate.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 9224370ed5..2736daef17 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -737,6 +737,19 @@ extern const VMStateInfo vmstate_info_qtailq;
 .start= offsetof(_type, _next),  \
 }
 
+/* Provides a way to save/load complex data structures that do not
+ * fit into int/struct/array terms.
+ * _info: a user defined instance of VMStateInfo to handle saving and loading.
+ */
+#define VMSTATE_OPAQUE(_name, _version, _info) {  \
+.name = _name,\
+.version_id   = (_version),   \
+.size = 0,\
+.info = &(_info), \
+.flags= VMS_SINGLE,   \
+.offset   = 0,\
+}
+
 /* _f : field name
_f_n : num of elements field_name
_n : num of elements
-- 
2.21.0.1020.gf2820cf01a-goog




Re: [Qemu-devel] [PULL v2 00/36] pci, pc, virtio: features, fixes

2019-05-22 Thread Laszlo Ersek
(+Ard)

On 05/22/19 16:22, Laszlo Ersek wrote:
> On 05/22/19 15:06, Igor Mammedov wrote:
>> On Tue, 21 May 2019 09:26:16 -0400
>> "Michael S. Tsirkin"  wrote:
>>
>>> On Tue, May 21, 2019 at 12:49:48PM +0100, Peter Maydell wrote:
 On Tue, 21 May 2019 at 00:10, Michael S. Tsirkin 
 wrote:
>
> The following changes since commit
> 2259637b95bef3116cc262459271de08e038cc66:
>
>   Merge remote-tracking branch 'remotes/kevin/tags/for-upstream'
>   into staging (2019-05-20 17:22:05 +0100)
>
> are available in the Git repository at:
>
>   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git
>   tags/for_upstream
>
> for you to fetch changes up to
> 0c05ec64c388aea59facbef740651afa78e04f50:
>
>   tests: acpi: print error unable to dump ACPI table during
>   rebuild (2019-05-20 18:40:02 -0400)
>
> 
> pci, pc, virtio: features, fixes
>
> reconnect for vhost blk
> tests for UEFI
> misc other stuff
>
> Signed-off-by: Michael S. Tsirkin 
>
> 

 Hi -- this failed 'make check' for 32-bit Arm hosts:

 ERROR:/home/peter.maydell/qemu/tests/acpi-utils.c:145:acpi_find_rsdp_address_uefi:
 code should not be reached
 Aborted
 ERROR - too few tests run (expected 1, got 0)
 /home/peter.maydell/qemu/tests/Makefile.include:885: recipe for
 /target check-qtest-aarch64' failed

 thanks
 -- PMM
>>>
>>> Nothing jumps out ... Igor?
>> On 32-bit ARM host and it looks like UEFI crashes (CCing Laszlo)
>> with:
>>
>> InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 469E52C0
>> ASSERT [DxeCore] 
>> /home/lacos/src/upstream/qemu/roms/edk2/MdePkg/Library/BaseLib/String.c(1090):
>>  Length < _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength
>>
>> CLI to reproduce:
>>
>> qemu-system-aarch64  -display none -machine virt,accel=tcg
>> -nodefaults -nographic -drive
>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly
>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
>> -cpu cortex-a57 -serial stdio
>
> This is very interesting. I had obviously tested booting
> "bios-tables-test.aarch64.iso.qcow2" against "edk2-aarch64-code.fd",
> using TCG, on my x86_64 laptop. (And, I've run the above exact command
> just now, at commit a4f667b67149 -- it works 100% fine.)
>
> However, I've never been *near* a 32-bit ARM host. Therefore my
> suspicion is that the AARCH64 UEFI guest code tickles something in the
> 32-bit ARM code generator. It could be a bug in 32-bit ARM TCG, or it
> could be a bug in edk2 that is exposed by 32-bit ARM TCG.
>
> The direct assertion failure is mostly useless. The AsciiStrLen()
> function does what you'd expect it to, except it has a kind of "safety
> check" where it trips an assertion if the string length (under
> measurement) exceeds a pre-set platform constant. It helps with
> catching memory corruption errors.
>
> $ git show edk2-stable201903:MdePkg/Library/BaseLib/String.c | less
> 1090g
>
> UINTN
> EFIAPI
> AsciiStrLen (
>   IN  CONST CHAR8   *String
>   )
> {
>   UINTN Length;
>
>   ASSERT (String != NULL);
>
>   for (Length = 0; *String != '\0'; String++, Length++) {
> //
> // If PcdMaximumUnicodeStringLength is not zero,
> // length should not more than PcdMaximumUnicodeStringLength
> //
> if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
>   ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength)); <-- HERE
> }
>   }
>   return Length;
> }
>
> (Never mind that the comment has a typo -- it incorrectly references
> "PcdMaximumUnicodeStringLength", but the PCD that's actually checked
> is (correctly) "PcdMaximumAsciiStringLength".)
>
> The constant is set to decimal 1,000,000 in ArmVirtQemu builds
> (inherited from MdePkg.dec), and that's indeed a quite unlikely length
> for real-word strings seen by firmware.
>
> I'll take a closer look once I have access to a 32-bit ARM host, but
> I'll definitely need help. Basically we should compare the original
> AARCH64 (dis)assembly with the QEMU-generated 32-bit ARM assembly.
> Hopefully I can at least get a backtrace myself.

I have narrowed down the issue sufficiently that I think I can hand it
over to Peter and Ard now -- because they know AARCH32 and AARCH64
assembly, and "target/arm/translate-a64.c" and "tcg/arm/*" too.

The summarize the issue for Ard, the symptom is that AARCH64 ArmVirtQemu
runs perfectly fine with TCG on an x86-64 system, but it crashes on an
AARCH32 host system.

Below is my analysis.

(1) First, I determined a backtrace for the crash. For this, I flipped
the ASSERT() failure disposition from CpuDeadLoop() to CpuBreakpoint(),
via "PcdDebugPropertyMask". This printed a very nice 

Re: [Qemu-devel] [PULL v2 00/36] pci, pc, virtio: features, fixes

2019-05-22 Thread Laszlo Ersek
On 05/23/19 02:51, Laszlo Ersek wrote:

> I'm attaching the two log sections ("good.txt" (from
> the x86-64 host) vs "bad.txt" (from the aarch64 host)).

Typo correction: "bad.txt" comes from an aarch32 host. (That's quite the
point.)

Thanks & sorry
Laszlo



Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests

2019-05-22 Thread Cleber Rosa



- Original Message -
> From: "Eduardo Habkost" 
> To: "Cleber Rosa" 
> Cc: "Philippe Mathieu-Daudé" , qemu-devel@nongnu.org, 
> "Aleksandar Rikalo" ,
> "Aleksandar Markovic" , "Aleksandar Markovic" 
> , "Aurelien
> Jarno" , "Wainer dos Santos Moschetta" 
> 
> Sent: Wednesday, May 22, 2019 7:07:05 PM
> Subject: Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests
> 
> On Wed, May 22, 2019 at 05:46:06PM -0400, Cleber Rosa wrote:
> > 
> > 
> > - Original Message -
> > > From: "Eduardo Habkost" 
> > > To: "Philippe Mathieu-Daudé" 
> > > Cc: qemu-devel@nongnu.org, "Aleksandar Rikalo" ,
> > > "Aleksandar Markovic"
> > > , "Aleksandar Markovic"
> > > , "Cleber Rosa" ,
> > > "Aurelien Jarno" , "Wainer dos Santos Moschetta"
> > > 
> > > Sent: Wednesday, May 22, 2019 5:12:30 PM
> > > Subject: Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests
> > > 
> > > On Tue, May 21, 2019 at 01:19:06AM +0200, Philippe Mathieu-Daudé wrote:
> > > > Hi,
> > > > 
> > > > It was a rainy week-end here, so I invested it to automatize some
> > > > of my MIPS tests.
> > > > 
> > > > The BootLinuxSshTest is not Global warming friendly, it is not
> > > > meant to run on a CI system but rather on a workstation previous
> > > > to post a pull request.
> > > > It can surely be improved, but it is a good starting point.
> > > 
> > > Until we actually have a mechanism to exclude the test case on
> > > travis-ci, I will remove patch 4/4 from the queue.  Aleksandar,
> > > please don't merge patch 4/4 yet or it will break travis-ci.
> > > 
> > > Cleber, Wainer, is it already possible to make "avocado run" skip
> > > tests tagged with "slow"?
> > > 
> > 
> > The mechanism exists, but we haven't tagged any test so far as slow.
> > 
> > Should we define/document a criteria for a test to be slow?  Given
> > that this is highly subjective, we have to think of:
> > 
> >  * Will we consider the average or maximum run time (the timeout
> >definition)?
> >  
> >  * For a single test, what is "slow"? Some rough numbers from Travis
> >CI[1] to help us with guidelines:
> >- boot_linux_console.py:BootLinuxConsole.test_x86_64_pc:  PASS (6.04 s)
> >- boot_linux_console.py:BootLinuxConsole.test_arm_virt:  PASS (2.91 s)
> >-
> >
> > linux_initrd.py:LinuxInitrd.test_with_2gib_file_should_work_with_linux_v4_16:
> >PASS (18.14 s)
> >- boot_linux.py:BootLinuxAarch64.test_virt:  PASS (396.88 s)
> 
> I don't think we need to overthink this.  Whatever objective
> criteria we choose, I'm sure we'll have to adapt them later due
> to real world problems.
> 
> e.g.: is 396 seconds too slow?  I don't know, it depends: does it
> break Travis and other CI systems often because of timeouts?  If
> yes, then we should probably tag it as slow.
> 

It's not only that.  We're close to a point where we'll need to
determine whether "make check-acceptance" will work as a generic
enough default for most user on their environments and most CI
systems.

As an example, this job ran 5 fairly slow tests (which I'm preparing
to send):

  https://travis-ci.org/clebergnu/qemu/jobs/535967210#L3518

Those are justifiably slow, given the fact that they boot a full
Fedora 30 system using TCG.  The job has a cumulative execution time
of ~39 minutes.  That leaves only 11 minutes to spare on the Travis
CI environment.  If they all exercised close to their 600s allowances
(timeout), the Travis job would have failed. 

Having said that, if a CI failure is supposed to be a major breakage,
which I believe it's the right mind set and a worthy goal, we should
limit the amount of tests we run so that their *maximum* execution
time does not exceed the maximum job time limit.

> If having subjective criteria is really a problem (I don't think
> it is), then we can call the tag "skip_travis", and stop worrying
> about defining what exactly is "slow".
> 
> 
> > 
> >  * Do we want to set a maximum job timeout?  This way we can skip
> >tests after a given amount of time has passed.  Currently we interrupt
> >the test running when the job timeout is reached, but it's possible
> >to add a option so that no new tests will be started, but currently
> >running ones will be waited on.
> 
> I'm not sure I understand the suggestion to skip tests.  If we
> skip tests after a timeout, how would we differentiate a test
> being expectedly slow from a QEMU hang?
> 
> --
> Eduardo
> 

Basically, what I meant is that we could attempt something like:

 * Job "Brave"
  - 50 tests, each with 60 seconds timeout = 50 min max
  - 60 tests, each with 1 second timeout  = 1 min max

If Job "Brave" is run on a system such as Travis, it *can* fail,
because it can go over the maximum Travis CI job limit of 50 min.
We could set an Avocado job timeout of say, 48 minutes, and tell
Avocado to mark the tests it wasn't able to spawn as "SKIPPED",
and do not report an overall error condition.

But, if we want to be more conservative (which I now realize is
the best 

Re: [Qemu-devel] [PATCH v2] numa: improve cpu hotplug error message with a wrong node-id

2019-05-22 Thread David Gibson
On Tue, May 21, 2019 at 09:33:48AM +0200, Laurent Vivier wrote:
> On pseries, core-ids are strongly binded to a node-id by the command
> line option. If an user tries to add a CPU to the wrong node, he has
> an error but it is not really helpful:
> 
>   qemu-system-ppc64 ... -smp 1,maxcpus=64,cores=1,threads=1,sockets=1 \
> -numa node,nodeid=0 -numa node,nodeid=1 ...
> 
>   (qemu) device_add power9_v2.0-spapr-cpu-core,core-id=30,node-id=1
>   Error: node-id=1 must match numa node specified with -numa option
> 
> This patch improves this error message by giving to the user the good
> topology information (node-id, socket-id and thread-id if they are
> available) to use with the core-id he's providing:
> 
>   Error: core-id 30 can only be plugged into node-id 0
> 
> Signed-off-by: Laurent Vivier 

LGTM,

Reviewed-by: David Gibson 

> ---
> 
> Notes:
> v2: display full topology in the error message
> 
>  numa.c | 28 ++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
> 
> diff --git a/numa.c b/numa.c
> index 3875e1efda3a..7413f821e2bb 100644
> --- a/numa.c
> +++ b/numa.c
> @@ -458,6 +458,27 @@ void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
>  set_numa_options(MACHINE(qdev_get_machine()), cmd, errp);
>  }
>  
> +static char *cpu_topology_to_string(const CPUArchId *cpu)
> +{
> +GString *s = g_string_new(NULL);
> +if (cpu->props.has_socket_id) {
> +g_string_append_printf(s, "socket-id %"PRId64, cpu->props.socket_id);
> +}
> +if (cpu->props.has_node_id) {
> +if (s->len) {
> +g_string_append_printf(s, ", ");
> +}
> +g_string_append_printf(s, "node-id %"PRId64, cpu->props.node_id);
> +}
> +if (cpu->props.has_thread_id) {
> +if (s->len) {
> +g_string_append_printf(s, ", ");
> +}
> +g_string_append_printf(s, "thread-id %"PRId64, cpu->props.thread_id);
> +}
> +return g_string_free(s, false);
> +}
> +
>  void numa_cpu_pre_plug(const CPUArchId *slot, DeviceState *dev, Error **errp)
>  {
>  int node_id = object_property_get_int(OBJECT(dev), "node-id", 
> _abort);
> @@ -470,8 +491,11 @@ void numa_cpu_pre_plug(const CPUArchId *slot, 
> DeviceState *dev, Error **errp)
>  "node-id", errp);
>  }
>  } else if (node_id != slot->props.node_id) {
> -error_setg(errp, "node-id=%d must match numa node specified "
> -   "with -numa option", node_id);
> +char *topology = cpu_topology_to_string(slot);
> +error_setg(errp,
> +   "core-id %"PRId64" can only be plugged into %s",
> +   slot->props.core_id, topology);
> +g_free(topology);
>  }
>  }
>  

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 1/1] spapr: Do not re-read the clock on pre_save handler on migration

2019-05-22 Thread David Gibson
On Mon, May 20, 2019 at 05:43:40PM -0300, Maxiwell S. Garcia wrote:
> This handler was added in the commit:
>   42043e4f1241: spapr: clock should count only if vm is running
> 
> In a scenario without migration, this pre_save handler is not
> triggered, so the 'stop/cont' commands save and restore the clock
> in the function 'cpu_ppc_clock_vm_state_change.' The SW clock
> in the guest doesn't know about this pause.
> 
> If the command 'migrate' is called between 'stop' and 'cont',
> the pre_save handler re-read the clock, and the SW clock in the
> guest will know about the pause between 'stop' and 'migrate.'
> If the guest is running a workload like HTC, a side-effect of
> this is a lot of process stall messages (with call traces) in
> the kernel guest.
> 
> Signed-off-by: Maxiwell S. Garcia 

What affect will this have on the clock for the case of migrations
without a stop/cont around?  The complicated thing here is that for
*explicit* stops/continues we want to freeze the clock, however for
the implicit stop/continue during migration downtime, we want to keep
the clock running (logically), so that the guest time of day doesn't
get out of sync on migration.

> ---
>  hw/ppc/ppc.c | 24 
>  1 file changed, 24 deletions(-)
> 
> diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
> index ad20584f26..3fb50cbeee 100644
> --- a/hw/ppc/ppc.c
> +++ b/hw/ppc/ppc.c
> @@ -1056,35 +1056,11 @@ void cpu_ppc_clock_vm_state_change(void *opaque, int 
> running,
>  }
>  }
>  
> -/*
> - * When migrating, read the clock just before migration,
> - * so that the guest clock counts during the events
> - * between:
> - *
> - *  * vm_stop()
> - *  *
> - *  * pre_save()
> - *
> - *  This reduces clock difference on migration from 5s
> - *  to 0.1s (when max_downtime == 5s), because sending the
> - *  final pages of memory (which happens between vm_stop()
> - *  and pre_save()) takes max_downtime.

Urgh.. this comment is confusing - 5s would be a ludicrously long
max_downtime by modern standards.

> - */
> -static int timebase_pre_save(void *opaque)
> -{
> -PPCTimebase *tb = opaque;
> -
> -timebase_save(tb);
> -
> -return 0;
> -}
> -
>  const VMStateDescription vmstate_ppc_timebase = {
>  .name = "timebase",
>  .version_id = 1,
>  .minimum_version_id = 1,
>  .minimum_version_id_old = 1,
> -.pre_save = timebase_pre_save,
>  .fields  = (VMStateField []) {
>  VMSTATE_UINT64(guest_timebase, PPCTimebase),
>  VMSTATE_INT64(time_of_the_day_ns, PPCTimebase),

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 0/2] spapr/xive: change default interrupt mode to 'dual'

2019-05-22 Thread David Gibson
On Wed, May 22, 2019 at 09:40:14AM +0200, Cédric Le Goater wrote:
> Hello,
> 
> Here is a little series fixing multiple resets when in 'dual'
> interrupt mode and changing the default mode to 'dual'.

Applied, thanks.

> 
> Thanks,
> 
> C.
> 
> Cédric Le Goater (2):
>   spapr/xive: fix multiple resets when using the 'dual' interrupt mode
>   spapr: change default interrupt mode to 'dual'
> 
>  hw/intc/spapr_xive.c | 11 +--
>  hw/intc/spapr_xive_kvm.c |  4 
>  hw/ppc/spapr.c   |  3 ++-
>  3 files changed, 7 insertions(+), 11 deletions(-)
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] spapr: Don't migrate the hpt_maxpagesize cap to older machine types

2019-05-22 Thread David Gibson
On Wed, May 22, 2019 at 03:43:46PM +0200, Greg Kurz wrote:
> Commit 0b8c89be7f7b added the hpt_maxpagesize capability to the migration
> stream. This is okay for new machine types but it breaks backward migration
> to older QEMUs, which don't expect the extra subsection.
> 
> Add a compatibility boolean flag to the sPAPR machine class and use it to
> skip migration of the capability for machine types 4.0 and older. This
> fixes migration to an older QEMU. Note that the destination will emit a
> warning:
> 
> qemu-system-ppc64: warning: cap-hpt-max-page-size lower level (16) in 
> incoming stream than on destination (24)
> 
> This is expected and harmless though. It is okay to migrate from a lower
> HPT maximum page size (64k) to a greater one (16M).
> 
> Fixes: 0b8c89be7f7b "spapr: Add forgotten capability to migration stream"
> Based-on: <20190522074016.10521-3-...@kaod.org>
> Signed-off-by: Greg Kurz 

Applied, thanks.

> ---
> 
> Please notice that this is based on Cedric's patch that make "dual" the
> default for the ic-mode property.
> ---
>  hw/ppc/spapr.c |1 +
>  hw/ppc/spapr_caps.c|   12 +++-
>  include/hw/ppc/spapr.h |1 +
>  3 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 4fd16b43f014..e2b33e5890ae 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4431,6 +4431,7 @@ static void 
> spapr_machine_4_0_class_options(MachineClass *mc)
>  compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
>  smc->phb_placement = phb_placement_4_0;
>  smc->irq = _irq_xics;
> +smc->pre_4_1_migration = true;
>  }
>  
>  DEFINE_SPAPR_MACHINE(4_0, "4.0", false);
> diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
> index 658eb15a147b..31b466139975 100644
> --- a/hw/ppc/spapr_caps.c
> +++ b/hw/ppc/spapr_caps.c
> @@ -64,6 +64,7 @@ typedef struct SpaprCapabilityInfo {
>  void (*apply)(SpaprMachineState *spapr, uint8_t val, Error **errp);
>  void (*cpu_apply)(SpaprMachineState *spapr, PowerPCCPU *cpu,
>uint8_t val, Error **errp);
> +bool (*migrate_needed)(void *opaque);
>  } SpaprCapabilityInfo;
>  
>  static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
> @@ -350,6 +351,11 @@ static void cap_hpt_maxpagesize_apply(SpaprMachineState 
> *spapr,
>  spapr_check_pagesize(spapr, qemu_minrampagesize(), errp);
>  }
>  
> +static bool cap_hpt_maxpagesize_migrate_needed(void *opaque)
> +{
> +return !SPAPR_MACHINE_GET_CLASS(opaque)->pre_4_1_migration;
> +}
> +
>  static bool spapr_pagesize_cb(void *opaque, uint32_t seg_pshift,
>uint32_t pshift)
>  {
> @@ -542,6 +548,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
>  .type = "int",
>  .apply = cap_hpt_maxpagesize_apply,
>  .cpu_apply = cap_hpt_maxpagesize_cpu_apply,
> +.migrate_needed = cap_hpt_maxpagesize_migrate_needed,
>  },
>  [SPAPR_CAP_NESTED_KVM_HV] = {
>  .name = "nested-hv",
> @@ -679,8 +686,11 @@ int spapr_caps_post_migration(SpaprMachineState *spapr)
>  static bool spapr_cap_##sname##_needed(void *opaque)\
>  {   \
>  SpaprMachineState *spapr = opaque;  \
> +bool (*needed)(void *opaque) =  \
> +capability_table[cap].migrate_needed;   \
>  \
> -return spapr->cmd_line_caps[cap] && \
> +return needed ? needed(opaque) : true &&\
> +   spapr->cmd_line_caps[cap] && \
> (spapr->eff.caps[cap] != \
>  spapr->def.caps[cap]);  \
>  }   \
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 9fc91c8f5eac..4f5becf1f3cc 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -119,6 +119,7 @@ struct SpaprMachineClass {
>  bool pre_2_10_has_unused_icps;
>  bool legacy_irq_allocation;
>  bool broken_host_serial_model; /* present real host info to the guest */
> +bool pre_4_1_migration; /* don't migrate hpt-max-page-size */
>  
>  void (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
>uint64_t *buid, hwaddr *pio, 
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests

2019-05-22 Thread Eduardo Habkost
On Wed, May 22, 2019 at 05:46:06PM -0400, Cleber Rosa wrote:
> 
> 
> - Original Message -
> > From: "Eduardo Habkost" 
> > To: "Philippe Mathieu-Daudé" 
> > Cc: qemu-devel@nongnu.org, "Aleksandar Rikalo" , 
> > "Aleksandar Markovic"
> > , "Aleksandar Markovic" 
> > , "Cleber Rosa" ,
> > "Aurelien Jarno" , "Wainer dos Santos Moschetta" 
> > 
> > Sent: Wednesday, May 22, 2019 5:12:30 PM
> > Subject: Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests
> > 
> > On Tue, May 21, 2019 at 01:19:06AM +0200, Philippe Mathieu-Daudé wrote:
> > > Hi,
> > > 
> > > It was a rainy week-end here, so I invested it to automatize some
> > > of my MIPS tests.
> > > 
> > > The BootLinuxSshTest is not Global warming friendly, it is not
> > > meant to run on a CI system but rather on a workstation previous
> > > to post a pull request.
> > > It can surely be improved, but it is a good starting point.
> > 
> > Until we actually have a mechanism to exclude the test case on
> > travis-ci, I will remove patch 4/4 from the queue.  Aleksandar,
> > please don't merge patch 4/4 yet or it will break travis-ci.
> > 
> > Cleber, Wainer, is it already possible to make "avocado run" skip
> > tests tagged with "slow"?
> > 
> 
> The mechanism exists, but we haven't tagged any test so far as slow.
> 
> Should we define/document a criteria for a test to be slow?  Given
> that this is highly subjective, we have to think of:
> 
>  * Will we consider the average or maximum run time (the timeout
>definition)?
>  
>  * For a single test, what is "slow"? Some rough numbers from Travis
>CI[1] to help us with guidelines:
>- boot_linux_console.py:BootLinuxConsole.test_x86_64_pc:  PASS (6.04 s)
>- boot_linux_console.py:BootLinuxConsole.test_arm_virt:  PASS (2.91 s)
>- 
> linux_initrd.py:LinuxInitrd.test_with_2gib_file_should_work_with_linux_v4_16: 
>  PASS (18.14 s)
>- boot_linux.py:BootLinuxAarch64.test_virt:  PASS (396.88 s)

I don't think we need to overthink this.  Whatever objective
criteria we choose, I'm sure we'll have to adapt them later due
to real world problems.

e.g.: is 396 seconds too slow?  I don't know, it depends: does it
break Travis and other CI systems often because of timeouts?  If
yes, then we should probably tag it as slow.

If having subjective criteria is really a problem (I don't think
it is), then we can call the tag "skip_travis", and stop worrying
about defining what exactly is "slow".


> 
>  * Do we want to set a maximum job timeout?  This way we can skip
>tests after a given amount of time has passed.  Currently we interrupt
>the test running when the job timeout is reached, but it's possible
>to add a option so that no new tests will be started, but currently
>running ones will be waited on.

I'm not sure I understand the suggestion to skip tests.  If we
skip tests after a timeout, how would we differentiate a test
being expectedly slow from a QEMU hang?

-- 
Eduardo



Re: [Qemu-devel] [PATCH 4/4] hw/arm/exynos4210: QOM'ify the Exynos4210 SoC

2019-05-22 Thread Alistair Francis
On Mon, May 20, 2019 at 2:47 PM Philippe Mathieu-Daudé
 wrote:
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/arm/exynos4210.c | 26 +++---
>  hw/arm/exynos4_boards.c |  9 ++---
>  include/hw/arm/exynos4210.h |  9 +++--
>  3 files changed, 36 insertions(+), 8 deletions(-)
>
> diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
> index 19009b76e7c..0b09129eff8 100644
> --- a/hw/arm/exynos4210.c
> +++ b/hw/arm/exynos4210.c
> @@ -178,9 +178,10 @@ static void pl330_create(uint32_t base, qemu_irq irq, 
> int nreq)
>  sysbus_connect_irq(busdev, 0, irq);
>  }
>
> -Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
> +static void exynos4210_realize(DeviceState *socdev, Error **errp)
>  {
> -Exynos4210State *s = g_new0(Exynos4210State, 1);
> +Exynos4210State *s = EXYNOS4210_SOC(socdev);
> +MemoryRegion *system_mem = get_system_memory();
>  qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
>  SysBusDevice *busdev;
>  DeviceState *dev;
> @@ -435,6 +436,25 @@ Exynos4210State *exynos4210_init(MemoryRegion 
> *system_mem)
>   qemu_irq_invert(s->irq_table[exynos4210_get_irq(36, 1)]), 
> 32);
>  pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
>   qemu_irq_invert(s->irq_table[exynos4210_get_irq(34, 1)]), 
> 1);
> +}
> +
> +static void exynos4210_class_init(ObjectClass *klass, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(klass);
>
> -return s;
> +dc->realize = exynos4210_realize;
>  }
> +
> +static const TypeInfo exynos4210_info = {
> +.name = TYPE_EXYNOS4210_SOC,
> +.parent = TYPE_SYS_BUS_DEVICE,
> +.instance_size = sizeof(Exynos4210State),
> +.class_init = exynos4210_class_init,
> +};
> +
> +static void exynos4210_register_types(void)
> +{
> +type_register_static(_info);
> +}
> +
> +type_init(exynos4210_register_types)
> diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
> index f824eef0d36..700e90d6671 100644
> --- a/hw/arm/exynos4_boards.c
> +++ b/hw/arm/exynos4_boards.c
> @@ -45,7 +45,7 @@ typedef enum Exynos4BoardType {
>  } Exynos4BoardType;
>
>  typedef struct Exynos4BoardState {
> -Exynos4210State *soc;
> +Exynos4210State soc;
>  MemoryRegion dram0_mem;
>  MemoryRegion dram1_mem;
>  } Exynos4BoardState;
> @@ -130,7 +130,10 @@ exynos4_boards_init_common(MachineState *machine,
>  exynos4_boards_init_ram(s, get_system_memory(),
>  exynos4_board_ram_size[board_type]);
>
> -s->soc = exynos4210_init(get_system_memory());
> +object_initialize(>soc, sizeof(s->soc), TYPE_EXYNOS4210_SOC);
> +qdev_set_parent_bus(DEVICE(>soc), sysbus_get_default());
> +object_property_set_bool(OBJECT(>soc), true, "realized",
> + _fatal);
>
>  return s;
>  }
> @@ -148,7 +151,7 @@ static void smdkc210_init(MachineState *machine)
>
> EXYNOS4_BOARD_SMDKC210);
>
>  lan9215_init(SMDK_LAN9118_BASE_ADDR,
> -qemu_irq_invert(s->soc->irq_table[exynos4210_get_irq(37, 1)]));
> +qemu_irq_invert(s->soc.irq_table[exynos4210_get_irq(37, 1)]));
>  arm_load_kernel(ARM_CPU(first_cpu), _board_binfo);
>  }
>
> diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
> index 098a69ec73d..27c684e851d 100644
> --- a/include/hw/arm/exynos4210.h
> +++ b/include/hw/arm/exynos4210.h
> @@ -85,6 +85,9 @@ typedef struct Exynos4210Irq {
>  } Exynos4210Irq;
>
>  typedef struct Exynos4210State {
> +/*< private >*/
> +SysBusDevice parent_obj;
> +/*< public >*/
>  ARMCPU *cpu[EXYNOS4210_NCPUS];
>  Exynos4210Irq irqs;
>  qemu_irq *irq_table;
> @@ -98,11 +101,13 @@ typedef struct Exynos4210State {
>  I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
>  } Exynos4210State;
>
> +#define TYPE_EXYNOS4210_SOC "exynos4210"
> +#define EXYNOS4210_SOC(obj) \
> +OBJECT_CHECK(Exynos4210State, obj, TYPE_EXYNOS4210_SOC)
> +
>  void exynos4210_write_secondary(ARMCPU *cpu,
>  const struct arm_boot_info *info);
>
> -Exynos4210State *exynos4210_init(MemoryRegion *system_mem);
> -
>  /* Initialize exynos4210 IRQ subsystem stub */
>  qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
>
> --
> 2.20.1
>
>



Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests

2019-05-22 Thread Aleksandar Markovic
On May 22, 2019 11:46 PM, "Cleber Rosa"  wrote:
>
>
>
> - Original Message -
> > From: "Eduardo Habkost" 
> > To: "Philippe Mathieu-Daudé" 
> > Cc: qemu-devel@nongnu.org, "Aleksandar Rikalo" ,
"Aleksandar Markovic"
> > , "Aleksandar Markovic" <
amarko...@wavecomp.com>, "Cleber Rosa" ,
> > "Aurelien Jarno" , "Wainer dos Santos Moschetta" <
waine...@redhat.com>
> > Sent: Wednesday, May 22, 2019 5:12:30 PM
> > Subject: Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests
> >
> > On Tue, May 21, 2019 at 01:19:06AM +0200, Philippe Mathieu-Daudé wrote:
> > > Hi,
> > >
> > > It was a rainy week-end here, so I invested it to automatize some
> > > of my MIPS tests.
> > >
> > > The BootLinuxSshTest is not Global warming friendly, it is not
> > > meant to run on a CI system but rather on a workstation previous
> > > to post a pull request.
> > > It can surely be improved, but it is a good starting point.
> >
> > Until we actually have a mechanism to exclude the test case on
> > travis-ci, I will remove patch 4/4 from the queue.  Aleksandar,
> > please don't merge patch 4/4 yet or it will break travis-ci.
> >
> > Cleber, Wainer, is it already possible to make "avocado run" skip
> > tests tagged with "slow"?
> >
>
> The mechanism exists, but we haven't tagged any test so far as slow.
>

Cleber,

For the test from patch 4/4, there is no dilemma - it should be in the
“slow” group, as Philippe envisioned and said, so that it is not humpered
with stricter requirements for “fast” (default) group. Could you explain us
how to do it, so that we can hopefully finally proceed?

Gratefully,
Aleksandar

> Should we define/document a criteria for a test to be slow?  Given
> that this is highly subjective, we have to think of:
>
>  * Will we consider the average or maximum run time (the timeout
>definition)?
>
>  * For a single test, what is "slow"? Some rough numbers from Travis
>CI[1] to help us with guidelines:
>- boot_linux_console.py:BootLinuxConsole.test_x86_64_pc:  PASS (6.04 s)
>- boot_linux_console.py:BootLinuxConsole.test_arm_virt:  PASS (2.91 s)
>-
linux_initrd.py:LinuxInitrd.test_with_2gib_file_should_work_with_linux_v4_16:
PASS (18.14 s)
>- boot_linux.py:BootLinuxAarch64.test_virt:  PASS (396.88 s)
>
>  * Do we want to set a maximum job timeout?  This way we can skip
>tests after a given amount of time has passed.  Currently we interrupt
>the test running when the job timeout is reached, but it's possible
>to add a option so that no new tests will be started, but currently
>running ones will be waited on.
>
> Regards,
> - Cleber.
>
> [1] - https://travis-ci.org/clebergnu/qemu/jobs/535967210#L3518
>
> > --
> > Eduardo
> >


[Qemu-devel] [PULL 15/16] tcg/aarch64: Allow immediates for vector ORR and BIC

2019-05-22 Thread Richard Henderson
The allows immediates to be used for ORR and BIC,
as well as the trivial inversions, ORC and AND.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 90 +---
 1 file changed, 83 insertions(+), 7 deletions(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 52c18074ae..9e1dad9696 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -119,6 +119,8 @@ static inline bool patch_reloc(tcg_insn_unit *code_ptr, int 
type,
 #define TCG_CT_CONST_LIMM 0x200
 #define TCG_CT_CONST_ZERO 0x400
 #define TCG_CT_CONST_MONE 0x800
+#define TCG_CT_CONST_ORRI 0x1000
+#define TCG_CT_CONST_ANDI 0x2000
 
 /* parse target specific constraints */
 static const char *target_parse_constraint(TCGArgConstraint *ct,
@@ -154,6 +156,12 @@ static const char 
*target_parse_constraint(TCGArgConstraint *ct,
 case 'M': /* minus one */
 ct->ct |= TCG_CT_CONST_MONE;
 break;
+case 'O': /* vector orr/bic immediate */
+ct->ct |= TCG_CT_CONST_ORRI;
+break;
+case 'N': /* vector orr/bic immediate, inverted */
+ct->ct |= TCG_CT_CONST_ANDI;
+break;
 case 'Z': /* zero */
 ct->ct |= TCG_CT_CONST_ZERO;
 break;
@@ -293,6 +301,16 @@ static int is_shimm32_pair(uint32_t v32, int *cmode, int 
*imm8)
 return i;
 }
 
+/* Return true if V is a valid 16-bit or 32-bit shifted immediate.  */
+static bool is_shimm1632(uint32_t v32, int *cmode, int *imm8)
+{
+if (v32 == deposit32(v32, 16, 16, v32)) {
+return is_shimm16(v32, cmode, imm8);
+} else {
+return is_shimm32(v32, cmode, imm8);
+}
+}
+
 static int tcg_target_const_match(tcg_target_long val, TCGType type,
   const TCGArgConstraint *arg_ct)
 {
@@ -317,6 +335,23 @@ static int tcg_target_const_match(tcg_target_long val, 
TCGType type,
 return 1;
 }
 
+switch (ct & (TCG_CT_CONST_ORRI | TCG_CT_CONST_ANDI)) {
+case 0:
+break;
+case TCG_CT_CONST_ANDI:
+val = ~val;
+/* fallthru */
+case TCG_CT_CONST_ORRI:
+if (val == deposit64(val, 32, 32, val)) {
+int cmode, imm8;
+return is_shimm1632(val, , );
+}
+break;
+default:
+/* Both bits should not be set for the same insn.  */
+g_assert_not_reached();
+}
+
 return 0;
 }
 
@@ -2278,6 +2313,7 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 TCGType type = vecl + TCG_TYPE_V64;
 unsigned is_q = vecl;
 TCGArg a0, a1, a2, a3;
+int cmode, imm8;
 
 a0 = args[0];
 a1 = args[1];
@@ -2309,20 +2345,56 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 tcg_out_insn(s, 3617, ABS, is_q, vece, a0, a1);
 break;
 case INDEX_op_and_vec:
+if (const_args[2]) {
+is_shimm1632(~a2, , );
+if (a0 == a1) {
+tcg_out_insn(s, 3606, BIC, is_q, a0, 0, cmode, imm8);
+return;
+}
+tcg_out_insn(s, 3606, MVNI, is_q, a0, 0, cmode, imm8);
+a2 = a0;
+}
 tcg_out_insn(s, 3616, AND, is_q, 0, a0, a1, a2);
 break;
 case INDEX_op_or_vec:
+if (const_args[2]) {
+is_shimm1632(a2, , );
+if (a0 == a1) {
+tcg_out_insn(s, 3606, ORR, is_q, a0, 0, cmode, imm8);
+return;
+}
+tcg_out_insn(s, 3606, MOVI, is_q, a0, 0, cmode, imm8);
+a2 = a0;
+}
 tcg_out_insn(s, 3616, ORR, is_q, 0, a0, a1, a2);
 break;
-case INDEX_op_xor_vec:
-tcg_out_insn(s, 3616, EOR, is_q, 0, a0, a1, a2);
-break;
 case INDEX_op_andc_vec:
+if (const_args[2]) {
+is_shimm1632(a2, , );
+if (a0 == a1) {
+tcg_out_insn(s, 3606, BIC, is_q, a0, 0, cmode, imm8);
+return;
+}
+tcg_out_insn(s, 3606, MOVI, is_q, a0, 0, cmode, imm8);
+a2 = a0;
+}
 tcg_out_insn(s, 3616, BIC, is_q, 0, a0, a1, a2);
 break;
 case INDEX_op_orc_vec:
+if (const_args[2]) {
+is_shimm1632(~a2, , );
+if (a0 == a1) {
+tcg_out_insn(s, 3606, ORR, is_q, a0, 0, cmode, imm8);
+return;
+}
+tcg_out_insn(s, 3606, MVNI, is_q, a0, 0, cmode, imm8);
+a2 = a0;
+}
 tcg_out_insn(s, 3616, ORN, is_q, 0, a0, a1, a2);
 break;
+case INDEX_op_xor_vec:
+tcg_out_insn(s, 3616, EOR, is_q, 0, a0, a1, a2);
+break;
 case INDEX_op_ssadd_vec:
 tcg_out_insn(s, 3616, SQADD, is_q, vece, a0, a1, a2);
 break;
@@ -2505,6 +2577,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 static const TCGTargetOpDef lZ_l = { .args_ct_str = { "lZ", "l" } };
 static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
 

[Qemu-devel] [PULL 11/16] tcg/aarch64: Support vector bitwise select value

2019-05-22 Thread Richard Henderson
The instruction set has 3 insns that perform the same operation,
only varying in which operand must overlap the destination.  We
can represent the operation without overlap and choose based on
the operands seen.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  2 +-
 tcg/aarch64/tcg-target.inc.c | 24 +++-
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index b4a9d36bbc..ca214f6909 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -140,7 +140,7 @@ typedef enum {
 #define TCG_TARGET_HAS_mul_vec  1
 #define TCG_TARGET_HAS_sat_vec  1
 #define TCG_TARGET_HAS_minmax_vec   1
-#define TCG_TARGET_HAS_bitsel_vec   0
+#define TCG_TARGET_HAS_bitsel_vec   1
 #define TCG_TARGET_HAS_cmpsel_vec   0
 
 #define TCG_TARGET_DEFAULT_MO (0)
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 40bf35079a..e99149cda7 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -523,6 +523,9 @@ typedef enum {
 I3616_ADD   = 0x0e208400,
 I3616_AND   = 0x0e201c00,
 I3616_BIC   = 0x0e601c00,
+I3616_BIF   = 0x2ee01c00,
+I3616_BIT   = 0x2ea01c00,
+I3616_BSL   = 0x2e601c00,
 I3616_EOR   = 0x2e201c00,
 I3616_MUL   = 0x0e209c00,
 I3616_ORR   = 0x0ea01c00,
@@ -2181,7 +2184,7 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 
 TCGType type = vecl + TCG_TYPE_V64;
 unsigned is_q = vecl;
-TCGArg a0, a1, a2;
+TCGArg a0, a1, a2, a3;
 
 a0 = args[0];
 a1 = args[1];
@@ -2304,6 +2307,20 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 }
 break;
 
+case INDEX_op_bitsel_vec:
+a3 = args[3];
+if (a0 == a3) {
+tcg_out_insn(s, 3616, BIT, is_q, 0, a0, a2, a1);
+} else if (a0 == a2) {
+tcg_out_insn(s, 3616, BIF, is_q, 0, a0, a3, a1);
+} else {
+if (a0 != a1) {
+tcg_out_mov(s, type, a0, a1);
+}
+tcg_out_insn(s, 3616, BSL, is_q, 0, a0, a2, a3);
+}
+break;
+
 case INDEX_op_mov_vec:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_dupi_vec: /* Always emitted via tcg_out_movi.  */
 case INDEX_op_dup_vec:  /* Always emitted via tcg_out_dup_vec.  */
@@ -2334,6 +2351,7 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 case INDEX_op_usadd_vec:
 case INDEX_op_ussub_vec:
 case INDEX_op_shlv_vec:
+case INDEX_op_bitsel_vec:
 return 1;
 case INDEX_op_shrv_vec:
 case INDEX_op_sarv_vec:
@@ -2408,6 +2426,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 = { .args_ct_str = { "r", "r", "rA", "rZ", "rZ" } };
 static const TCGTargetOpDef add2
 = { .args_ct_str = { "r", "r", "rZ", "rZ", "rA", "rMZ" } };
+static const TCGTargetOpDef w_w_w_w
+= { .args_ct_str = { "w", "w", "w", "w" } };
 
 switch (op) {
 case INDEX_op_goto_ptr:
@@ -2580,6 +2600,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode 
op)
 return _wr;
 case INDEX_op_cmp_vec:
 return _w_wZ;
+case INDEX_op_bitsel_vec:
+return _w_w_w;
 
 default:
 return NULL;
-- 
2.17.1




[Qemu-devel] [PULL 13/16] tcg/aarch64: Use MVNI in tcg_out_dupi_vec

2019-05-22 Thread Richard Henderson
The compliment of a subset of immediates can be computed
with a single instruction.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 1422dfebe2..0b8b733805 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -494,6 +494,7 @@ typedef enum {
 
 /* AdvSIMD modified immediate */
 I3606_MOVI  = 0x0f000400,
+I3606_MVNI  = 0x2f000400,
 
 /* AdvSIMD shift by immediate */
 I3614_SSHR  = 0x0f000400,
@@ -838,8 +839,13 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
 tcg_out_insn(s, 3606, MOVI, q, rd, 0, cmode, imm8);
 return;
 }
+if (is_shimm16(~v16, , )) {
+tcg_out_insn(s, 3606, MVNI, q, rd, 0, cmode, imm8);
+return;
+}
 } else if (v64 == dup_const(MO_32, v64)) {
 uint32_t v32 = v64;
+uint32_t n32 = ~v32;
 
 if (is_shimm32(v32, , ) ||
 is_soimm32(v32, , ) ||
@@ -847,6 +853,11 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
 tcg_out_insn(s, 3606, MOVI, q, rd, 0, cmode, imm8);
 return;
 }
+if (is_shimm32(n32, , ) ||
+is_soimm32(n32, , )) {
+tcg_out_insn(s, 3606, MVNI, q, rd, 0, cmode, imm8);
+return;
+}
 } else if (is_fimm64(v64, , )) {
 tcg_out_insn(s, 3606, MOVI, q, rd, 1, cmode, imm8);
 return;
-- 
2.17.1




[Qemu-devel] [PULL 12/16] tcg/aarch64: Split up is_fimm

2019-05-22 Thread Richard Henderson
There are several sub-classes of vector immediate, and only MOVI
can use them all.  This will enable usage of MVNI and ORRI, which
use progressively fewer sub-classes.

This patch adds no new functionality, merely splits the function
and moves part of the logic into tcg_out_dupi_vec.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 205 ---
 1 file changed, 120 insertions(+), 85 deletions(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index e99149cda7..1422dfebe2 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -190,103 +190,86 @@ static inline bool is_limm(uint64_t val)
 return (val & (val - 1)) == 0;
 }
 
-/* Match a constant that is valid for vectors.  */
-static bool is_fimm(uint64_t v64, int *op, int *cmode, int *imm8)
+/* Return true if v16 is a valid 16-bit shifted immediate.  */
+static bool is_shimm16(uint16_t v16, int *cmode, int *imm8)
 {
-int i;
-
-*op = 0;
-/* Match replication across 8 bits.  */
-if (v64 == dup_const(MO_8, v64)) {
-*cmode = 0xe;
-*imm8 = v64 & 0xff;
+if (v16 == (v16 & 0xff)) {
+*cmode = 0x8;
+*imm8 = v16 & 0xff;
+return true;
+} else if (v16 == (v16 & 0xff00)) {
+*cmode = 0xa;
+*imm8 = v16 >> 8;
 return true;
 }
-/* Match replication across 16 bits.  */
-if (v64 == dup_const(MO_16, v64)) {
-uint16_t v16 = v64;
+return false;
+}
 
-if (v16 == (v16 & 0xff)) {
-*cmode = 0x8;
-*imm8 = v16 & 0xff;
-return true;
-} else if (v16 == (v16 & 0xff00)) {
-*cmode = 0xa;
-*imm8 = v16 >> 8;
-return true;
-}
+/* Return true if v32 is a valid 32-bit shifted immediate.  */
+static bool is_shimm32(uint32_t v32, int *cmode, int *imm8)
+{
+if (v32 == (v32 & 0xff)) {
+*cmode = 0x0;
+*imm8 = v32 & 0xff;
+return true;
+} else if (v32 == (v32 & 0xff00)) {
+*cmode = 0x2;
+*imm8 = (v32 >> 8) & 0xff;
+return true;
+} else if (v32 == (v32 & 0xff)) {
+*cmode = 0x4;
+*imm8 = (v32 >> 16) & 0xff;
+return true;
+} else if (v32 == (v32 & 0xff00)) {
+*cmode = 0x6;
+*imm8 = v32 >> 24;
+return true;
 }
-/* Match replication across 32 bits.  */
-if (v64 == dup_const(MO_32, v64)) {
-uint32_t v32 = v64;
+return false;
+}
 
-if (v32 == (v32 & 0xff)) {
-*cmode = 0x0;
-*imm8 = v32 & 0xff;
-return true;
-} else if (v32 == (v32 & 0xff00)) {
-*cmode = 0x2;
-*imm8 = (v32 >> 8) & 0xff;
-return true;
-} else if (v32 == (v32 & 0xff)) {
-*cmode = 0x4;
-*imm8 = (v32 >> 16) & 0xff;
-return true;
-} else if (v32 == (v32 & 0xff00)) {
-*cmode = 0x6;
-*imm8 = v32 >> 24;
-return true;
-} else if ((v32 & 0x00ff) == 0xff) {
-*cmode = 0xc;
-*imm8 = (v32 >> 8) & 0xff;
-return true;
-} else if ((v32 & 0xff00) == 0x) {
-*cmode = 0xd;
-*imm8 = (v32 >> 16) & 0xff;
-return true;
-}
-/* Match forms of a float32.  */
-if (extract32(v32, 0, 19) == 0
-&& (extract32(v32, 25, 6) == 0x20
-|| extract32(v32, 25, 6) == 0x1f)) {
-*cmode = 0xf;
-*imm8 = (extract32(v32, 31, 1) << 7)
-  | (extract32(v32, 25, 1) << 6)
-  | extract32(v32, 19, 6);
-return true;
-}
+/* Return true if v32 is a valid 32-bit shifting ones immediate.  */
+static bool is_soimm32(uint32_t v32, int *cmode, int *imm8)
+{
+if ((v32 & 0x00ff) == 0xff) {
+*cmode = 0xc;
+*imm8 = (v32 >> 8) & 0xff;
+return true;
+} else if ((v32 & 0xff00) == 0x) {
+*cmode = 0xd;
+*imm8 = (v32 >> 16) & 0xff;
+return true;
 }
-/* Match forms of a float64.  */
+return false;
+}
+
+/* Return true if v32 is a valid float32 immediate.  */
+static bool is_fimm32(uint32_t v32, int *cmode, int *imm8)
+{
+if (extract32(v32, 0, 19) == 0
+&& (extract32(v32, 25, 6) == 0x20
+|| extract32(v32, 25, 6) == 0x1f)) {
+*cmode = 0xf;
+*imm8 = (extract32(v32, 31, 1) << 7)
+  | (extract32(v32, 25, 1) << 6)
+  | extract32(v32, 19, 6);
+return true;
+}
+return false;
+}
+
+/* Return true if v64 is a valid float64 immediate.  */
+static bool is_fimm64(uint64_t v64, int *cmode, int *imm8)
+{
 if (extract64(v64, 0, 48) == 0
 && (extract64(v64, 54, 9) == 0x100
 || extract64(v64, 54, 9) == 0x0ff)) {
 *cmode = 0xf;
-*op = 1;
 *imm8 = (extract64(v64, 63, 1) << 7)
  

[Qemu-devel] [PULL 16/16] tcg/i386: Use MOVDQA for TCG_TYPE_V128 load/store

2019-05-22 Thread Richard Henderson
This instruction raises #GP, aka SIGSEGV, if the effective address
is not aligned to 16-bytes.

We have assertions in tcg-op-gvec.c that the offset from ENV is
aligned, for vector types <= V128.  But the offset itself does not
validate that the final pointer is aligned -- one must also remember
to use the QEMU_ALIGNED() attribute on the vector member within ENV.

PowerPC Altivec has vector load/store instructions that silently
discard the low 4 bits of the address, making alignment mistakes
difficult to discover.  Aid that by making the most popular host
visibly signal the error.

Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.inc.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 6ec5e60448..c0443da4af 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -1082,14 +1082,24 @@ static void tcg_out_ld(TCGContext *s, TCGType type, 
TCGReg ret,
 }
 /* FALLTHRU */
 case TCG_TYPE_V64:
+/* There is no instruction that can validate 8-byte alignment.  */
 tcg_debug_assert(ret >= 16);
 tcg_out_vex_modrm_offset(s, OPC_MOVQ_VqWq, ret, 0, arg1, arg2);
 break;
 case TCG_TYPE_V128:
+/*
+ * The gvec infrastructure is asserts that v128 vector loads
+ * and stores use a 16-byte aligned offset.  Validate that the
+ * final pointer is aligned by using an insn that will SIGSEGV.
+ */
 tcg_debug_assert(ret >= 16);
-tcg_out_vex_modrm_offset(s, OPC_MOVDQU_VxWx, ret, 0, arg1, arg2);
+tcg_out_vex_modrm_offset(s, OPC_MOVDQA_VxWx, ret, 0, arg1, arg2);
 break;
 case TCG_TYPE_V256:
+/*
+ * The gvec infrastructure only requires 16-byte alignment,
+ * so here we must use an unaligned load.
+ */
 tcg_debug_assert(ret >= 16);
 tcg_out_vex_modrm_offset(s, OPC_MOVDQU_VxWx | P_VEXL,
  ret, 0, arg1, arg2);
@@ -1117,14 +1127,24 @@ static void tcg_out_st(TCGContext *s, TCGType type, 
TCGReg arg,
 }
 /* FALLTHRU */
 case TCG_TYPE_V64:
+/* There is no instruction that can validate 8-byte alignment.  */
 tcg_debug_assert(arg >= 16);
 tcg_out_vex_modrm_offset(s, OPC_MOVQ_WqVq, arg, 0, arg1, arg2);
 break;
 case TCG_TYPE_V128:
+/*
+ * The gvec infrastructure is asserts that v128 vector loads
+ * and stores use a 16-byte aligned offset.  Validate that the
+ * final pointer is aligned by using an insn that will SIGSEGV.
+ */
 tcg_debug_assert(arg >= 16);
-tcg_out_vex_modrm_offset(s, OPC_MOVDQU_WxVx, arg, 0, arg1, arg2);
+tcg_out_vex_modrm_offset(s, OPC_MOVDQA_WxVx, arg, 0, arg1, arg2);
 break;
 case TCG_TYPE_V256:
+/*
+ * The gvec infrastructure only requires 16-byte alignment,
+ * so here we must use an unaligned store.
+ */
 tcg_debug_assert(arg >= 16);
 tcg_out_vex_modrm_offset(s, OPC_MOVDQU_WxVx | P_VEXL,
  arg, 0, arg1, arg2);
-- 
2.17.1




[Qemu-devel] [PULL 10/16] tcg/i386: Use umin/umax in expanding unsigned compare

2019-05-22 Thread Richard Henderson
Using umin(a, b) == a as an expansion for TCG_COND_LEU is a
better alternative to (a - INT_MIN) <= (b - INT_MIN).

Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.inc.c | 80 +--
 1 file changed, 61 insertions(+), 19 deletions(-)

diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 569a2c2120..6ec5e60448 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -3468,28 +3468,61 @@ static bool expand_vec_cmp_noinv(TCGType type, unsigned 
vece, TCGv_vec v0,
  TCGv_vec v1, TCGv_vec v2, TCGCond cond)
 {
 enum {
-NEED_SWAP = 1,
-NEED_INV  = 2,
-NEED_BIAS = 4
-};
-static const uint8_t fixups[16] = {
-[0 ... 15] = -1,
-[TCG_COND_EQ] = 0,
-[TCG_COND_NE] = NEED_INV,
-[TCG_COND_GT] = 0,
-[TCG_COND_LT] = NEED_SWAP,
-[TCG_COND_LE] = NEED_INV,
-[TCG_COND_GE] = NEED_SWAP | NEED_INV,
-[TCG_COND_GTU] = NEED_BIAS,
-[TCG_COND_LTU] = NEED_BIAS | NEED_SWAP,
-[TCG_COND_LEU] = NEED_BIAS | NEED_INV,
-[TCG_COND_GEU] = NEED_BIAS | NEED_SWAP | NEED_INV,
+NEED_INV  = 1,
+NEED_SWAP = 2,
+NEED_BIAS = 4,
+NEED_UMIN = 8,
+NEED_UMAX = 16,
 };
 TCGv_vec t1, t2;
 uint8_t fixup;
 
-fixup = fixups[cond & 15];
-tcg_debug_assert(fixup != 0xff);
+switch (cond) {
+case TCG_COND_EQ:
+case TCG_COND_GT:
+fixup = 0;
+break;
+case TCG_COND_NE:
+case TCG_COND_LE:
+fixup = NEED_INV;
+break;
+case TCG_COND_LT:
+fixup = NEED_SWAP;
+break;
+case TCG_COND_GE:
+fixup = NEED_SWAP | NEED_INV;
+break;
+case TCG_COND_LEU:
+if (vece <= MO_32) {
+fixup = NEED_UMIN;
+} else {
+fixup = NEED_BIAS | NEED_INV;
+}
+break;
+case TCG_COND_GTU:
+if (vece <= MO_32) {
+fixup = NEED_UMIN | NEED_INV;
+} else {
+fixup = NEED_BIAS;
+}
+break;
+case TCG_COND_GEU:
+if (vece <= MO_32) {
+fixup = NEED_UMAX;
+} else {
+fixup = NEED_BIAS | NEED_SWAP | NEED_INV;
+}
+break;
+case TCG_COND_LTU:
+if (vece <= MO_32) {
+fixup = NEED_UMAX | NEED_INV;
+} else {
+fixup = NEED_BIAS | NEED_SWAP;
+}
+break;
+default:
+g_assert_not_reached();
+}
 
 if (fixup & NEED_INV) {
 cond = tcg_invert_cond(cond);
@@ -3500,7 +3533,16 @@ static bool expand_vec_cmp_noinv(TCGType type, unsigned 
vece, TCGv_vec v0,
 }
 
 t1 = t2 = NULL;
-if (fixup & NEED_BIAS) {
+if (fixup & (NEED_UMIN | NEED_UMAX)) {
+t1 = tcg_temp_new_vec(type);
+if (fixup & NEED_UMIN) {
+tcg_gen_umin_vec(vece, t1, v1, v2);
+} else {
+tcg_gen_umax_vec(vece, t1, v1, v2);
+}
+v2 = t1;
+cond = TCG_COND_EQ;
+} else if (fixup & NEED_BIAS) {
 t1 = tcg_temp_new_vec(type);
 t2 = tcg_temp_new_vec(type);
 tcg_gen_dupi_vec(vece, t2, 1ull << ((8 << vece) - 1));
-- 
2.17.1




[Qemu-devel] [PULL 07/16] tcg: Add TCG_OPF_NOT_PRESENT if TCG_TARGET_HAS_foo is negative

2019-05-22 Thread Richard Henderson
If INDEX_op_foo is always expanded by tcg_expand_vec_op, then
there may be no reasonable set of constraints to return from
tcg_target_op_def for that opcode.

Let TCG_TARGET_HAS_foo be specified as -1 in that case.  Thus a
boolean test for TCG_TARGET_HAS_foo is true, but we will not
assert within process_op_defs when no constraints are specified.

Compare this with tcg_can_emit_vec_op, which already uses this
tri-state indication.

Signed-off-by: Richard Henderson 
---
 tcg/tcg-opc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index c7d971fa3d..242d608e6d 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -35,7 +35,7 @@ DEF(call, 0, 0, 3, TCG_OPF_CALL_CLOBBER | TCG_OPF_NOT_PRESENT)
 
 DEF(br, 0, 0, 1, TCG_OPF_BB_END)
 
-#define IMPL(X) (__builtin_constant_p(X) && !(X) ? TCG_OPF_NOT_PRESENT : 0)
+#define IMPL(X) (__builtin_constant_p(X) && (X) <= 0 ? TCG_OPF_NOT_PRESENT : 0)
 #if TCG_TARGET_REG_BITS == 32
 # define IMPL64  TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT
 #else
-- 
2.17.1




[Qemu-devel] [PULL 08/16] tcg/i386: Support vector comparison select value

2019-05-22 Thread Richard Henderson
We already had backend support for this feature.  Expand the new
cmpsel opcode using vpblendb.  The combination allows us to avoid
an extra NOT for some comparison codes.

Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.h |  2 +-
 tcg/i386/tcg-target.inc.c | 39 +++
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 16a83a7f7b..928e8b87bb 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -191,7 +191,7 @@ extern bool have_avx2;
 #define TCG_TARGET_HAS_sat_vec  1
 #define TCG_TARGET_HAS_minmax_vec   1
 #define TCG_TARGET_HAS_bitsel_vec   0
-#define TCG_TARGET_HAS_cmpsel_vec   0
+#define TCG_TARGET_HAS_cmpsel_vec   -1
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) \
 (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index b3601446cd..ffcafb1e14 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -3246,6 +3246,7 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 case INDEX_op_andc_vec:
 return 1;
 case INDEX_op_cmp_vec:
+case INDEX_op_cmpsel_vec:
 return -1;
 
 case INDEX_op_shli_vec:
@@ -3464,8 +3465,8 @@ static void expand_vec_mul(TCGType type, unsigned vece,
 }
 }
 
-static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
-   TCGv_vec v1, TCGv_vec v2, TCGCond cond)
+static bool expand_vec_cmp_noinv(TCGType type, unsigned vece, TCGv_vec v0,
+ TCGv_vec v1, TCGv_vec v2, TCGCond cond)
 {
 enum {
 NEED_SWAP = 1,
@@ -3522,11 +3523,34 @@ static void expand_vec_cmp(TCGType type, unsigned vece, 
TCGv_vec v0,
 tcg_temp_free_vec(t2);
 }
 }
-if (fixup & NEED_INV) {
+return fixup & NEED_INV;
+}
+
+static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
+   TCGv_vec v1, TCGv_vec v2, TCGCond cond)
+{
+if (expand_vec_cmp_noinv(type, vece, v0, v1, v2, cond)) {
 tcg_gen_not_vec(vece, v0, v0);
 }
 }
 
+static void expand_vec_cmpsel(TCGType type, unsigned vece, TCGv_vec v0,
+  TCGv_vec c1, TCGv_vec c2,
+  TCGv_vec v3, TCGv_vec v4, TCGCond cond)
+{
+TCGv_vec t = tcg_temp_new_vec(type);
+
+if (expand_vec_cmp_noinv(type, vece, t, c1, c2, cond)) {
+/* Invert the sense of the compare by swapping arguments.  */
+TCGv_vec x;
+x = v3, v3 = v4, v4 = x;
+}
+vec_gen_4(INDEX_op_x86_vpblendvb_vec, type, vece,
+  tcgv_vec_arg(v0), tcgv_vec_arg(v4),
+  tcgv_vec_arg(v3), tcgv_vec_arg(t));
+tcg_temp_free_vec(t);
+}
+
 static void expand_vec_minmax(TCGType type, unsigned vece,
   TCGCond cond, bool min,
   TCGv_vec v0, TCGv_vec v1, TCGv_vec v2)
@@ -3551,7 +3575,7 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece,
 {
 va_list va;
 TCGArg a2;
-TCGv_vec v0, v1, v2;
+TCGv_vec v0, v1, v2, v3, v4;
 
 va_start(va, a0);
 v0 = temp_tcgv_vec(arg_temp(a0));
@@ -3578,6 +3602,13 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece,
 expand_vec_cmp(type, vece, v0, v1, v2, va_arg(va, TCGArg));
 break;
 
+case INDEX_op_cmpsel_vec:
+v2 = temp_tcgv_vec(arg_temp(a2));
+v3 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
+v4 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
+expand_vec_cmpsel(type, vece, v0, v1, v2, v3, v4, va_arg(va, TCGArg));
+break;
+
 case INDEX_op_smin_vec:
 v2 = temp_tcgv_vec(arg_temp(a2));
 expand_vec_minmax(type, vece, TCG_COND_GT, true, v0, v1, v2);
-- 
2.17.1




[Qemu-devel] [PULL 09/16] tcg/i386: Remove expansion for missing minmax

2019-05-22 Thread Richard Henderson
This is now handled by code within tcg-op-vec.c.

Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.inc.c | 37 -
 1 file changed, 37 deletions(-)

diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index ffcafb1e14..569a2c2120 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -3297,7 +3297,6 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece)
 case INDEX_op_smax_vec:
 case INDEX_op_umin_vec:
 case INDEX_op_umax_vec:
-return vece <= MO_32 ? 1 : -1;
 case INDEX_op_abs_vec:
 return vece <= MO_32;
 
@@ -3551,25 +3550,6 @@ static void expand_vec_cmpsel(TCGType type, unsigned 
vece, TCGv_vec v0,
 tcg_temp_free_vec(t);
 }
 
-static void expand_vec_minmax(TCGType type, unsigned vece,
-  TCGCond cond, bool min,
-  TCGv_vec v0, TCGv_vec v1, TCGv_vec v2)
-{
-TCGv_vec t1 = tcg_temp_new_vec(type);
-
-tcg_debug_assert(vece == MO_64);
-
-tcg_gen_cmp_vec(cond, vece, t1, v1, v2);
-if (min) {
-TCGv_vec t2;
-t2 = v1, v1 = v2, v2 = t2;
-}
-vec_gen_4(INDEX_op_x86_vpblendvb_vec, type, vece,
-  tcgv_vec_arg(v0), tcgv_vec_arg(v1),
-  tcgv_vec_arg(v2), tcgv_vec_arg(t1));
-tcg_temp_free_vec(t1);
-}
-
 void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
TCGArg a0, ...)
 {
@@ -3609,23 +3589,6 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, 
unsigned vece,
 expand_vec_cmpsel(type, vece, v0, v1, v2, v3, v4, va_arg(va, TCGArg));
 break;
 
-case INDEX_op_smin_vec:
-v2 = temp_tcgv_vec(arg_temp(a2));
-expand_vec_minmax(type, vece, TCG_COND_GT, true, v0, v1, v2);
-break;
-case INDEX_op_smax_vec:
-v2 = temp_tcgv_vec(arg_temp(a2));
-expand_vec_minmax(type, vece, TCG_COND_GT, false, v0, v1, v2);
-break;
-case INDEX_op_umin_vec:
-v2 = temp_tcgv_vec(arg_temp(a2));
-expand_vec_minmax(type, vece, TCG_COND_GTU, true, v0, v1, v2);
-break;
-case INDEX_op_umax_vec:
-v2 = temp_tcgv_vec(arg_temp(a2));
-expand_vec_minmax(type, vece, TCG_COND_GTU, false, v0, v1, v2);
-break;
-
 default:
 break;
 }
-- 
2.17.1




[Qemu-devel] [PULL 14/16] tcg/aarch64: Build vector immediates with two insns

2019-05-22 Thread Richard Henderson
Use MOVI+ORR or MVNI+BIC in order to build some vector constants,
as opposed to dropping them to the constant pool.  This includes
all 16-bit constants and a similar set of 32-bit constants.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 47 
 1 file changed, 47 insertions(+)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 0b8b733805..52c18074ae 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -273,6 +273,26 @@ static bool is_fimm64(uint64_t v64, int *cmode, int *imm8)
 return false;
 }
 
+/*
+ * Return non-zero if v32 can be formed by MOVI+ORR.
+ * Place the parameters for MOVI in (cmode, imm8).
+ * Return the cmode for ORR; the imm8 can be had via extraction from v32.
+ */
+static int is_shimm32_pair(uint32_t v32, int *cmode, int *imm8)
+{
+int i;
+
+for (i = 6; i > 0; i -= 2) {
+/* Mask out one byte we can add with ORR.  */
+uint32_t tmp = v32 & ~(0xffu << (i * 4));
+if (is_shimm32(tmp, cmode, imm8) ||
+is_soimm32(tmp, cmode, imm8)) {
+break;
+}
+}
+return i;
+}
+
 static int tcg_target_const_match(tcg_target_long val, TCGType type,
   const TCGArgConstraint *arg_ct)
 {
@@ -495,6 +515,8 @@ typedef enum {
 /* AdvSIMD modified immediate */
 I3606_MOVI  = 0x0f000400,
 I3606_MVNI  = 0x2f000400,
+I3606_BIC   = 0x2f001400,
+I3606_ORR   = 0x0f001400,
 
 /* AdvSIMD shift by immediate */
 I3614_SSHR  = 0x0f000400,
@@ -843,6 +865,14 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
 tcg_out_insn(s, 3606, MVNI, q, rd, 0, cmode, imm8);
 return;
 }
+
+/*
+ * Otherwise, all remaining constants can be loaded in two insns:
+ * rd = v16 & 0xff, rd |= v16 & 0xff00.
+ */
+tcg_out_insn(s, 3606, MOVI, q, rd, 0, 0x8, v16 & 0xff);
+tcg_out_insn(s, 3606, ORR, q, rd, 0, 0xa, v16 >> 8);
+return;
 } else if (v64 == dup_const(MO_32, v64)) {
 uint32_t v32 = v64;
 uint32_t n32 = ~v32;
@@ -858,6 +888,23 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
 tcg_out_insn(s, 3606, MVNI, q, rd, 0, cmode, imm8);
 return;
 }
+
+/*
+ * Restrict the set of constants to those we can load with
+ * two instructions.  Others we load from the pool.
+ */
+i = is_shimm32_pair(v32, , );
+if (i) {
+tcg_out_insn(s, 3606, MOVI, q, rd, 0, cmode, imm8);
+tcg_out_insn(s, 3606, ORR, q, rd, 0, i, extract32(v32, i * 4, 8));
+return;
+}
+i = is_shimm32_pair(n32, , );
+if (i) {
+tcg_out_insn(s, 3606, MVNI, q, rd, 0, cmode, imm8);
+tcg_out_insn(s, 3606, BIC, q, rd, 0, i, extract32(n32, i * 4, 8));
+return;
+}
 } else if (is_fimm64(v64, , )) {
 tcg_out_insn(s, 3606, MOVI, q, rd, 1, cmode, imm8);
 return;
-- 
2.17.1




[Qemu-devel] [PULL 00/16] tcg queued patches

2019-05-22 Thread Richard Henderson
The following changes since commit a4f667b6714916683408b983cfe0a615a725775f:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190521-3' into 
staging (2019-05-21 16:30:13 +0100)

are available in the Git repository at:

  https://github.com/rth7680/qemu.git tags/pull-tcg-20190522

for you to fetch changes up to 11e2bfef799024be4a08fcf6797fe0b22fb16b58:

  tcg/i386: Use MOVDQA for TCG_TYPE_V128 load/store (2019-05-22 15:09:43 -0400)


Misc gvec improvements


Richard Henderson (16):
  tcg/i386: Fix dupi/dupm for avx1 and 32-bit hosts
  tcg: Fix missing checks and clears in tcg_gen_gvec_dup_mem
  tcg: Add support for vector bitwise select
  tcg: Add support for vector compare select
  tcg: Introduce do_op3_nofail for vector expansion
  tcg: Expand vector minmax using cmp+cmpsel
  tcg: Add TCG_OPF_NOT_PRESENT if TCG_TARGET_HAS_foo is negative
  tcg/i386: Support vector comparison select value
  tcg/i386: Remove expansion for missing minmax
  tcg/i386: Use umin/umax in expanding unsigned compare
  tcg/aarch64: Support vector bitwise select value
  tcg/aarch64: Split up is_fimm
  tcg/aarch64: Use MVNI in tcg_out_dupi_vec
  tcg/aarch64: Build vector immediates with two insns
  tcg/aarch64: Allow immediates for vector ORR and BIC
  tcg/i386: Use MOVDQA for TCG_TYPE_V128 load/store

 accel/tcg/tcg-runtime.h  |   2 +
 tcg/aarch64/tcg-target.h |   2 +
 tcg/i386/tcg-target.h|   2 +
 tcg/tcg-op-gvec.h|   7 +
 tcg/tcg-op.h |   5 +
 tcg/tcg-opc.h|   5 +-
 tcg/tcg.h|   2 +
 accel/tcg/tcg-runtime-gvec.c |  14 ++
 tcg/aarch64/tcg-target.inc.c | 371 ---
 tcg/i386/tcg-target.inc.c| 169 +---
 tcg/tcg-op-gvec.c|  71 ++---
 tcg/tcg-op-vec.c | 142 ++---
 tcg/tcg.c|   5 +
 tcg/README   |  11 ++
 14 files changed, 620 insertions(+), 188 deletions(-)



[Qemu-devel] [PULL 04/16] tcg: Add support for vector compare select

2019-05-22 Thread Richard Henderson
Perform a per-element conditional move.  This combination operation is
easier to implement on some host vector units than plain cmp+bitsel.
Omit the usual gvec interface, as this is intended to be used by
target-specific gvec expansion call-backs.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  1 +
 tcg/i386/tcg-target.h|  1 +
 tcg/tcg-op.h |  2 ++
 tcg/tcg-opc.h|  1 +
 tcg/tcg.h|  1 +
 tcg/tcg-op-vec.c | 59 
 tcg/tcg.c|  3 ++
 tcg/README   |  7 +
 8 files changed, 75 insertions(+)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 52ee66424f..b4a9d36bbc 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -141,6 +141,7 @@ typedef enum {
 #define TCG_TARGET_HAS_sat_vec  1
 #define TCG_TARGET_HAS_minmax_vec   1
 #define TCG_TARGET_HAS_bitsel_vec   0
+#define TCG_TARGET_HAS_cmpsel_vec   0
 
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 08a0386433..16a83a7f7b 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -191,6 +191,7 @@ extern bool have_avx2;
 #define TCG_TARGET_HAS_sat_vec  1
 #define TCG_TARGET_HAS_minmax_vec   1
 #define TCG_TARGET_HAS_bitsel_vec   0
+#define TCG_TARGET_HAS_cmpsel_vec   0
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) \
 (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 268860ed2f..2d4dd5cd7d 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -1002,6 +1002,8 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, 
TCGv_vec r,
 
 void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a,
 TCGv_vec b, TCGv_vec c);
+void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r,
+TCGv_vec a, TCGv_vec b, TCGv_vec c, TCGv_vec d);
 
 void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset);
 void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset);
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index c05b71427c..c7d971fa3d 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -257,6 +257,7 @@ DEF(sarv_vec, 1, 2, 0, IMPLVEC | 
IMPL(TCG_TARGET_HAS_shv_vec))
 DEF(cmp_vec, 1, 2, 1, IMPLVEC)
 
 DEF(bitsel_vec, 1, 3, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_bitsel_vec))
+DEF(cmpsel_vec, 1, 4, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_cmpsel_vec))
 
 DEF(last_generic, 0, 0, 0, TCG_OPF_NOT_PRESENT)
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 72f9f6c70b..21cd6f1249 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -188,6 +188,7 @@ typedef uint64_t TCGRegSet;
 #define TCG_TARGET_HAS_sat_vec  0
 #define TCG_TARGET_HAS_minmax_vec   0
 #define TCG_TARGET_HAS_bitsel_vec   0
+#define TCG_TARGET_HAS_cmpsel_vec   0
 #else
 #define TCG_TARGET_MAYBE_vec1
 #endif
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
index 99cbf29e0b..a888c02df8 100644
--- a/tcg/tcg-op-vec.c
+++ b/tcg/tcg-op-vec.c
@@ -119,6 +119,11 @@ bool tcg_can_emit_vecop_list(const TCGOpcode *list,
 continue;
 }
 break;
+case INDEX_op_cmpsel_vec:
+if (tcg_can_emit_vec_op(INDEX_op_cmp_vec, type, vece)) {
+continue;
+}
+break;
 default:
 break;
 }
@@ -159,6 +164,20 @@ void vec_gen_4(TCGOpcode opc, TCGType type, unsigned vece,
 op->args[3] = c;
 }
 
+static void vec_gen_6(TCGOpcode opc, TCGType type, unsigned vece, TCGArg r,
+  TCGArg a, TCGArg b, TCGArg c, TCGArg d, TCGArg e)
+{
+TCGOp *op = tcg_emit_op(opc);
+TCGOP_VECL(op) = type - TCG_TYPE_V64;
+TCGOP_VECE(op) = vece;
+op->args[0] = r;
+op->args[1] = a;
+op->args[2] = b;
+op->args[3] = c;
+op->args[4] = d;
+op->args[5] = e;
+}
+
 static void vec_gen_op2(TCGOpcode opc, unsigned vece, TCGv_vec r, TCGv_vec a)
 {
 TCGTemp *rt = tcgv_vec_temp(r);
@@ -717,3 +736,43 @@ void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, 
TCGv_vec a,
 tcg_temp_free_vec(t);
 }
 }
+
+void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r,
+TCGv_vec a, TCGv_vec b, TCGv_vec c, TCGv_vec d)
+{
+TCGTemp *rt = tcgv_vec_temp(r);
+TCGTemp *at = tcgv_vec_temp(a);
+TCGTemp *bt = tcgv_vec_temp(b);
+TCGTemp *ct = tcgv_vec_temp(c);
+TCGTemp *dt = tcgv_vec_temp(d);
+TCGArg ri = temp_arg(rt);
+TCGArg ai = temp_arg(at);
+TCGArg bi = temp_arg(bt);
+TCGArg ci = temp_arg(ct);
+TCGArg di = temp_arg(dt);
+TCGType type = rt->base_type;
+const TCGOpcode *hold_list;
+int can;
+
+tcg_debug_assert(at->base_type >= type);
+tcg_debug_assert(bt->base_type >= type);
+tcg_debug_assert(ct->base_type >= type);
+tcg_debug_assert(dt->base_type >= type);
+
+tcg_assert_listed_vecop(INDEX_op_cmpsel_vec);

[Qemu-devel] [PULL 05/16] tcg: Introduce do_op3_nofail for vector expansion

2019-05-22 Thread Richard Henderson
This makes do_op3 match do_op2 in allowing for failure,
and thus fall back expansions.

Signed-off-by: Richard Henderson 
---
 tcg/tcg-op-vec.c | 45 +++--
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
index a888c02df8..004a34935b 100644
--- a/tcg/tcg-op-vec.c
+++ b/tcg/tcg-op-vec.c
@@ -562,7 +562,7 @@ void tcg_gen_cmp_vec(TCGCond cond, unsigned vece,
 }
 }
 
-static void do_op3(unsigned vece, TCGv_vec r, TCGv_vec a,
+static bool do_op3(unsigned vece, TCGv_vec r, TCGv_vec a,
TCGv_vec b, TCGOpcode opc)
 {
 TCGTemp *rt = tcgv_vec_temp(r);
@@ -580,82 +580,91 @@ static void do_op3(unsigned vece, TCGv_vec r, TCGv_vec a,
 can = tcg_can_emit_vec_op(opc, type, vece);
 if (can > 0) {
 vec_gen_3(opc, type, vece, ri, ai, bi);
-} else {
+} else if (can < 0) {
 const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL);
-tcg_debug_assert(can < 0);
 tcg_expand_vec_op(opc, type, vece, ri, ai, bi);
 tcg_swap_vecop_list(hold_list);
+} else {
+return false;
 }
+return true;
+}
+
+static void do_op3_nofail(unsigned vece, TCGv_vec r, TCGv_vec a,
+  TCGv_vec b, TCGOpcode opc)
+{
+bool ok = do_op3(vece, r, a, b, opc);
+tcg_debug_assert(ok);
 }
 
 void tcg_gen_add_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_add_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_add_vec);
 }
 
 void tcg_gen_sub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_sub_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_sub_vec);
 }
 
 void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_mul_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_mul_vec);
 }
 
 void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_ssadd_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_ssadd_vec);
 }
 
 void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_usadd_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_usadd_vec);
 }
 
 void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_sssub_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_sssub_vec);
 }
 
 void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_ussub_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_ussub_vec);
 }
 
 void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_smin_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_smin_vec);
 }
 
 void tcg_gen_umin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_umin_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_umin_vec);
 }
 
 void tcg_gen_smax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_smax_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_smax_vec);
 }
 
 void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_umax_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_umax_vec);
 }
 
 void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_shlv_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_shlv_vec);
 }
 
 void tcg_gen_shrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_shrv_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_shrv_vec);
 }
 
 void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3(vece, r, a, b, INDEX_op_sarv_vec);
+do_op3_nofail(vece, r, a, b, INDEX_op_sarv_vec);
 }
 
 static void do_shifts(unsigned vece, TCGv_vec r, TCGv_vec a,
@@ -691,7 +700,7 @@ static void do_shifts(unsigned vece, TCGv_vec r, TCGv_vec a,
 } else {
 tcg_gen_dup_i32_vec(vece, vec_s, s);
 }
-do_op3(vece, r, a, vec_s, opc_v);
+do_op3_nofail(vece, r, a, vec_s, opc_v);
 tcg_temp_free_vec(vec_s);
 }
 tcg_swap_vecop_list(hold_list);
-- 
2.17.1




[Qemu-devel] [PULL 06/16] tcg: Expand vector minmax using cmp+cmpsel

2019-05-22 Thread Richard Henderson
Provide a generic fallback for the min/max operations.

Signed-off-by: Richard Henderson 
---
 tcg/tcg-op-vec.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
index 004a34935b..501d9630a2 100644
--- a/tcg/tcg-op-vec.c
+++ b/tcg/tcg-op-vec.c
@@ -120,6 +120,10 @@ bool tcg_can_emit_vecop_list(const TCGOpcode *list,
 }
 break;
 case INDEX_op_cmpsel_vec:
+case INDEX_op_smin_vec:
+case INDEX_op_smax_vec:
+case INDEX_op_umin_vec:
+case INDEX_op_umax_vec:
 if (tcg_can_emit_vec_op(INDEX_op_cmp_vec, type, vece)) {
 continue;
 }
@@ -632,24 +636,32 @@ void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, 
TCGv_vec a, TCGv_vec b)
 do_op3_nofail(vece, r, a, b, INDEX_op_ussub_vec);
 }
 
+static void do_minmax(unsigned vece, TCGv_vec r, TCGv_vec a,
+  TCGv_vec b, TCGOpcode opc, TCGCond cond)
+{
+if (!do_op3(vece, r, a, b, opc)) {
+tcg_gen_cmpsel_vec(cond, vece, r, a, b, a, b);
+}
+}
+
 void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3_nofail(vece, r, a, b, INDEX_op_smin_vec);
+do_minmax(vece, r, a, b, INDEX_op_smin_vec, TCG_COND_LT);
 }
 
 void tcg_gen_umin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3_nofail(vece, r, a, b, INDEX_op_umin_vec);
+do_minmax(vece, r, a, b, INDEX_op_umin_vec, TCG_COND_LTU);
 }
 
 void tcg_gen_smax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3_nofail(vece, r, a, b, INDEX_op_smax_vec);
+do_minmax(vece, r, a, b, INDEX_op_smax_vec, TCG_COND_GT);
 }
 
 void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
 {
-do_op3_nofail(vece, r, a, b, INDEX_op_umax_vec);
+do_minmax(vece, r, a, b, INDEX_op_umax_vec, TCG_COND_GTU);
 }
 
 void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
-- 
2.17.1




[Qemu-devel] [PULL 02/16] tcg: Fix missing checks and clears in tcg_gen_gvec_dup_mem

2019-05-22 Thread Richard Henderson
The paths through tcg_gen_dup_mem_vec and through MO_128 were
missing the check_size_align.  The path through MO_128 was also
missing the expand_clr.  This last was not visible because the
only user is ARM SVE, which would set oprsz == maxsz, and not
require the clear.

Fix by adding the check_size_align and using do_dup directly
instead of duplicating the check in tcg_gen_gvec_dup_{i32,i64}.

Signed-off-by: Richard Henderson 
---
 tcg/tcg-op-gvec.c | 48 ---
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index 338ddd9d9e..bbf70e3cd9 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -1446,36 +1446,35 @@ void tcg_gen_gvec_dup_i64(unsigned vece, uint32_t dofs, 
uint32_t oprsz,
 void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
   uint32_t oprsz, uint32_t maxsz)
 {
+check_size_align(oprsz, maxsz, dofs);
 if (vece <= MO_64) {
-TCGType type = choose_vector_type(0, vece, oprsz, 0);
+TCGType type = choose_vector_type(NULL, vece, oprsz, 0);
 if (type != 0) {
 TCGv_vec t_vec = tcg_temp_new_vec(type);
 tcg_gen_dup_mem_vec(vece, t_vec, cpu_env, aofs);
 do_dup_store(type, dofs, oprsz, maxsz, t_vec);
 tcg_temp_free_vec(t_vec);
-return;
+} else if (vece <= MO_32) {
+TCGv_i32 in = tcg_temp_new_i32();
+switch (vece) {
+case MO_8:
+tcg_gen_ld8u_i32(in, cpu_env, aofs);
+break;
+case MO_16:
+tcg_gen_ld16u_i32(in, cpu_env, aofs);
+break;
+default:
+tcg_gen_ld_i32(in, cpu_env, aofs);
+break;
+}
+do_dup(vece, dofs, oprsz, maxsz, in, NULL, 0);
+tcg_temp_free_i32(in);
+} else {
+TCGv_i64 in = tcg_temp_new_i64();
+tcg_gen_ld_i64(in, cpu_env, aofs);
+do_dup(vece, dofs, oprsz, maxsz, NULL, in, 0);
+tcg_temp_free_i64(in);
 }
-}
-if (vece <= MO_32) {
-TCGv_i32 in = tcg_temp_new_i32();
-switch (vece) {
-case MO_8:
-tcg_gen_ld8u_i32(in, cpu_env, aofs);
-break;
-case MO_16:
-tcg_gen_ld16u_i32(in, cpu_env, aofs);
-break;
-case MO_32:
-tcg_gen_ld_i32(in, cpu_env, aofs);
-break;
-}
-tcg_gen_gvec_dup_i32(vece, dofs, oprsz, maxsz, in);
-tcg_temp_free_i32(in);
-} else if (vece == MO_64) {
-TCGv_i64 in = tcg_temp_new_i64();
-tcg_gen_ld_i64(in, cpu_env, aofs);
-tcg_gen_gvec_dup_i64(MO_64, dofs, oprsz, maxsz, in);
-tcg_temp_free_i64(in);
 } else {
 /* 128-bit duplicate.  */
 /* ??? Dup to 256-bit vector.  */
@@ -1504,6 +1503,9 @@ void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, 
uint32_t aofs,
 tcg_temp_free_i64(in0);
 tcg_temp_free_i64(in1);
 }
+if (oprsz < maxsz) {
+expand_clr(dofs + oprsz, maxsz - oprsz);
+}
 }
 }
 
-- 
2.17.1




[Qemu-devel] [PULL 03/16] tcg: Add support for vector bitwise select

2019-05-22 Thread Richard Henderson
This operation performs d = (b & a) | (c & ~a), and is present
on a majority of host vector units.  Include gvec expanders.

Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-runtime.h  |  2 ++
 tcg/aarch64/tcg-target.h |  1 +
 tcg/i386/tcg-target.h|  1 +
 tcg/tcg-op-gvec.h|  7 +++
 tcg/tcg-op.h |  3 +++
 tcg/tcg-opc.h|  2 ++
 tcg/tcg.h|  1 +
 accel/tcg/tcg-runtime-gvec.c | 14 ++
 tcg/tcg-op-gvec.c| 23 +++
 tcg/tcg-op-vec.c | 26 ++
 tcg/tcg.c|  2 ++
 tcg/README   |  4 
 12 files changed, 86 insertions(+)

diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index 6d73dc2d65..4fa61b49b4 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -303,3 +303,5 @@ DEF_HELPER_FLAGS_4(gvec_leu8, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_leu16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_leu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_leu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index e43554c3c7..52ee66424f 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -140,6 +140,7 @@ typedef enum {
 #define TCG_TARGET_HAS_mul_vec  1
 #define TCG_TARGET_HAS_sat_vec  1
 #define TCG_TARGET_HAS_minmax_vec   1
+#define TCG_TARGET_HAS_bitsel_vec   0
 
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 66f16fbe3c..08a0386433 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -190,6 +190,7 @@ extern bool have_avx2;
 #define TCG_TARGET_HAS_mul_vec  1
 #define TCG_TARGET_HAS_sat_vec  1
 #define TCG_TARGET_HAS_minmax_vec   1
+#define TCG_TARGET_HAS_bitsel_vec   0
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) \
 (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \
diff --git a/tcg/tcg-op-gvec.h b/tcg/tcg-op-gvec.h
index 52a398c190..2a9e0c7c0a 100644
--- a/tcg/tcg-op-gvec.h
+++ b/tcg/tcg-op-gvec.h
@@ -342,6 +342,13 @@ void tcg_gen_gvec_cmp(TCGCond cond, unsigned vece, 
uint32_t dofs,
   uint32_t aofs, uint32_t bofs,
   uint32_t oprsz, uint32_t maxsz);
 
+/*
+ * Perform vector bit select: d = (b & a) | (c & ~a).
+ */
+void tcg_gen_gvec_bitsel(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t cofs,
+ uint32_t oprsz, uint32_t maxsz);
+
 /*
  * 64-bit vector operations.  Use these when the register has been allocated
  * with tcg_global_mem_new_i64, and so we cannot also address it via pointer.
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 660fe205d0..268860ed2f 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -1000,6 +1000,9 @@ void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec 
a, TCGv_vec s);
 void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, TCGv_vec r,
  TCGv_vec a, TCGv_vec b);
 
+void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a,
+TCGv_vec b, TCGv_vec c);
+
 void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset);
 void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset);
 void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index 4a2dd116eb..c05b71427c 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -256,6 +256,8 @@ DEF(sarv_vec, 1, 2, 0, IMPLVEC | 
IMPL(TCG_TARGET_HAS_shv_vec))
 
 DEF(cmp_vec, 1, 2, 1, IMPLVEC)
 
+DEF(bitsel_vec, 1, 3, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_bitsel_vec))
+
 DEF(last_generic, 0, 0, 0, TCG_OPF_NOT_PRESENT)
 
 #if TCG_TARGET_MAYBE_vec
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 0e01a70d66..72f9f6c70b 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -187,6 +187,7 @@ typedef uint64_t TCGRegSet;
 #define TCG_TARGET_HAS_mul_vec  0
 #define TCG_TARGET_HAS_sat_vec  0
 #define TCG_TARGET_HAS_minmax_vec   0
+#define TCG_TARGET_HAS_bitsel_vec   0
 #else
 #define TCG_TARGET_MAYBE_vec1
 #endif
diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index 0f09e0ef38..3b6052fe97 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -1444,3 +1444,17 @@ void HELPER(gvec_umax64)(void *d, void *a, void *b, 
uint32_t desc)
 }
 clear_high(d, oprsz, desc);
 }
+
+void HELPER(gvec_bitsel)(void *d, void *a, void *b, void *c, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+intptr_t i;
+
+for (i = 0; i < oprsz; i += sizeof(vec64)) {
+vec64 aa = *(vec64 *)(a + i);
+vec64 bb = *(vec64 *)(b + i);
+vec64 cc = *(vec64 *)(c + i);
+   

[Qemu-devel] [PULL 01/16] tcg/i386: Fix dupi/dupm for avx1 and 32-bit hosts

2019-05-22 Thread Richard Henderson
The VBROADCASTSD instruction only allows %ymm registers as destination.
Rather than forcing VEX.L and writing to the entire 256-bit register,
revert to using MOVDDUP with an %xmm register.  This is sufficient for
an avx1 host since we do not support TCG_TYPE_V256 for that case.

Also fix the 32-bit avx2, which should have used VPBROADCASTW.

Fixes: 1e262b49b533
Tested-by: Mark Cave-Ayland 
Reported-by: Mark Cave-Ayland 
Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.inc.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index aafd01cb49..b3601446cd 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -358,6 +358,7 @@ static inline int tcg_target_const_match(tcg_target_long 
val, TCGType type,
 #define OPC_MOVBE_MyGy  (0xf1 | P_EXT38)
 #define OPC_MOVD_VyEy   (0x6e | P_EXT | P_DATA16)
 #define OPC_MOVD_EyVy   (0x7e | P_EXT | P_DATA16)
+#define OPC_MOVDDUP (0x12 | P_EXT | P_SIMDF2)
 #define OPC_MOVDQA_VxWx (0x6f | P_EXT | P_DATA16)
 #define OPC_MOVDQA_WxVx (0x7f | P_EXT | P_DATA16)
 #define OPC_MOVDQU_VxWx (0x6f | P_EXT | P_SIMDF3)
@@ -921,7 +922,7 @@ static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, 
unsigned vece,
 } else {
 switch (vece) {
 case MO_64:
-tcg_out_vex_modrm_offset(s, OPC_VBROADCASTSD, r, 0, base, offset);
+tcg_out_vex_modrm_offset(s, OPC_MOVDDUP, r, 0, base, offset);
 break;
 case MO_32:
 tcg_out_vex_modrm_offset(s, OPC_VBROADCASTSS, r, 0, base, offset);
@@ -963,12 +964,12 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
 } else if (have_avx2) {
 tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTQ + vex_l, ret);
 } else {
-tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSD, ret);
+tcg_out_vex_modrm_pool(s, OPC_MOVDDUP, ret);
 }
 new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4);
 } else {
 if (have_avx2) {
-tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSD + vex_l, ret);
+tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTW + vex_l, ret);
 } else {
 tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSS, ret);
 }
-- 
2.17.1




Re: [Qemu-devel] [PULL v2 00/11] MIPS queue for May 19th, 2019 - v2

2019-05-22 Thread Aleksandar Markovic
On May 22, 2019 9:15 PM, "Aleksandar Markovic" <
aleksandar.marko...@rt-rk.com> wrote:
>
> From: Aleksandar Markovic 
>
> The following changes since commit
a4f667b6714916683408b983cfe0a615a725775f:
>
>   Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190521-3'
into staging (2019-05-21 16:30:13 +0100)
>
> are available in the git repository at:
>
>   https://github.com/AMarkovic/qemu tags/mips-queue-may-19-2019-v2
>
> for you to fetch changes up to 9a89468145b8a3e53e508992f54061427c52780f:
>
>   BootLinuxSshTest: Test some userspace commands on Malta (2019-05-22
20:10:46 +0200)
>
> 
>

Peter,

Please put this pull request on hold, there are some reservations from test
group about patch 11/11, that came just hours after I sent this pull
request.

Yours,
Aleksandar

> MIPS queue for May 19th, 2019 - v2
>
> v1-v2:
>- fixed missing invocations in patch on ST. that caused
>  clang build error
>- added a patch on acceptance test for Malta
>
> overall content:
>
>* Improved usage of object_initialize() and object_initialize_child()
>* Added an acceptance test for Malta board
>* Better handling of memory pages (flag PAGE_EXEC)
>* A set of fixes for emulation of MSA ASE on big endian hosts
>* Better handling of 'div by zero' cases of MSA ASE instructions
>
> 
>
> Jakub Jermář (1):
>   mips: Decide to map PAGE_EXEC in map_address
>
> Mateja Marjanovic (7):
>   target/mips: Make the results of DIV_. the same as on
> hardware
>   target/mips: Make the results of MOD_. the same as on
> hardware
>   target/mips: Fix MSA instructions LD. on big endian host
>   target/mips: Fix MSA instructions ST. on big endian host
>   target/mips: Refactor and fix COPY_S. instructions
>   target/mips: Refactor and fix COPY_U. instructions
>   target/mips: Refactor and fix INSERT. instructions
>
> Philippe Mathieu-Daudé (3):
>   hw/mips: Use object_initialize() on MIPSCPSState
>   hw/mips: Use object_initialize_child for correct reference counting
>   BootLinuxSshTest: Test some userspace commands on Malta
>
>  MAINTAINERS  |   1 +
>  hw/mips/boston.c |  25 +-
>  hw/mips/cps.c|  20 +-
>  hw/mips/mips_malta.c |  17 +-
>  target/mips/helper.c |  13 +-
>  target/mips/helper.h |  16 +-
>  target/mips/msa_helper.c | 191 ++-
>  target/mips/op_helper.c  | 388
+++
>  target/mips/translate.c  |  59 -
>  tests/acceptance/linux_ssh_mips_malta.py | 229 ++
>  tests/requirements.txt   |   1 +
>  11 files changed, 817 insertions(+), 143 deletions(-)
>  create mode 100644 tests/acceptance/linux_ssh_mips_malta.py
>
> --
> 2.7.4
>
>


Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests

2019-05-22 Thread Aleksandar Markovic
On May 22, 2019 11:46 PM, "Cleber Rosa"  wrote:
>
>
>
> - Original Message -
> > From: "Eduardo Habkost" 
> > To: "Philippe Mathieu-Daudé" 
> > Cc: qemu-devel@nongnu.org, "Aleksandar Rikalo" ,
"Aleksandar Markovic"
> > , "Aleksandar Markovic" <
amarko...@wavecomp.com>, "Cleber Rosa" ,
> > "Aurelien Jarno" , "Wainer dos Santos Moschetta" <
waine...@redhat.com>
> > Sent: Wednesday, May 22, 2019 5:12:30 PM
> > Subject: Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests
> >
> > On Tue, May 21, 2019 at 01:19:06AM +0200, Philippe Mathieu-Daudé wrote:
> > > Hi,
> > >
> > > It was a rainy week-end here, so I invested it to automatize some
> > > of my MIPS tests.
> > >
> > > The BootLinuxSshTest is not Global warming friendly, it is not
> > > meant to run on a CI system but rather on a workstation previous
> > > to post a pull request.
> > > It can surely be improved, but it is a good starting point.
> >
> > Until we actually have a mechanism to exclude the test case on
> > travis-ci, I will remove patch 4/4 from the queue.  Aleksandar,
> > please don't merge patch 4/4 yet or it will break travis-ci.
> >
> > Cleber, Wainer, is it already possible to make "avocado run" skip
> > tests tagged with "slow"?
> >
>
> The mechanism exists, but we haven't tagged any test so far as slow.
>
> Should we define/document a criteria for a test to be slow?  Given
> that this is highly subjective, we have to think of:
>
>  * Will we consider the average or maximum run time (the timeout
>definition)?
>
>  * For a single test, what is "slow"? Some rough numbers from Travis
>CI[1] to help us with guidelines:
>- boot_linux_console.py:BootLinuxConsole.test_x86_64_pc:  PASS (6.04 s)
>- boot_linux_console.py:BootLinuxConsole.test_arm_virt:  PASS (2.91 s)
>-
linux_initrd.py:LinuxInitrd.test_with_2gib_file_should_work_with_linux_v4_16:
PASS (18.14 s)
>- boot_linux.py:BootLinuxAarch64.test_virt:  PASS (396.88 s)
>
>  * Do we want to set a maximum job timeout?  This way we can skip
>tests after a given amount of time has passed.  Currently we interrupt
>the test running when the job timeout is reached, but it's possible
>to add a option so that no new tests will be started, but currently
>running ones will be waited on.
>

As far as integrating the patch into my queue, I did it just an hour or so
prior the objections of others, but will inform Peter to put the pull
request on hold, so it will not go to the main tree.

We in Wave Computing (MIPS) are very happy with this test, even in its
current state, and understand it as an initial version that will be subject
to improvement and expansion. We consider this test seriously and think it
is vital for QEMU for MIPS.

We would like to put it in the “slow” group for the simple reason that, we
gather, this would give us more freedom in future versions.

Yours,
Aleksandar

> Regards,
> - Cleber.
>
> [1] - https://travis-ci.org/clebergnu/qemu/jobs/535967210#L3518
>
> > --
> > Eduardo
> >


Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests

2019-05-22 Thread Cleber Rosa



- Original Message -
> From: "Eduardo Habkost" 
> To: "Philippe Mathieu-Daudé" 
> Cc: qemu-devel@nongnu.org, "Aleksandar Rikalo" , 
> "Aleksandar Markovic"
> , "Aleksandar Markovic" 
> , "Cleber Rosa" ,
> "Aurelien Jarno" , "Wainer dos Santos Moschetta" 
> 
> Sent: Wednesday, May 22, 2019 5:12:30 PM
> Subject: Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests
> 
> On Tue, May 21, 2019 at 01:19:06AM +0200, Philippe Mathieu-Daudé wrote:
> > Hi,
> > 
> > It was a rainy week-end here, so I invested it to automatize some
> > of my MIPS tests.
> > 
> > The BootLinuxSshTest is not Global warming friendly, it is not
> > meant to run on a CI system but rather on a workstation previous
> > to post a pull request.
> > It can surely be improved, but it is a good starting point.
> 
> Until we actually have a mechanism to exclude the test case on
> travis-ci, I will remove patch 4/4 from the queue.  Aleksandar,
> please don't merge patch 4/4 yet or it will break travis-ci.
> 
> Cleber, Wainer, is it already possible to make "avocado run" skip
> tests tagged with "slow"?
> 

The mechanism exists, but we haven't tagged any test so far as slow.

Should we define/document a criteria for a test to be slow?  Given
that this is highly subjective, we have to think of:

 * Will we consider the average or maximum run time (the timeout
   definition)?
 
 * For a single test, what is "slow"? Some rough numbers from Travis
   CI[1] to help us with guidelines:
   - boot_linux_console.py:BootLinuxConsole.test_x86_64_pc:  PASS (6.04 s)
   - boot_linux_console.py:BootLinuxConsole.test_arm_virt:  PASS (2.91 s)
   - 
linux_initrd.py:LinuxInitrd.test_with_2gib_file_should_work_with_linux_v4_16:  
PASS (18.14 s)
   - boot_linux.py:BootLinuxAarch64.test_virt:  PASS (396.88 s)

 * Do we want to set a maximum job timeout?  This way we can skip
   tests after a given amount of time has passed.  Currently we interrupt
   the test running when the job timeout is reached, but it's possible
   to add a option so that no new tests will be started, but currently
   running ones will be waited on.

Regards,
- Cleber. 

[1] - https://travis-ci.org/clebergnu/qemu/jobs/535967210#L3518

> --
> Eduardo
> 



Re: [Qemu-devel] [PULL v2 00/36] pci, pc, virtio: features, fixes

2019-05-22 Thread Peter Maydell
On Wed, 22 May 2019 at 15:22, Laszlo Ersek  wrote:
> This is very interesting. I had obviously tested booting
> "bios-tables-test.aarch64.iso.qcow2" against "edk2-aarch64-code.fd",
> using TCG, on my x86_64 laptop. (And, I've run the above exact command
> just now, at commit a4f667b67149 -- it works 100% fine.)
>
> However, I've never been *near* a 32-bit ARM host. Therefore my
> suspicion is that the AARCH64 UEFI guest code tickles something in the
> 32-bit ARM code generator. It could be a bug in 32-bit ARM TCG, or it
> could be a bug in edk2 that is exposed by 32-bit ARM TCG.

Does it repro in a 32-bit-chroot in an aarch64 host ?
I don't know if that might be easier for you to set up than
getting access to real 32-bit hardware.

thanks
-- PMM



Re: [Qemu-devel] [PATCH 0/4] mips: Add more Avocado tests

2019-05-22 Thread Eduardo Habkost
On Tue, May 21, 2019 at 01:19:06AM +0200, Philippe Mathieu-Daudé wrote:
> Hi,
> 
> It was a rainy week-end here, so I invested it to automatize some
> of my MIPS tests.
> 
> The BootLinuxSshTest is not Global warming friendly, it is not
> meant to run on a CI system but rather on a workstation previous
> to post a pull request.
> It can surely be improved, but it is a good starting point.

Until we actually have a mechanism to exclude the test case on
travis-ci, I will remove patch 4/4 from the queue.  Aleksandar,
please don't merge patch 4/4 yet or it will break travis-ci.

Cleber, Wainer, is it already possible to make "avocado run" skip
tests tagged with "slow"?

-- 
Eduardo



Re: [Qemu-devel] [PATCH 1/2] sphinx: add qmp_lexer

2019-05-22 Thread Peter Maydell
On Wed, 22 May 2019 at 20:02, John Snow  wrote:
>
>
>
> On 5/22/19 4:49 AM, Peter Maydell wrote:
> > On Tue, 21 May 2019 at 21:07, John Snow  wrote:
> >>
> >> Sphinx, through Pygments, does not like annotated json examples very
> >> much. In some versions of Sphinx (1.7), it will render the non-json
> >> portions of code blocks in red, but in newer versions (2.0) it will
> >> throw an exception and not highlight the block at all. Though we can
> >> suppress this warning, it doesn't bring back highlighting on non-strict
> >> json blocks.
> >>
> >> We can alleviate this by creating a custom lexer for QMP examples that
> >> allows us to properly highlight these examples in a robust way, keeping
> >> our directionality notations.
> >
> >> diff --git a/docs/sphinx/qmp_lexer.py b/docs/sphinx/qmp_lexer.py
> >> new file mode 100644
> >> index 00..f619f11139
> >> --- /dev/null
> >> +++ b/docs/sphinx/qmp_lexer.py
> >> @@ -0,0 +1,34 @@
> >> +# QEMU Monitor Protocol Lexer Extension
> >> +#
> >> +# Copyright (C) 2019, Red Hat Inc.
> >> +#
> >> +# Authors:
> >> +#  Eduardo Habkost 
> >> +#  John Snow 
> >> +#
> >> +# This work is licensed under the terms of the GNU GPL, version 2.  See
> >> +# the COPYING file in the top-level directory.
> >
> > Did you definitely mean 2-only and not 2-or-later ?

> Copy-paste pulled from another Python script. 2 or later is fine by me;
> I can resend if desired (or, I'd be fine with anyone touching it up in
> post.)

Our default-preference as a project is 2-or-later, so if
you're both happy with that I think we should use that.

thanks
-- PMM



Re: [Qemu-devel] [PATCH v2 2/2] Boot Linux Console Test: add a test for the Raspberry Pi 2

2019-05-22 Thread Cleber Rosa



- Original Message -
> From: "Eduardo Habkost" 
> To: "Philippe Mathieu-Daudé" 
> Cc: qemu-devel@nongnu.org, "Cleber Rosa" , "Peter Maydell" 
> ,
> qemu-...@nongnu.org, "Philippe Mathieu-Daudé" , "Andrew 
> Baumann" 
> Sent: Wednesday, May 22, 2019 4:52:34 PM
> Subject: Re: [Qemu-devel] [PATCH v2 2/2] Boot Linux Console Test: add a test 
> for the Raspberry Pi 2
> 
> On Wed, Mar 13, 2019 at 12:45:41AM +0100, Philippe Mathieu-Daudé wrote:
> > From: Philippe Mathieu-Daudé 
> > 
> > Similar to the x86_64/pc test, it boots a Linux kernel on a raspi2
> > board and verify the serial is working.
> > 
> > If ARM is a target being built, "make check-acceptance" will
> > automatically include this test by the use of the "arch:arm" tags.
> > 
> > Alternatively, this test can be run using:
> > 
> > $ avocado run -t arch:arm tests/acceptance
> > $ avocado run -t machine:raspi2 tests/acceptance
> > 
> > Signed-off-by: Philippe Mathieu-Daudé 
> 
> We're getting timeouts on travis-ci:
> https://travis-ci.org/ehabkost/qemu/jobs/535468057#L3289
> 
> I don't know yet if the guest is hanging, or if we just need to
> increase the timeout.  I could reproduce the timeout locally,
> too.
> 
> --
> Eduardo
> 

It may be related to:

 https://bugs.launchpad.net/qemu/+bug/1829779

And this is a proof that we urgently need to have a better
way of presenting/storing test artifacts.  The brief output
is nice when everything goes well, but makes the test results
close to useless once a failure happens.

Philippe showed us how GitLab allows CI jobs to preserve
artifacts, so maybe the solution is to move the loads there.

- Cleber.



Re: [Qemu-devel] [PATCH v2 2/2] Boot Linux Console Test: add a test for the Raspberry Pi 2

2019-05-22 Thread Eduardo Habkost
On Wed, Mar 13, 2019 at 12:45:41AM +0100, Philippe Mathieu-Daudé wrote:
> From: Philippe Mathieu-Daudé 
> 
> Similar to the x86_64/pc test, it boots a Linux kernel on a raspi2
> board and verify the serial is working.
> 
> If ARM is a target being built, "make check-acceptance" will
> automatically include this test by the use of the "arch:arm" tags.
> 
> Alternatively, this test can be run using:
> 
> $ avocado run -t arch:arm tests/acceptance
> $ avocado run -t machine:raspi2 tests/acceptance
> 
> Signed-off-by: Philippe Mathieu-Daudé 

We're getting timeouts on travis-ci:
https://travis-ci.org/ehabkost/qemu/jobs/535468057#L3289

I don't know yet if the guest is hanging, or if we just need to
increase the timeout.  I could reproduce the timeout locally,
too.

-- 
Eduardo



Re: [Qemu-devel] [PATCH 4/4] BootLinuxSshTest: Test some userspace commands on Malta

2019-05-22 Thread Eduardo Habkost
On Tue, May 21, 2019 at 10:18:10AM +0200, Aleksandar Markovic wrote:
> On May 21, 2019 1:19 AM, "Philippe Mathieu-Daudé"  wrote:
> >
> > This tests boot a full VM and check the serial console until
> > the SSH daemon is running, then start a SSH session and run
> > some commands.
> >
> > This test can be run using:
> >
> >   $ avocado --show=ssh run -t arch:mips
> tests/acceptance/linux_ssh_mips_malta.py
> >   ssh: Entering interactive session.
> >   ssh: # uname -a
> >   ssh: Linux debian-mips 3.2.0-4-4kc-malta #1 Debian 3.2.51-1 mips
> GNU/Linux
> >   ssh: # lspci -d 11ab:4620
> >   ssh: 00:00.0 Host bridge: Marvell Technology Group Ltd.
> GT-64120/64120A/64121A System Controller (rev 10)
> >   ssh: # cat /sys/bus/i2c/devices/i2c-0/name
> >   ssh: SMBus PIIX4 adapter at 1100
> >   ssh: # cat /proc/mtd
> >   ssh: dev:size   erasesize  name
> >   ssh: mtd0: 0010 0001 "YAMON"
> >   ssh: mtd1: 002e 0001 "User FS"
> >   ssh: mtd2: 0002 0001 "Board Config"
> >   ssh: # md5sum /dev/mtd2ro
> >   ssh: 0dfbe8aa4c20b52e1b8bf3cb6cbdf193  /dev/mtd2ro
> >   ssh: # poweroff
> >
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> 
> Excelent! Frankly, this was something that we in MIPS needed and missed
> very much for a long time.
> 
> I liked the idea that this test does not run as a default, giving us
> opportunity to extend and adjust it in future as we deem appropriate for
> our MIPS needs, but without affecting people running default test
> execution. In other words, this patch achieves “best of both worlds”.
> 

Actually, the test is being run by default, and is timing out on
travis-ci:

https://travis-ci.org/ehabkost/qemu/jobs/535468057#L3297

-- 
Eduardo



Re: [Qemu-devel] [PATCH v14 1/1] qcow2: skip writing zero buffers to empty COW areas

2019-05-22 Thread Max Reitz
On 16.05.19 16:27, Anton Nefedov wrote:
> If COW areas of the newly allocated clusters are zeroes on the backing
> image, efficient bdrv_write_zeroes(flags=BDRV_REQ_NO_FALLBACK) can be
> used on the whole cluster instead of writing explicit zero buffers later
> in perform_cow().
> 
> iotest 060:
> write to the discarded cluster does not trigger COW anymore.
> Use a backing image instead.
> 
> Signed-off-by: Anton Nefedov 
> ---
>  qapi/block-core.json   |  4 +-
>  block/qcow2.h  |  6 +++
>  block/qcow2-cluster.c  |  2 +-
>  block/qcow2.c  | 93 +-
>  block/trace-events |  1 +
>  tests/qemu-iotests/060 |  7 ++-
>  tests/qemu-iotests/060.out |  5 +-
>  7 files changed, 112 insertions(+), 6 deletions(-)

[...]

> diff --git a/block/qcow2.c b/block/qcow2.c
> index 8e024007db..e6b1293ddf 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c

[...]

> @@ -2145,6 +2150,80 @@ static bool merge_cow(uint64_t offset, unsigned bytes,
>  return false;
>  }
>  
> +static bool is_unallocated(BlockDriverState *bs, int64_t offset, int64_t 
> bytes)
> +{
> +int64_t nr;
> +return !bytes ||
> +(!bdrv_is_allocated_above(bs, NULL, offset, bytes, ) && nr == 
> bytes);

It's a pity that this bdrv_is_allocated() throws away BDRV_BLOCK_ZERO
information.  If something in the backing chain has explicit zero
clusters there, we could get the information for free, but this will
consider it allocated.

Wouldn't it make sense to make bdrv_co_block_status_above() public and
then use that (with want_zero == false)?

(But that can be done later, too, of course.)

> +}
> +
> +static bool is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
> +{
> +/*
> + * This check is designed for optimization shortcut so it must be
> + * efficient.
> + * Instead of is_zero(), use is_unallocated() as it is faster (but not
> + * as accurate and can result in false negatives).
> + */
> +return is_unallocated(bs, m->offset + m->cow_start.offset,
> +  m->cow_start.nb_bytes) &&
> +   is_unallocated(bs, m->offset + m->cow_end.offset,
> +  m->cow_end.nb_bytes);
> +}
> +
> +static int handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
> +{
> +BDRVQcow2State *s = bs->opaque;
> +QCowL2Meta *m;
> +
> +if (!(s->data_file->bs->supported_zero_flags & BDRV_REQ_NO_FALLBACK)) {
> +return 0;
> +}
> +
> +if (bs->encrypted) {
> +return 0;
> +}
> +
> +for (m = l2meta; m != NULL; m = m->next) {
> +int ret;
> +
> +if (!m->cow_start.nb_bytes && !m->cow_end.nb_bytes) {
> +continue;
> +}
> +
> +if (!is_zero_cow(bs, m)) {
> +continue;
> +}
> +
> +/*
> + * instead of writing zero COW buffers,
> + * efficiently zero out the whole clusters
> + */
> +
> +ret = qcow2_pre_write_overlap_check(bs, 0, m->alloc_offset,
> +m->nb_clusters * s->cluster_size,
> +true);
> +if (ret < 0) {
> +return ret;
> +}
> +
> +BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_SPACE);
> +ret = bdrv_co_pwrite_zeroes(s->data_file, m->alloc_offset,
> +m->nb_clusters * s->cluster_size,
> +BDRV_REQ_NO_FALLBACK);

Mostly I'm writing this mail because of this.  Zeroing the whole range
seems inefficient to me for very large requests, and the commit message
doesn't say anything about the reasoning behind unconditionally zeroing
everything.

Benchmarking looks like in most cases it is about equal to zeroing head
and tail separately.  But if I pre-filll an image with random data, it
is much slower:

$ qemu-img create -f qcow2 foo.qcow2 10G
$ dd if=/dev/urandom of=foo.qcow2 bs=1M seek=1 count=4096
$ sync

Then doing large unaligned requests on it:

$ ./qemu-img bench -w -t none -s $((400 * 1048576)) \
  -S $((401 * 1048576)) -o 32768 -c 10 -d 2 -f qcow2 foo.qcow2

When zeroing the whole range, this usually takes around 25 s for me;
just zeroing head and tail takes around 14 s. Without this patch, it
takes around 14 s, too.

On the other hand, when doing smaller requests on a single cluster
(which is what this patch is for):

$ ./qemu-img bench -w -t none -s 4096 -S 65536 -o 32768 \
  -f qcow2 foo.qcow2

This takes around 26 s before this patch, 12 s with it, and like 30 to
40 when zeroing head and tail separately.


Now, such large requests surely are the exception, as is allocating
blocks in an area of the image that already contains data.  However, I
just want to ask back that zeroing the whole range unconditionally is
done on purpose.  Maybe it makes sense to split head and tail if they
are like more than, I don't know, 16 MB apart?  But the "I don't know"
is the problem of course.  Is there a way 

[Qemu-devel] [PULL v2 11/11] BootLinuxSshTest: Test some userspace commands on Malta

2019-05-22 Thread Aleksandar Markovic
From: Philippe Mathieu-Daudé 

This tests boot a full VM and check the serial console until
the SSH daemon is running, then start a SSH session and run
some commands.

This test can be run using:

  $ avocado --show=ssh run -t arch:mips tests/acceptance/linux_ssh_mips_malta.py
  ssh: Entering interactive session.
  ssh: # uname -a
  ssh: Linux debian-mips 3.2.0-4-4kc-malta #1 Debian 3.2.51-1 mips GNU/Linux
  ssh: # lspci -d 11ab:4620
  ssh: 00:00.0 Host bridge: Marvell Technology Group Ltd. 
GT-64120/64120A/64121A System Controller (rev 10)
  ssh: # cat /sys/bus/i2c/devices/i2c-0/name
  ssh: SMBus PIIX4 adapter at 1100
  ssh: # cat /proc/mtd
  ssh: dev:size   erasesize  name
  ssh: mtd0: 0010 0001 "YAMON"
  ssh: mtd1: 002e 0001 "User FS"
  ssh: mtd2: 0002 0001 "Board Config"
  ssh: # md5sum /dev/mtd2ro
  ssh: 0dfbe8aa4c20b52e1b8bf3cb6cbdf193  /dev/mtd2ro
  ssh: # poweroff

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Acked-by: Eduardo Habkost 
Message-Id: <20190520231910.12184-5-f4...@amsat.org>
---
 MAINTAINERS  |   1 +
 tests/acceptance/linux_ssh_mips_malta.py | 229 +++
 tests/requirements.txt   |   1 +
 3 files changed, 231 insertions(+)
 create mode 100644 tests/acceptance/linux_ssh_mips_malta.py

diff --git a/MAINTAINERS b/MAINTAINERS
index a6948eb..75f6544 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -934,6 +934,7 @@ M: Aurelien Jarno 
 R: Aleksandar Rikalo 
 S: Maintained
 F: hw/mips/mips_malta.c
+F: tests/acceptance/linux_ssh_mips_malta.py
 
 Mipssim
 M: Aleksandar Markovic 
diff --git a/tests/acceptance/linux_ssh_mips_malta.py 
b/tests/acceptance/linux_ssh_mips_malta.py
new file mode 100644
index 000..ceb530f
--- /dev/null
+++ b/tests/acceptance/linux_ssh_mips_malta.py
@@ -0,0 +1,229 @@
+# Functional test that boots a VM and run commands via a SSH session
+#
+# Copyright (c) Philippe Mathieu-Daudé 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+import os
+import re
+import base64
+import logging
+import paramiko
+import time
+
+from avocado_qemu import Test
+from avocado.utils import process
+from avocado.utils import archive
+
+
+class LinuxSSH(Test):
+
+timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
+
+KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
+VM_IP = '127.0.0.1'
+
+IMAGE_INFO = {
+'be': {
+'image_url': 'https://people.debian.org/~aurel32/qemu/mips/'
+ 'debian_wheezy_mips_standard.qcow2',
+'image_hash': '8987a63270df67345b2135a6b7a4885a35e392d5',
+'rsa_hostkey': b'B3NzaC1yc2EDAQABAAABAQCca1VitiyLAdQOld'
+   b'zT43IOEVJZ0wHD78GJi8wDAjMiYWUzNSSn0rXGQsINHuH5'
+   b'IlF+kBZsHinb/FtKCAyS9a8uCHhQI4SuB4QhAb0+39MlUw'
+   b'Mm0CLkctgM2eUUZ6MQMQvDlqnue6CCkxN62EZYbaxmby7j'
+   b'CQa1125o1HRKBvdGm2zrJWxXAfA+f1v6jHLyE8Jnu83eQ+'
+   b'BFY25G+Vzx1PVc3zQBwJ8r0NGTRqy2//oWQP0h+bMsgeFe'
+   b'KH/J3RJM22vg6+I4JAdBFcxnK+l781h1FuRxOn4O/Xslbg'
+   b'go6WtB4V4TOsw2E/KfxI5IZ/icxF+swVcnvF46Hf3uQc/0'
+   b'BBqb',
+},
+'le': {
+'image_url': 'https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'debian_wheezy_mipsel_standard.qcow2',
+'image_hash': '7866764d9de3ef536ffca24c9fb9f04ffdb45802',
+'rsa_hostkey': b'B3NzaC1yc2EDAQABAAABAQClXJlBT71HL5yKvv'
+   b'gfC7jmxSWx5zSBCzET6CLZczwAafSIs7YKfNOy/dQTxhuk'
+   b'yIGFUugZFoF3E9PzdhunuyvyTd56MPoNIqFbb5rGokwU5I'
+   b'TOx3dBHZR0mClypL6MVrwe0bsiIb8GhF1zioNwcsaAZnAi'
+   b'KfXStVDtXvn/kLLq+xLABYt48CC5KYWoFaCoICskLAY+qo'
+   b'L+LWyAnQisj4jAH8VSaSKIImFpfkHWEXPhHcC4ZBlDKtnH'
+   b'po9vhfCHgnfW3Pzrqmk8BI4HysqPFVmJWkJGlGUL+sGeg3'
+   b'ZZolAYuDXGuBrw8ooPJq2v2dOH+z6dyD2q/ypmAbyPqj5C'
+   b'rc8H',
+},
+}
+
+def wait_for_console_pattern(self, success_message,
+ failure_message='Oops'):
+console = self.vm.console_socket.makefile()
+console_logger = logging.getLogger('console')
+while True:
+msg = console.readline()
+console_logger.debug(msg.strip())
+if success_message in msg:
+break
+if failure_message in msg:
+fail = 'Failure message found in console: %s' % failure_message
+self.fail(fail)
+
+def get_portfwd(self):
+res = self.vm.command('human-monitor-command',
+  command_line='info usernet')

[Qemu-devel] [PULL v2 08/11] hw/mips: Use object_initialize() on MIPSCPSState

2019-05-22 Thread Aleksandar Markovic
From: Philippe Mathieu-Daudé 

Initialize the MIPSCPSState with object_initialize() instead of
object_new(). This will allow us to add it as children of the
machine container.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Paolo Bonzini 
Message-Id: <20190507163416.24647-10-phi...@redhat.com>
---
 hw/mips/boston.c | 25 -
 hw/mips/mips_malta.c | 17 -
 2 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index a8b29f6..cb3ea85 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -49,7 +49,7 @@ typedef struct {
 SysBusDevice parent_obj;
 
 MachineState *mach;
-MIPSCPSState *cps;
+MIPSCPSState cps;
 SerialState *uart;
 
 CharBackend lcd_display;
@@ -188,7 +188,7 @@ static uint64_t boston_platreg_read(void *opaque, hwaddr 
addr,
 case PLAT_DDR3_STATUS:
 return PLAT_DDR3_STATUS_LOCKED | PLAT_DDR3_STATUS_CALIBRATED;
 case PLAT_MMCM_DIV:
-gic_freq = mips_gictimer_get_freq(s->cps->gic.gic_timer) / 100;
+gic_freq = mips_gictimer_get_freq(s->cps.gic.gic_timer) / 100;
 val = gic_freq << PLAT_MMCM_DIV_INPUT_SHIFT;
 val |= 1 << PLAT_MMCM_DIV_MUL_SHIFT;
 val |= 1 << PLAT_MMCM_DIV_CLK0DIV_SHIFT;
@@ -455,20 +455,19 @@ static void boston_mach_init(MachineState *machine)
 
 is_64b = cpu_supports_isa(machine->cpu_type, ISA_MIPS64);
 
-s->cps = MIPS_CPS(object_new(TYPE_MIPS_CPS));
-qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default());
-
-object_property_set_str(OBJECT(s->cps), machine->cpu_type, "cpu-type",
+object_initialize(>cps, sizeof(s->cps), TYPE_MIPS_CPS);
+qdev_set_parent_bus(DEVICE(>cps), sysbus_get_default());
+object_property_set_str(OBJECT(>cps), machine->cpu_type, "cpu-type",
 );
-object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", );
-object_property_set_bool(OBJECT(s->cps), true, "realized", );
+object_property_set_int(OBJECT(>cps), smp_cpus, "num-vp", );
+object_property_set_bool(OBJECT(>cps), true, "realized", );
 
 if (err != NULL) {
 error_report("%s", error_get_pretty(err));
 exit(1);
 }
 
-sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1);
+sysbus_mmio_map_overlap(SYS_BUS_DEVICE(>cps), 0, 0, 1);
 
 flash =  g_new(MemoryRegion, 1);
 memory_region_init_rom(flash, NULL, "boston.flash", 128 * MiB, );
@@ -487,17 +486,17 @@ static void boston_mach_init(MachineState *machine)
 xilinx_pcie_init(sys_mem, 0,
  0x1000, 32 * MiB,
  0x4000, 1 * GiB,
- get_cps_irq(s->cps, 2), false);
+ get_cps_irq(>cps, 2), false);
 
 xilinx_pcie_init(sys_mem, 1,
  0x1200, 32 * MiB,
  0x2000, 512 * MiB,
- get_cps_irq(s->cps, 1), false);
+ get_cps_irq(>cps, 1), false);
 
 pcie2 = xilinx_pcie_init(sys_mem, 2,
  0x1400, 32 * MiB,
  0x1600, 1 * MiB,
- get_cps_irq(s->cps, 0), true);
+ get_cps_irq(>cps, 0), true);
 
 platreg = g_new(MemoryRegion, 1);
 memory_region_init_io(platreg, NULL, _platreg_ops, s,
@@ -505,7 +504,7 @@ static void boston_mach_init(MachineState *machine)
 memory_region_add_subregion_overlap(sys_mem, 0x17ffd000, platreg, 0);
 
 s->uart = serial_mm_init(sys_mem, 0x17ffe000, 2,
- get_cps_irq(s->cps, 3), 1000,
+ get_cps_irq(>cps, 3), 1000,
  serial_hd(0), DEVICE_NATIVE_ENDIAN);
 
 lcd = g_new(MemoryRegion, 1);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 439665a..04f2117 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -94,7 +94,7 @@ typedef struct {
 typedef struct {
 SysBusDevice parent_obj;
 
-MIPSCPSState *cps;
+MIPSCPSState cps;
 qemu_irq *i8259;
 } MaltaState;
 
@@ -1151,20 +1151,19 @@ static void create_cps(MaltaState *s, const char 
*cpu_type,
 {
 Error *err = NULL;
 
-s->cps = MIPS_CPS(object_new(TYPE_MIPS_CPS));
-qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default());
-
-object_property_set_str(OBJECT(s->cps), cpu_type, "cpu-type", );
-object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", );
-object_property_set_bool(OBJECT(s->cps), true, "realized", );
+object_initialize(>cps, sizeof(s->cps), TYPE_MIPS_CPS);
+qdev_set_parent_bus(DEVICE(>cps), sysbus_get_default());
+object_property_set_str(OBJECT(>cps), cpu_type, "cpu-type", );
+object_property_set_int(OBJECT(>cps), smp_cpus, "num-vp", );
+object_property_set_bool(OBJECT(>cps), true, "realized", );
 if (err != NULL) {
 error_report("%s", error_get_pretty(err));
 exit(1);
 }
 
-  

[Qemu-devel] [PULL v2 09/11] hw/mips: Use object_initialize_child for correct reference counting

2019-05-22 Thread Aleksandar Markovic
From: Philippe Mathieu-Daudé 

As explained in commit aff39be0ed97:

  Both functions, object_initialize() and object_property_add_child()
  increase the reference counter of the new object, so one of the
  references has to be dropped afterwards to get the reference
  counting right. Otherwise the child object will not be properly
  cleaned up when the parent gets destroyed.
  Thus let's use now object_initialize_child() instead to get the
  reference counting here right.

This patch was generated using the following Coccinelle script:

 @use_sysbus_init_child_obj_missing_parent@
 expression child_ptr;
 expression child_type;
 expression child_size;
 @@
 -   object_initialize(child_ptr, child_size, child_type);
 ...
 -   qdev_set_parent_bus(DEVICE(child_ptr), sysbus_get_default());
 ...
 ?-  object_unref(OBJECT(child_ptr));
 +   sysbus_init_child_obj(OBJECT(PARENT_OBJ), "CHILD_NAME", child_ptr,
 + child_size, child_type);

We let the Malta/Boston machines adopt the CPS child, and similarly
the CPS adopts the ITU/CPC/GIC/GCR children.

While the object_initialize() function doesn't take an
'Error *errp' argument, the object_initialize_child() does.
Since this code is used when a machine is created (and is not
yet running), we deliberately choose to use the _abort
argument instead of ignoring errors if an object creation failed.
This choice also matches when using sysbus_init_child_obj(),
since its code is:

  void sysbus_init_child_obj(Object *parent,
 const char *childname, void *child,
 size_t childsize, const char *childtype)
  {
  object_initialize_child(parent, childname, child, childsize,
  childtype, _abort, NULL);

  qdev_set_parent_bus(DEVICE(child), sysbus_get_default());
  }

Suggested-by: Eduardo Habkost 
Inspired-by: Thomas Huth 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Paolo Bonzini 
Message-Id: <20190507163416.24647-11-phi...@redhat.com>
---
 hw/mips/boston.c |  4 ++--
 hw/mips/cps.c| 20 
 hw/mips/mips_malta.c |  4 ++--
 3 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index cb3ea85..1ffccc8 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -455,8 +455,8 @@ static void boston_mach_init(MachineState *machine)
 
 is_64b = cpu_supports_isa(machine->cpu_type, ISA_MIPS64);
 
-object_initialize(>cps, sizeof(s->cps), TYPE_MIPS_CPS);
-qdev_set_parent_bus(DEVICE(>cps), sysbus_get_default());
+sysbus_init_child_obj(OBJECT(machine), "cps", OBJECT(>cps),
+  sizeof(s->cps), TYPE_MIPS_CPS);
 object_property_set_str(OBJECT(>cps), machine->cpu_type, "cpu-type",
 );
 object_property_set_int(OBJECT(>cps), smp_cpus, "num-vp", );
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index fc97f59..649b35a 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -94,9 +94,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 
 /* Inter-Thread Communication Unit */
 if (itu_present) {
-object_initialize(>itu, sizeof(s->itu), TYPE_MIPS_ITU);
-qdev_set_parent_bus(DEVICE(>itu), sysbus_get_default());
-
+sysbus_init_child_obj(OBJECT(dev), "itu", >itu, sizeof(s->itu),
+  TYPE_MIPS_ITU);
 object_property_set_int(OBJECT(>itu), 16, "num-fifo", );
 object_property_set_int(OBJECT(>itu), 16, "num-semaphores", );
 object_property_set_bool(OBJECT(>itu), saar_present, "saar-present",
@@ -115,9 +114,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 }
 
 /* Cluster Power Controller */
-object_initialize(>cpc, sizeof(s->cpc), TYPE_MIPS_CPC);
-qdev_set_parent_bus(DEVICE(>cpc), sysbus_get_default());
-
+sysbus_init_child_obj(OBJECT(dev), "cpc", >cpc, sizeof(s->cpc),
+  TYPE_MIPS_CPC);
 object_property_set_int(OBJECT(>cpc), s->num_vp, "num-vp", );
 object_property_set_int(OBJECT(>cpc), 1, "vp-start-running", );
 object_property_set_bool(OBJECT(>cpc), true, "realized", );
@@ -130,9 +128,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 sysbus_mmio_get_region(SYS_BUS_DEVICE(>cpc), 
0));
 
 /* Global Interrupt Controller */
-object_initialize(>gic, sizeof(s->gic), TYPE_MIPS_GIC);
-qdev_set_parent_bus(DEVICE(>gic), sysbus_get_default());
-
+sysbus_init_child_obj(OBJECT(dev), "gic", >gic, sizeof(s->gic),
+  TYPE_MIPS_GIC);
 object_property_set_int(OBJECT(>gic), s->num_vp, "num-vp", );
 object_property_set_int(OBJECT(>gic), 128, "num-irq", );
 object_property_set_bool(OBJECT(>gic), true, "realized", );
@@ -147,9 +144,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 /* Global Configuration Registers */
 gcr_base = env->CP0_CMGCRBase << 4;

[Qemu-devel] [PULL v2 06/11] target/mips: Refactor and fix COPY_U. instructions

2019-05-22 Thread Aleksandar Markovic
From: Mateja Marjanovic 

The old version of the helper for the COPY_U. MSA instructions
has been replaced with four helpers that don't use switch, and change
the endianness of the given index, when executed on a big endian host.

Signed-off-by: Mateja Marjanovic 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Message-Id: <1554212605-16457-5-git-send-email-mateja.marjano...@rt-rk.com>
---
 target/mips/helper.h |  4 +++-
 target/mips/msa_helper.c | 55 +++-
 target/mips/translate.c  | 21 +-
 3 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/target/mips/helper.h b/target/mips/helper.h
index de3a9e0..c4a77e2 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -877,7 +877,6 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
 
-DEF_HELPER_5(msa_copy_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
@@ -942,6 +941,9 @@ DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32)
 
 DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 89b3be9..52680fe 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -1298,29 +1298,46 @@ void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
 env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
 }
 
-void helper_msa_copy_u_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
-  uint32_t ws, uint32_t n)
+void helper_msa_copy_u_b(CPUMIPSState *env, uint32_t rd,
+ uint32_t ws, uint32_t n)
 {
-n %= DF_ELEMENTS(df);
+n %= 16;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 8) {
+n = 8 - n - 1;
+} else {
+n = 24 - n - 1;
+}
+#endif
+env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
+}
 
-switch (df) {
-case DF_BYTE:
-env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
-break;
-case DF_HALF:
-env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
-break;
-case DF_WORD:
-env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
-break;
-#ifdef TARGET_MIPS64
-case DF_DOUBLE:
-env->active_tc.gpr[rd] = (uint64_t)env->active_fpu.fpr[ws].wr.d[n];
-break;
+void helper_msa_copy_u_h(CPUMIPSState *env, uint32_t rd,
+ uint32_t ws, uint32_t n)
+{
+n %= 8;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 4) {
+n = 4 - n - 1;
+} else {
+n = 12 - n - 1;
+}
 #endif
-default:
-assert(0);
+env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
+}
+
+void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
+ uint32_t ws, uint32_t n)
+{
+n %= 4;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 2) {
+n = 2 - n - 1;
+} else {
+n = 6 - n - 1;
 }
+#endif
+env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
 }
 
 void helper_msa_insert_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
diff --git a/target/mips/translate.c b/target/mips/translate.c
index c65d19e..68ea6ee 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28297,6 +28297,11 @@ static void gen_msa_elm_df(CPUMIPSState *env, 
DisasContext *ctx, uint32_t df,
 generate_exception_end(ctx, EXCP_RI);
 break;
 }
+if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
+  (df == DF_WORD)) {
+generate_exception_end(ctx, EXCP_RI);
+break;
+}
 #endif
 switch (MASK_MSA_ELM(ctx->opcode)) {
 case OPC_COPY_S_df:
@@ -28323,7 +28328,21 @@ static void gen_msa_elm_df(CPUMIPSState *env, 
DisasContext *ctx, uint32_t df,
 break;
 case OPC_COPY_U_df:
 if (likely(wd != 0)) {
-gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
+switch (df) {
+case DF_BYTE:
+gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
+break;
+case DF_HALF:
+gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
+break;
+#if defined(TARGET_MIPS64)
+case DF_WORD:
+

Re: [Qemu-devel] [PATCH v3 0/8] block: Ignore loosening perm restrictions failures

2019-05-22 Thread Eric Blake
On 5/22/19 1:37 PM, Max Reitz wrote:

>> I don't know if there is an easy way to warn for normal users, but
>> silence the warnings if run under test setups to keep 'make check'
>> output unchanged (I know we've silenced warnings in the past when we
>> detect we are running qtest, but this isn't necessarily the same setup).
>>  So not a show-stopper for me.
> 
> Hm.  That doesn’t sound too bad.  I don’t think there is an easy way to
> silence the warning in qemu, but we might be able to just modify the test.
> 
> But I don’t even know whether the warnings are even useful or whether
> they would just confuse users more than anything.  So far, every case I
> know where loosening restrictions failed was because the file is just
> gone completely.  The only purpose of a warning is to show the user that
> qemu might have locks on the file that it doesn’t need, so they will
> know what’s up if they try to open the file in another qemu instance in
> a way that should normally work but suddenly doesn’t.  But if the file’s
> just gone, you can’t open it in another qemu, so I don’t even know
> whether there’s actually any point in warning.

Good point - if we unlink()ed the file, we can't loosen permissions, but
neither can anyone else open() it to collide with us :)

A network connection going down is a bit harder to justify (it might
come back up), but I think it still fits the bill (if we can't loosen
permissions, who else can interfere with us?)

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PULL v2 10/11] mips: Decide to map PAGE_EXEC in map_address

2019-05-22 Thread Aleksandar Markovic
From: Jakub Jermář 

This commit addresses QEMU Bug #1825311:

  mips_cpu_handle_mmu_fault renders all accessed pages executable

It allows finer-grained control over whether the accessed page should
be executable by moving the decision to the underlying map_address
function, which has more information for this.

As a result, pages that have the XI bit set in the TLB and are accessed
for read/write, don't suddenly end up being executable.

Fixes: https://bugs.launchpad.net/qemu/+bug/1825311
Fixes: 2fb58b73746e ('target-mips: add RI and XI fields to TLB entry')

Signed-off-by: Jakub Jermář 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20190517123533.868479-1-jakub.jer...@kernkonzept.com>
---
 target/mips/helper.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index 9799f2e..68e44df 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -43,7 +43,7 @@ int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, 
int *prot,
 target_ulong address, int rw, int access_type)
 {
 *physical = address;
-*prot = PAGE_READ | PAGE_WRITE;
+*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TLBRET_MATCH;
 }
 
@@ -61,7 +61,7 @@ int fixed_mmu_map_address (CPUMIPSState *env, hwaddr 
*physical, int *prot,
 else
 *physical = address;
 
-*prot = PAGE_READ | PAGE_WRITE;
+*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TLBRET_MATCH;
 }
 
@@ -101,6 +101,9 @@ int r4k_map_address (CPUMIPSState *env, hwaddr *physical, 
int *prot,
 *prot = PAGE_READ;
 if (n ? tlb->D1 : tlb->D0)
 *prot |= PAGE_WRITE;
+if (!(n ? tlb->XI1 : tlb->XI0)) {
+*prot |= PAGE_EXEC;
+}
 return TLBRET_MATCH;
 }
 return TLBRET_DIRTY;
@@ -182,7 +185,7 @@ static int get_seg_physical_address(CPUMIPSState *env, 
hwaddr *physical,
 } else {
 /* The segment is unmapped */
 *physical = physical_base | (real_address & segmask);
-*prot = PAGE_READ | PAGE_WRITE;
+*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TLBRET_MATCH;
 }
 }
@@ -907,7 +910,7 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 if (ret == TLBRET_MATCH) {
 tlb_set_page(cs, address & TARGET_PAGE_MASK,
- physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+ physical & TARGET_PAGE_MASK, prot,
  mmu_idx, TARGET_PAGE_SIZE);
 return true;
 }
@@ -927,7 +930,7 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
access_type, mips_access_type, mmu_idx);
 if (ret == TLBRET_MATCH) {
 tlb_set_page(cs, address & TARGET_PAGE_MASK,
- physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+ physical & TARGET_PAGE_MASK, prot,
  mmu_idx, TARGET_PAGE_SIZE);
 return true;
 }
-- 
2.7.4




[Qemu-devel] [PULL v2 03/11] target/mips: Fix MSA instructions LD. on big endian host

2019-05-22 Thread Aleksandar Markovic
From: Mateja Marjanovic 

Fix the case when the host is a big endian machine, and change
the approach toward LD. instruction helpers.

Signed-off-by: Mateja Marjanovic 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Message-Id: <1554212605-16457-2-git-send-email-mateja.marjano...@rt-rk.com>
---
 target/mips/op_helper.c | 188 ++--
 1 file changed, 168 insertions(+), 20 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 6d86912..a8ae438 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -4356,31 +4356,179 @@ FOP_CONDN_S(sne,  (float32_lt(fst1, fst0, 
>active_fpu.fp_status)
 #define MEMOP_IDX(DF)
 #endif
 
-#define MSA_LD_DF(DF, TYPE, LD_INSN, ...)   \
-void helper_msa_ld_ ## TYPE(CPUMIPSState *env, uint32_t wd, \
-target_ulong addr)  \
-{   \
-wr_t *pwd = &(env->active_fpu.fpr[wd].wr);  \
-wr_t wx;\
-int i;  \
-MEMOP_IDX(DF)   \
-for (i = 0; i < DF_ELEMENTS(DF); i++) { \
-wx.TYPE[i] = LD_INSN(env, addr + (i << DF), ##__VA_ARGS__); \
-}   \
-memcpy(pwd, , sizeof(wr_t)); \
+void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd,
+ target_ulong addr)
+{
+wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+MEMOP_IDX(DF_BYTE)
+#if !defined(CONFIG_USER_ONLY)
+#if !defined(HOST_WORDS_BIGENDIAN)
+pwd->b[0]  = helper_ret_ldub_mmu(env, addr + (0  << DF_BYTE), oi, GETPC());
+pwd->b[1]  = helper_ret_ldub_mmu(env, addr + (1  << DF_BYTE), oi, GETPC());
+pwd->b[2]  = helper_ret_ldub_mmu(env, addr + (2  << DF_BYTE), oi, GETPC());
+pwd->b[3]  = helper_ret_ldub_mmu(env, addr + (3  << DF_BYTE), oi, GETPC());
+pwd->b[4]  = helper_ret_ldub_mmu(env, addr + (4  << DF_BYTE), oi, GETPC());
+pwd->b[5]  = helper_ret_ldub_mmu(env, addr + (5  << DF_BYTE), oi, GETPC());
+pwd->b[6]  = helper_ret_ldub_mmu(env, addr + (6  << DF_BYTE), oi, GETPC());
+pwd->b[7]  = helper_ret_ldub_mmu(env, addr + (7  << DF_BYTE), oi, GETPC());
+pwd->b[8]  = helper_ret_ldub_mmu(env, addr + (8  << DF_BYTE), oi, GETPC());
+pwd->b[9]  = helper_ret_ldub_mmu(env, addr + (9  << DF_BYTE), oi, GETPC());
+pwd->b[10] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC());
+pwd->b[11] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC());
+pwd->b[12] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC());
+pwd->b[13] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC());
+pwd->b[14] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC());
+pwd->b[15] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC());
+#else
+pwd->b[0]  = helper_ret_ldub_mmu(env, addr + (7  << DF_BYTE), oi, GETPC());
+pwd->b[1]  = helper_ret_ldub_mmu(env, addr + (6  << DF_BYTE), oi, GETPC());
+pwd->b[2]  = helper_ret_ldub_mmu(env, addr + (5  << DF_BYTE), oi, GETPC());
+pwd->b[3]  = helper_ret_ldub_mmu(env, addr + (4  << DF_BYTE), oi, GETPC());
+pwd->b[4]  = helper_ret_ldub_mmu(env, addr + (3  << DF_BYTE), oi, GETPC());
+pwd->b[5]  = helper_ret_ldub_mmu(env, addr + (2  << DF_BYTE), oi, GETPC());
+pwd->b[6]  = helper_ret_ldub_mmu(env, addr + (1  << DF_BYTE), oi, GETPC());
+pwd->b[7]  = helper_ret_ldub_mmu(env, addr + (0  << DF_BYTE), oi, GETPC());
+pwd->b[8]  = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC());
+pwd->b[9]  = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC());
+pwd->b[10] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC());
+pwd->b[11] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC());
+pwd->b[12] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC());
+pwd->b[13] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC());
+pwd->b[14] = helper_ret_ldub_mmu(env, addr + (9  << DF_BYTE), oi, GETPC());
+pwd->b[15] = helper_ret_ldub_mmu(env, addr + (8  << DF_BYTE), oi, GETPC());
+#endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+pwd->b[0]  = cpu_ldub_data(env, addr + (0  << DF_BYTE));
+pwd->b[1]  = cpu_ldub_data(env, addr + (1  << DF_BYTE));
+pwd->b[2]  = cpu_ldub_data(env, addr + (2  << DF_BYTE));
+pwd->b[3]  = cpu_ldub_data(env, addr + (3  << DF_BYTE));
+pwd->b[4]  = cpu_ldub_data(env, addr + (4  << DF_BYTE));
+pwd->b[5]  = cpu_ldub_data(env, addr + (5  << DF_BYTE));
+pwd->b[6]  = cpu_ldub_data(env, addr + (6  << DF_BYTE));
+pwd->b[7]  = cpu_ldub_data(env, addr + (7  << 

[Qemu-devel] [PULL v2 02/11] target/mips: Make the results of MOD_. the same as on hardware

2019-05-22 Thread Aleksandar Markovic
From: Mateja Marjanovic 

MSA instructions MOD_. when dividing by zero,
didn't return the same value when executed on a referent hardware
(FPGA MIPS 64 r6, little endian) and when executed on QEMU, which
is not a real bug, because the result when dividing by zero is
UNPREDICTABLE [1] (page 255, 256).

[1] MIPS Architecture for Programmers
Volume IV-j: The MIPS64 SIMD
Architecture Module, Revision 1.12

Signed-off-by: Mateja Marjanovic 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Message-Id: <1554207110-9113-3-git-send-email-mateja.marjano...@rt-rk.com>
---
 target/mips/msa_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 596190b..274c6ca 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -657,14 +657,14 @@ static inline int64_t msa_mod_s_df(uint32_t df, int64_t 
arg1, int64_t arg2)
 if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
 return 0;
 }
-return arg2 ? arg1 % arg2 : 0;
+return arg2 ? arg1 % arg2 : arg1;
 }
 
 static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
 uint64_t u_arg1 = UNSIGNED(arg1, df);
 uint64_t u_arg2 = UNSIGNED(arg2, df);
-return u_arg2 ? u_arg1 % u_arg2 : 0;
+return u_arg2 ? u_arg1 % u_arg2 : u_arg1;
 }
 
 #define SIGNED_EVEN(a, df) \
-- 
2.7.4




[Qemu-devel] [PULL 04/25] crypto: Do not fail for EINTR during qcrypto_random_bytes

2019-05-22 Thread Richard Henderson
We can always get EINTR for read; /dev/urandom is no exception.

Rearrange the order of tests for likelihood; allow degenerate buflen==0
case to perform a no-op zero-length read.  This means that the normal
success path is a straight line with a single test for success.

Reviewed-by: Laurent Vivier 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 crypto/random-platform.c | 36 +++-
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index f995fc0ef1..260b64564d 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -65,29 +65,23 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
  "Unable to read random bytes");
 return -1;
 }
-
-return 0;
 #else
-int ret = -1;
-int got;
-
-while (buflen > 0) {
-got = read(fd, buf, buflen);
-if (got < 0) {
-error_setg_errno(errp, errno,
- "Unable to read random bytes");
-goto cleanup;
-} else if (!got) {
-error_setg(errp,
-   "Unexpected EOF reading random bytes");
-goto cleanup;
+while (1) {
+ssize_t got = read(fd, buf, buflen);
+if (likely(got == buflen)) {
+return 0;
+}
+if (got > 0) {
+buflen -= got;
+buf += got;
+} else if (got == 0) {
+error_setg(errp, "Unexpected EOF reading random bytes");
+return -1;
+} else if (errno != EINTR) {
+error_setg_errno(errp, errno, "Unable to read random bytes");
+return -1;
 }
-buflen -= got;
-buf += got;
 }
-
-ret = 0;
- cleanup:
-return ret;
 #endif
+return 0;
 }
-- 
2.17.1




[Qemu-devel] [PULL 03/25] crypto: Reverse code blocks in random-platform.c

2019-05-22 Thread Richard Henderson
Use #ifdef _WIN32 instead of #ifndef _WIN32.
This will make other tests easier to sequence.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 crypto/random-platform.c | 35 +--
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 7541b4cae7..f995fc0ef1 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -32,7 +32,14 @@ static int fd; /* a file handle to either /dev/urandom or 
/dev/random */
 
 int qcrypto_random_init(Error **errp)
 {
-#ifndef _WIN32
+#ifdef _WIN32
+if (!CryptAcquireContext(, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
+error_setg_win32(errp, GetLastError(),
+ "Unable to create cryptographic provider");
+return -1;
+}
+#else
 /* TBD perhaps also add support for BSD getentropy / Linux
  * getrandom syscalls directly */
 fd = open("/dev/urandom", O_RDONLY);
@@ -44,15 +51,7 @@ int qcrypto_random_init(Error **errp)
 error_setg(errp, "No /dev/urandom or /dev/random found");
 return -1;
 }
-#else
-if (!CryptAcquireContext(, NULL, NULL, PROV_RSA_FULL,
- CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
-error_setg_win32(errp, GetLastError(),
- "Unable to create cryptographic provider");
-return -1;
-}
 #endif
-
 return 0;
 }
 
@@ -60,7 +59,15 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
  size_t buflen G_GNUC_UNUSED,
  Error **errp)
 {
-#ifndef _WIN32
+#ifdef _WIN32
+if (!CryptGenRandom(hCryptProv, buflen, buf)) {
+error_setg_win32(errp, GetLastError(),
+ "Unable to read random bytes");
+return -1;
+}
+
+return 0;
+#else
 int ret = -1;
 int got;
 
@@ -82,13 +89,5 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
 ret = 0;
  cleanup:
 return ret;
-#else
-if (!CryptGenRandom(hCryptProv, buflen, buf)) {
-error_setg_win32(errp, GetLastError(),
- "Unable to read random bytes");
-return -1;
-}
-
-return 0;
 #endif
 }
-- 
2.17.1




[Qemu-devel] [PULL 01/25] configure: Link test before auto-enabling crypto libraries

2019-05-22 Thread Richard Henderson
At least ubuntu 18.04 does not package static gnutls libraries.
At least Fedora 30 does not ship static nettle and gcrypt libraries.

Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Laurent Vivier 
Tested-by: Laurent Vivier 
Message-Id: <20190510012458.22706-2-richard.hender...@linaro.org>
Signed-off-by: Richard Henderson 
---
 configure | 72 +--
 1 file changed, 44 insertions(+), 28 deletions(-)

diff --git a/configure b/configure
index d2fc346302..571dd94ee2 100755
--- a/configure
+++ b/configure
@@ -2784,17 +2784,24 @@ fi
 # GNUTLS probe
 
 if test "$gnutls" != "no"; then
+pass="no"
 if $pkg_config --exists "gnutls >= 3.1.18"; then
 gnutls_cflags=$($pkg_config --cflags gnutls)
 gnutls_libs=$($pkg_config --libs gnutls)
-libs_softmmu="$gnutls_libs $libs_softmmu"
-libs_tools="$gnutls_libs $libs_tools"
-   QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
-gnutls="yes"
-elif test "$gnutls" = "yes"; then
+# Packaging for the static libraries is not always correct.
+# At least ubuntu 18.04 ships only shared libraries.
+write_c_skeleton
+if compile_prog "" "$gnutls_libs" ; then
+libs_softmmu="$gnutls_libs $libs_softmmu"
+libs_tools="$gnutls_libs $libs_tools"
+QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
+pass="yes"
+fi
+fi
+if test "$pass" = "no" && test "$gnutls" = "yes"; then
feature_not_found "gnutls" "Install gnutls devel >= 3.1.18"
 else
-gnutls="no"
+gnutls="$pass"
 fi
 fi
 
@@ -2849,43 +2856,54 @@ has_libgcrypt() {
 
 
 if test "$nettle" != "no"; then
+pass="no"
 if $pkg_config --exists "nettle >= 2.7.1"; then
 nettle_cflags=$($pkg_config --cflags nettle)
 nettle_libs=$($pkg_config --libs nettle)
 nettle_version=$($pkg_config --modversion nettle)
-libs_softmmu="$nettle_libs $libs_softmmu"
-libs_tools="$nettle_libs $libs_tools"
-QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
-nettle="yes"
-
-if test -z "$gcrypt"; then
-   gcrypt="no"
+# Link test to make sure the given libraries work (e.g for static).
+write_c_skeleton
+if compile_prog "" "$nettle_libs" ; then
+libs_softmmu="$nettle_libs $libs_softmmu"
+libs_tools="$nettle_libs $libs_tools"
+QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
+if test -z "$gcrypt"; then
+   gcrypt="no"
+fi
+pass="yes"
 fi
+fi
+if test "$pass" = "no" && test "$nettle" = "yes"; then
+feature_not_found "nettle" "Install nettle devel >= 2.7.1"
 else
-if test "$nettle" = "yes"; then
-feature_not_found "nettle" "Install nettle devel >= 2.7.1"
-else
-nettle="no"
-fi
+nettle="$pass"
 fi
 fi
 
 if test "$gcrypt" != "no"; then
+pass="no"
 if has_libgcrypt; then
 gcrypt_cflags=$(libgcrypt-config --cflags)
 gcrypt_libs=$(libgcrypt-config --libs)
-# Debian has remove -lgpg-error from libgcrypt-config
+# Debian has removed -lgpg-error from libgcrypt-config
 # as it "spreads unnecessary dependencies" which in
 # turn breaks static builds...
 if test "$static" = "yes"
 then
 gcrypt_libs="$gcrypt_libs -lgpg-error"
 fi
-libs_softmmu="$gcrypt_libs $libs_softmmu"
-libs_tools="$gcrypt_libs $libs_tools"
-QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
-gcrypt="yes"
 
+# Link test to make sure the given libraries work (e.g for static).
+write_c_skeleton
+if compile_prog "" "$gcrypt_libs" ; then
+libs_softmmu="$gcrypt_libs $libs_softmmu"
+libs_tools="$gcrypt_libs $libs_tools"
+QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
+pass="yes"
+fi
+fi
+if test "$pass" = "yes"; then
+gcrypt="yes"
 cat > $TMPC << EOF
 #include 
 int main(void) {
@@ -2898,12 +2916,10 @@ EOF
 if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
 gcrypt_hmac=yes
 fi
+elif test "$gcrypt" = "yes"; then
+feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
 else
-if test "$gcrypt" = "yes"; then
-feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
-else
-gcrypt="no"
-fi
+gcrypt="no"
 fi
 fi
 
-- 
2.17.1




Re: [Qemu-devel] [PATCH 1/2] sphinx: add qmp_lexer

2019-05-22 Thread John Snow



On 5/22/19 4:49 AM, Peter Maydell wrote:
> On Tue, 21 May 2019 at 21:07, John Snow  wrote:
>>
>> Sphinx, through Pygments, does not like annotated json examples very
>> much. In some versions of Sphinx (1.7), it will render the non-json
>> portions of code blocks in red, but in newer versions (2.0) it will
>> throw an exception and not highlight the block at all. Though we can
>> suppress this warning, it doesn't bring back highlighting on non-strict
>> json blocks.
>>
>> We can alleviate this by creating a custom lexer for QMP examples that
>> allows us to properly highlight these examples in a robust way, keeping
>> our directionality notations.
> 
>> diff --git a/docs/sphinx/qmp_lexer.py b/docs/sphinx/qmp_lexer.py
>> new file mode 100644
>> index 00..f619f11139
>> --- /dev/null
>> +++ b/docs/sphinx/qmp_lexer.py
>> @@ -0,0 +1,34 @@
>> +# QEMU Monitor Protocol Lexer Extension
>> +#
>> +# Copyright (C) 2019, Red Hat Inc.
>> +#
>> +# Authors:
>> +#  Eduardo Habkost 
>> +#  John Snow 
>> +#
>> +# This work is licensed under the terms of the GNU GPL, version 2.  See
>> +# the COPYING file in the top-level directory.
> 
> Did you definitely mean 2-only and not 2-or-later ?
> 
> thanks
> -- PMM
> 

Copy-paste pulled from another Python script. 2 or later is fine by me;
I can resend if desired (or, I'd be fine with anyone touching it up in
post.)




[Qemu-devel] [PULL 06/25] crypto: Use getrandom for qcrypto_random_bytes

2019-05-22 Thread Richard Henderson
Prefer it to direct use of /dev/urandom.

Reviewed-by: Laurent Vivier 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 crypto/random-platform.c | 37 -
 configure| 18 +-
 2 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 6df40744c7..cb3ca1bc09 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -27,7 +27,11 @@
 #include 
 static HCRYPTPROV hCryptProv;
 #else
-static int fd; /* a file handle to either /dev/urandom or /dev/random */
+# ifdef CONFIG_GETRANDOM
+#  include 
+# endif
+/* This is -1 for getrandom(), or a file handle for /dev/{u,}random.  */
+static int fd;
 #endif
 
 int qcrypto_random_init(Error **errp)
@@ -40,15 +44,20 @@ int qcrypto_random_init(Error **errp)
 return -1;
 }
 #else
-/* TBD perhaps also add support for BSD getentropy / Linux
- * getrandom syscalls directly */
+# ifdef CONFIG_GETRANDOM
+if (getrandom(NULL, 0, 0) == 0) {
+/* Use getrandom() */
+fd = -1;
+return 0;
+}
+/* Fall through to /dev/urandom case.  */
+# endif
 fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
 if (fd == -1 && errno == ENOENT) {
 fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
 }
-
 if (fd < 0) {
-error_setg(errp, "No /dev/urandom or /dev/random found");
+error_setg_errno(errp, errno, "No /dev/urandom or /dev/random");
 return -1;
 }
 #endif
@@ -66,6 +75,24 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
 return -1;
 }
 #else
+# ifdef CONFIG_GETRANDOM
+if (likely(fd < 0)) {
+while (1) {
+ssize_t got = getrandom(buf, buflen, 0);
+if (likely(got == buflen)) {
+return 0;
+}
+if (got >= 0) {
+buflen -= got;
+buf += got;
+} else if (errno != EINTR) {
+error_setg_errno(errp, errno, "getrandom");
+return -1;
+}
+}
+}
+/* Fall through to /dev/urandom case.  */
+# endif
 while (1) {
 ssize_t got = read(fd, buf, buflen);
 if (likely(got == buflen)) {
diff --git a/configure b/configure
index 54fa78c4dc..f3526a5bca 100755
--- a/configure
+++ b/configure
@@ -5815,6 +5815,20 @@ if compile_prog "" "" ; then
 have_utmpx=yes
 fi
 
+##
+# check for getrandom()
+
+have_getrandom=no
+cat > $TMPC << EOF
+#include 
+int main(void) {
+return getrandom(0, 0, GRND_NONBLOCK);
+}
+EOF
+if compile_prog "" "" ; then
+have_getrandom=yes
+fi
+
 ##
 # checks for sanitizers
 
@@ -7204,7 +7218,9 @@ fi
 if test "$have_utmpx" = "yes" ; then
   echo "HAVE_UTMPX=y" >> $config_host_mak
 fi
-
+if test "$have_getrandom" = "yes" ; then
+  echo "CONFIG_GETRANDOM=y" >> $config_host_mak
+fi
 if test "$ivshmem" = "yes" ; then
   echo "CONFIG_IVSHMEM=y" >> $config_host_mak
 fi
-- 
2.17.1




[Qemu-devel] [PULL 08/25] ui/vnc: Split out authentication_failed

2019-05-22 Thread Richard Henderson
There were 3 copies of this code, one of which used the wrong
data size for the failure indicator.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Gerd Hoffmann 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 ui/vnc.c | 37 +++--
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 1871422e1d..785edf3af1 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2535,6 +2535,18 @@ void start_client_init(VncState *vs)
 vnc_read_when(vs, protocol_client_init, 1);
 }
 
+static void authentication_failed(VncState *vs)
+{
+vnc_write_u32(vs, 1); /* Reject auth */
+if (vs->minor >= 8) {
+static const char err[] = "Authentication failed";
+vnc_write_u32(vs, sizeof(err));
+vnc_write(vs, err, sizeof(err));
+}
+vnc_flush(vs);
+vnc_client_error(vs);
+}
+
 static void make_challenge(VncState *vs)
 {
 int i;
@@ -2609,14 +2621,7 @@ static int protocol_client_auth_vnc(VncState *vs, 
uint8_t *data, size_t len)
 return 0;
 
 reject:
-vnc_write_u32(vs, 1); /* Reject auth */
-if (vs->minor >= 8) {
-static const char err[] = "Authentication failed";
-vnc_write_u32(vs, sizeof(err));
-vnc_write(vs, err, sizeof(err));
-}
-vnc_flush(vs);
-vnc_client_error(vs);
+authentication_failed(vs);
 qcrypto_cipher_free(cipher);
 return 0;
 }
@@ -2638,13 +2643,7 @@ static int protocol_client_auth(VncState *vs, uint8_t 
*data, size_t len)
  * must pick the one we sent. Verify this */
 if (data[0] != vs->auth) { /* Reject auth */
trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
-   vnc_write_u32(vs, 1);
-   if (vs->minor >= 8) {
-   static const char err[] = "Authentication failed";
-   vnc_write_u32(vs, sizeof(err));
-   vnc_write(vs, err, sizeof(err));
-   }
-   vnc_client_error(vs);
+   authentication_failed(vs);
 } else { /* Accept requested auth */
trace_vnc_auth_start(vs, vs->auth);
switch (vs->auth) {
@@ -2673,13 +2672,7 @@ static int protocol_client_auth(VncState *vs, uint8_t 
*data, size_t len)
 
default: /* Should not be possible, but just in case */
trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
-   vnc_write_u8(vs, 1);
-   if (vs->minor >= 8) {
-   static const char err[] = "Authentication failed";
-   vnc_write_u32(vs, sizeof(err));
-   vnc_write(vs, err, sizeof(err));
-   }
-   vnc_client_error(vs);
+   authentication_failed(vs);
}
 }
 return 0;
-- 
2.17.1




[Qemu-devel] [PULL 07/25] crypto: Change the qcrypto_random_bytes buffer type to void*

2019-05-22 Thread Richard Henderson
Using uint8_t* merely requires useless casts for use with
other types to be filled with randomness.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 include/crypto/random.h  | 2 +-
 crypto/random-gcrypt.c   | 2 +-
 crypto/random-gnutls.c   | 2 +-
 crypto/random-platform.c | 4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/crypto/random.h b/include/crypto/random.h
index 8764ca0562..fde592904e 100644
--- a/include/crypto/random.h
+++ b/include/crypto/random.h
@@ -34,7 +34,7 @@
  *
  * Returns 0 on success, -1 on error
  */
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
  size_t buflen,
  Error **errp);
 
diff --git a/crypto/random-gcrypt.c b/crypto/random-gcrypt.c
index 9f1c9ee60e..7aea4ac81f 100644
--- a/crypto/random-gcrypt.c
+++ b/crypto/random-gcrypt.c
@@ -24,7 +24,7 @@
 
 #include 
 
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
  size_t buflen,
  Error **errp G_GNUC_UNUSED)
 {
diff --git a/crypto/random-gnutls.c b/crypto/random-gnutls.c
index 445fd6a30b..ed6c9ca12f 100644
--- a/crypto/random-gnutls.c
+++ b/crypto/random-gnutls.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
  size_t buflen,
  Error **errp)
 {
diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index cb3ca1bc09..66624106fe 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -64,8 +64,8 @@ int qcrypto_random_init(Error **errp)
 return 0;
 }
 
-int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
- size_t buflen G_GNUC_UNUSED,
+int qcrypto_random_bytes(void *buf,
+ size_t buflen,
  Error **errp)
 {
 #ifdef _WIN32
-- 
2.17.1




[Qemu-devel] [PULL v2 07/11] target/mips: Refactor and fix INSERT. instructions

2019-05-22 Thread Aleksandar Markovic
From: Mateja Marjanovic 

The old version of the helper for the INSERT. MSA instructions
has been replaced with four helpers that don't use switch, and change
the endianness of the given index, when executed on a big endian host.

Signed-off-by: Mateja Marjanovic 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Message-Id: <1554212605-16457-6-git-send-email-mateja.marjano...@rt-rk.com>
---
 target/mips/helper.h |  5 +++-
 target/mips/msa_helper.c | 65 
 target/mips/translate.c  | 19 +-
 3 files changed, 71 insertions(+), 18 deletions(-)

diff --git a/target/mips/helper.h b/target/mips/helper.h
index c4a77e2..2863f60 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -877,7 +877,6 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
 
-DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
 DEF_HELPER_2(msa_cfcmsa, tl, env, i32)
@@ -944,6 +943,10 @@ DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32)
 
 DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 52680fe..ee1b1fa 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -1340,28 +1340,61 @@ void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
 env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
 }
 
-void helper_msa_insert_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
   uint32_t rs_num, uint32_t n)
 {
 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 target_ulong rs = env->active_tc.gpr[rs_num];
+n %= 16;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 8) {
+n = 8 - n - 1;
+} else {
+n = 24 - n - 1;
+}
+#endif
+pwd->b[n] = (int8_t)rs;
+}
 
-switch (df) {
-case DF_BYTE:
-pwd->b[n] = (int8_t)rs;
-break;
-case DF_HALF:
-pwd->h[n] = (int16_t)rs;
-break;
-case DF_WORD:
-pwd->w[n] = (int32_t)rs;
-break;
-case DF_DOUBLE:
-pwd->d[n] = (int64_t)rs;
-break;
-default:
-assert(0);
+void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
+  uint32_t rs_num, uint32_t n)
+{
+wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+target_ulong rs = env->active_tc.gpr[rs_num];
+n %= 8;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 4) {
+n = 4 - n - 1;
+} else {
+n = 12 - n - 1;
+}
+#endif
+pwd->h[n] = (int16_t)rs;
+}
+
+void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
+  uint32_t rs_num, uint32_t n)
+{
+wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+target_ulong rs = env->active_tc.gpr[rs_num];
+n %= 4;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 2) {
+n = 2 - n - 1;
+} else {
+n = 6 - n - 1;
 }
+#endif
+pwd->w[n] = (int32_t)rs;
+}
+
+void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
+  uint32_t rs_num, uint32_t n)
+{
+wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+target_ulong rs = env->active_tc.gpr[rs_num];
+n %= 2;
+pwd->d[n] = (int64_t)rs;
 }
 
 void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 68ea6ee..dd706ad 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28346,7 +28346,24 @@ static void gen_msa_elm_df(CPUMIPSState *env, 
DisasContext *ctx, uint32_t df,
 }
 break;
 case OPC_INSERT_df:
-gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
+switch (df) {
+case DF_BYTE:
+gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
+break;
+case DF_HALF:
+gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
+break;
+case DF_WORD:
+gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
+break;
+#if defined(TARGET_MIPS64)
+case DF_DOUBLE:
+gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
+break;
+#endif
+default:
+assert(0);
+}
 break;
 }

[Qemu-devel] [PULL 17/25] aspeed/scu: Use qemu_guest_getrandom_nofail

2019-05-22 Thread Richard Henderson
The random number is intended for use by the guest.  As such, we should
honor the -seed argument for reproducibility.  Use the *_nofail routine
instead of rolling our own error handling locally.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Joel Stanley 
Signed-off-by: Richard Henderson 
---
 hw/misc/aspeed_scu.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index c8217740ef..ab1e18ed4b 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -16,7 +16,7 @@
 #include "qapi/visitor.h"
 #include "qemu/bitops.h"
 #include "qemu/log.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.h"
 #include "trace.h"
 
 #define TO_REG(offset) ((offset) >> 2)
@@ -157,14 +157,8 @@ static const uint32_t 
ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
 
 static uint32_t aspeed_scu_get_random(void)
 {
-Error *err = NULL;
 uint32_t num;
-
-if (qcrypto_random_bytes((uint8_t *), sizeof(num), )) {
-error_report_err(err);
-exit(1);
-}
-
+qemu_guest_getrandom_nofail(, sizeof(num));
 return num;
 }
 
-- 
2.17.1




[Qemu-devel] [PULL 10/25] util: Add qemu_guest_getrandom and associated routines

2019-05-22 Thread Richard Henderson
This routine is intended to produce high-quality random numbers to the
guest.  Normally, such numbers are crypto quality from the host, but a
command-line option can force the use of a fully deterministic sequence
for use while debugging.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 include/qemu/guest-random.h | 68 +++
 util/guest-random.c | 93 +
 util/Makefile.objs  |  1 +
 3 files changed, 162 insertions(+)
 create mode 100644 include/qemu/guest-random.h
 create mode 100644 util/guest-random.c

diff --git a/include/qemu/guest-random.h b/include/qemu/guest-random.h
new file mode 100644
index 00..09ff9c2236
--- /dev/null
+++ b/include/qemu/guest-random.h
@@ -0,0 +1,68 @@
+/*
+ * QEMU guest-visible random functions
+ *
+ * Copyright 2019 Linaro, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#ifndef QEMU_GUEST_RANDOM_H
+#define QEMU_GUEST_RANDOM_H
+
+/**
+ * qemu_guest_random_seed_main(const char *optarg, Error **errp)
+ * @optarg: a non-NULL pointer to a C string
+ * @errp: an error indicator
+ *
+ * The @optarg value is that which accompanies the -seed argument.
+ * This forces qemu_guest_getrandom into deterministic mode.
+ *
+ * Returns 0 on success, < 0 on failure while setting *errp.
+ */
+int qemu_guest_random_seed_main(const char *optarg, Error **errp);
+
+/**
+ * qemu_guest_random_seed_thread_part1(void)
+ *
+ * If qemu_getrandom is in deterministic mode, returns an
+ * independent seed for the new thread.  Otherwise returns 0.
+ */
+uint64_t qemu_guest_random_seed_thread_part1(void);
+
+/**
+ * qemu_guest_random_seed_thread_part2(uint64_t seed)
+ * @seed: a value for the new thread.
+ *
+ * If qemu_guest_getrandom is in deterministic mode, this stores an
+ * independent seed for the new thread.  Otherwise a no-op.
+ */
+void qemu_guest_random_seed_thread_part2(uint64_t seed);
+
+/**
+ * qemu_guest_getrandom(void *buf, size_t len, Error **errp)
+ * @buf: a buffer of bytes to be written
+ * @len: the number of bytes in @buf
+ * @errp: an error indicator
+ *
+ * Fills len bytes in buf with random data.  This should only be used
+ * for data presented to the guest.  Host-side crypto services should
+ * use qcrypto_random_bytes.
+ *
+ * Returns 0 on success, < 0 on failure while setting *errp.
+ */
+int qemu_guest_getrandom(void *buf, size_t len, Error **errp);
+
+/**
+ * qemu_guest_getrandom_nofail(void *buf, size_t len)
+ * @buf: a buffer of bytes to be written
+ * @len: the number of bytes in @buf
+ *
+ * Like qemu_guest_getrandom, but will assert for failure.
+ * Use this when there is no reasonable recovery.
+ */
+void qemu_guest_getrandom_nofail(void *buf, size_t len);
+
+#endif /* QEMU_GUEST_RANDOM_H */
diff --git a/util/guest-random.c b/util/guest-random.c
new file mode 100644
index 00..e8124a3cad
--- /dev/null
+++ b/util/guest-random.c
@@ -0,0 +1,93 @@
+/*
+ * QEMU guest-visible random functions
+ *
+ * Copyright 2019 Linaro, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
+#include "crypto/random.h"
+
+
+static __thread GRand *thread_rand;
+static bool deterministic;
+
+
+static int glib_random_bytes(void *buf, size_t len)
+{
+GRand *rand = thread_rand;
+size_t i;
+uint32_t x;
+
+if (unlikely(rand == NULL)) {
+/* Thread not initialized for a cpu, or main w/o -seed.  */
+thread_rand = rand = g_rand_new();
+}
+
+for (i = 0; i + 4 <= len; i += 4) {
+x = g_rand_int(rand);
+__builtin_memcpy(buf + i, , 4);
+}
+if (i < len) {
+x = g_rand_int(rand);
+__builtin_memcpy(buf + i, , i - len);
+}
+return 0;
+}
+
+int qemu_guest_getrandom(void *buf, size_t len, Error **errp)
+{
+if (unlikely(deterministic)) {
+/* Deterministic implementation using Glib's Mersenne Twister.  */
+return glib_random_bytes(buf, len);
+} else {
+/* Non-deterministic implementation using crypto routines.  */
+return qcrypto_random_bytes(buf, len, errp);
+}
+}
+
+void qemu_guest_getrandom_nofail(void *buf, size_t len)
+{
+qemu_guest_getrandom(buf, len, _fatal);
+}
+
+uint64_t qemu_guest_random_seed_thread_part1(void)
+{
+if (deterministic) {
+uint64_t ret;
+glib_random_bytes(, sizeof(ret));
+return ret;
+}
+

[Qemu-devel] [PULL v2 05/11] target/mips: Refactor and fix COPY_S. instructions

2019-05-22 Thread Aleksandar Markovic
From: Mateja Marjanovic 

The old version of the helper for the COPY_S. MSA instructions
has been replaced with four helpers that don't use switch, and change
the endianness of the given index, when executed on a big endian host.

Signed-off-by: Mateja Marjanovic 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Message-Id: <1554212605-16457-4-git-send-email-mateja.marjano...@rt-rk.com>
---
 target/mips/helper.h |  7 +-
 target/mips/msa_helper.c | 62 +---
 target/mips/translate.c  | 19 ++-
 3 files changed, 67 insertions(+), 21 deletions(-)

diff --git a/target/mips/helper.h b/target/mips/helper.h
index a6d687e..de3a9e0 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -876,7 +876,7 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32)
 
 DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
-DEF_HELPER_5(msa_copy_s_df, void, env, i32, i32, i32, i32)
+
 DEF_HELPER_5(msa_copy_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
@@ -938,6 +938,11 @@ DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)
 
+DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
+
 DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 274c6ca..89b3be9 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -1249,29 +1249,53 @@ void helper_msa_splati_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 msa_splat_df(df, pwd, pws, n);
 }
 
-void helper_msa_copy_s_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
-  uint32_t ws, uint32_t n)
+void helper_msa_copy_s_b(CPUMIPSState *env, uint32_t rd,
+ uint32_t ws, uint32_t n)
 {
-n %= DF_ELEMENTS(df);
+n %= 16;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 8) {
+n = 8 - n - 1;
+} else {
+n = 24 - n - 1;
+}
+#endif
+env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
+}
 
-switch (df) {
-case DF_BYTE:
-env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
-break;
-case DF_HALF:
-env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
-break;
-case DF_WORD:
-env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
-break;
-#ifdef TARGET_MIPS64
-case DF_DOUBLE:
-env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
-break;
+void helper_msa_copy_s_h(CPUMIPSState *env, uint32_t rd,
+ uint32_t ws, uint32_t n)
+{
+n %= 8;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 4) {
+n = 4 - n - 1;
+} else {
+n = 12 - n - 1;
+}
 #endif
-default:
-assert(0);
+env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
+}
+
+void helper_msa_copy_s_w(CPUMIPSState *env, uint32_t rd,
+ uint32_t ws, uint32_t n)
+{
+n %= 4;
+#if defined(HOST_WORDS_BIGENDIAN)
+if (n < 2) {
+n = 2 - n - 1;
+} else {
+n = 6 - n - 1;
 }
+#endif
+env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
+}
+
+void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
+ uint32_t ws, uint32_t n)
+{
+n %= 2;
+env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
 }
 
 void helper_msa_copy_u_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
diff --git a/target/mips/translate.c b/target/mips/translate.c
index f96c0d0..c65d19e 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28301,7 +28301,24 @@ static void gen_msa_elm_df(CPUMIPSState *env, 
DisasContext *ctx, uint32_t df,
 switch (MASK_MSA_ELM(ctx->opcode)) {
 case OPC_COPY_S_df:
 if (likely(wd != 0)) {
-gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
+switch (df) {
+case DF_BYTE:
+gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
+break;
+case DF_HALF:
+gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
+break;
+case DF_WORD:
+gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
+break;
+#if defined(TARGET_MIPS64)
+case DF_DOUBLE:
+gen_helper_msa_copy_s_d(cpu_env, twd, tws, 

[Qemu-devel] [PULL 16/25] linux-user: Remove srand call

2019-05-22 Thread Richard Henderson
We no longer use rand() within linux-user.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/main.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 66c909a1a6..689bcf436d 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -623,8 +623,6 @@ int main(int argc, char **argv, char **envp)
 
 cpu_model = NULL;
 
-srand(time(NULL));
-
 qemu_add_opts(_trace_opts);
 
 optind = parse_args(argc, argv);
@@ -692,15 +690,6 @@ int main(int argc, char **argv, char **envp)
 {
 Error *err = NULL;
 if (seed_optarg != NULL) {
-unsigned long long seed;
-
-/* This will go away with the last user of rand(). */
-if (parse_uint_full(seed_optarg, , 0) != 0) {
-fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
-exit(EXIT_FAILURE);
-}
-srand(seed);
-
 qemu_guest_random_seed_main(seed_optarg, );
 } else {
 qcrypto_init();
-- 
2.17.1




[Qemu-devel] [PULL 11/25] cpus: Initialize pseudo-random seeds for all guest cpus

2019-05-22 Thread Richard Henderson
When the -seed option is given, call qemu_guest_random_seed_main,
putting the subsystem into deterministic mode.  Pass derived seeds
to each cpu created; which is a no-op unless the subsystem is in
deterministic mode.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 include/qom/cpu.h |  1 +
 cpus.c|  9 +
 vl.c  |  4 
 qemu-options.hx   | 10 ++
 4 files changed, 24 insertions(+)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 32983f27c3..98e12d914c 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -375,6 +375,7 @@ struct CPUState {
 int singlestep_enabled;
 int64_t icount_budget;
 int64_t icount_extra;
+uint64_t random_seed;
 sigjmp_buf jmp_env;
 
 QemuMutex work_mutex;
diff --git a/cpus.c b/cpus.c
index e58e7ab0f6..ffc57119ca 100644
--- a/cpus.c
+++ b/cpus.c
@@ -50,6 +50,7 @@
 #include "qemu/option.h"
 #include "qemu/bitmap.h"
 #include "qemu/seqlock.h"
+#include "qemu/guest-random.h"
 #include "tcg.h"
 #include "hw/nmi.h"
 #include "sysemu/replay.h"
@@ -1276,6 +1277,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 cpu->created = true;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 if (cpu_can_run(cpu)) {
@@ -1319,6 +1321,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 cpu->created = true;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 qemu_mutex_unlock_iothread();
@@ -1478,6 +1481,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
 cpu->created = true;
 cpu->can_do_io = 1;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 /* wait for initial kick-off after machine start */
 while (first_cpu->stopped) {
@@ -1592,6 +1596,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
 
 hax_init_vcpu(cpu);
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 if (cpu_can_run(cpu)) {
@@ -1631,6 +1636,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 cpu->created = true;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 if (cpu_can_run(cpu)) {
@@ -1671,6 +1677,7 @@ static void *qemu_whpx_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 cpu->created = true;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 if (cpu_can_run(cpu)) {
@@ -1724,6 +1731,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 cpu->can_do_io = 1;
 current_cpu = cpu;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 /* process any pending work */
 cpu->exit_request = 1;
@@ -2071,6 +2079,7 @@ void qemu_init_vcpu(CPUState *cpu)
 cpu->nr_cores = smp_cores;
 cpu->nr_threads = smp_threads;
 cpu->stopped = true;
+cpu->random_seed = qemu_guest_random_seed_thread_part1();
 
 if (!cpu->as) {
 /* If the target cpu hasn't set up any address spaces itself,
diff --git a/vl.c b/vl.c
index 201144b162..5550bd7693 100644
--- a/vl.c
+++ b/vl.c
@@ -128,6 +128,7 @@ int main(int argc, char **argv)
 #include "qapi/qapi-commands-ui.h"
 #include "qapi/qmp/qerror.h"
 #include "sysemu/iothread.h"
+#include "qemu/guest-random.h"
 
 #define MAX_VIRTIO_CONSOLES 1
 
@@ -3349,6 +3350,9 @@ int main(int argc, char **argv, char **envp)
 case QEMU_OPTION_DFILTER:
 qemu_set_dfilter_ranges(optarg, _fatal);
 break;
+case QEMU_OPTION_seed:
+qemu_guest_random_seed_main(optarg, _fatal);
+break;
 case QEMU_OPTION_s:
 add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
 break;
diff --git a/qemu-options.hx b/qemu-options.hx
index 5daa5a8fb0..7ae3373a00 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3641,6 +3641,16 @@ the 0x200 sized block starting at 0xffc8 and 
another 0x1000 sized
 block starting at 0xffc5f000.
 ETEXI
 
+DEF("seed", HAS_ARG, QEMU_OPTION_seed, \
+"-seed number   seed the pseudo-random number generator\n",
+QEMU_ARCH_ALL)
+STEXI
+@item -seed @var{number}
+@findex -seed
+Force the guest to use a deterministic pseudo-random number generator, seeded
+with @var{number}.  This does not affect crypto routines within the host.
+ETEXI
+
 DEF("L", HAS_ARG, QEMU_OPTION_L, \
 "-L path set the directory for the BIOS, VGA BIOS and keymaps\n",
 QEMU_ARCH_ALL)
-- 
2.17.1




[Qemu-devel] [PULL v2 04/11] target/mips: Fix MSA instructions ST. on big endian host

2019-05-22 Thread Aleksandar Markovic
From: Mateja Marjanovic 

Fix the case when the host is a big endian machine, and change
the approach toward ST. instruction helpers.

Signed-off-by: Mateja Marjanovic 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Message-Id: <1554212605-16457-3-git-send-email-mateja.marjano...@rt-rk.com>
---
 target/mips/op_helper.c | 200 +++-
 1 file changed, 180 insertions(+), 20 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index a8ae438..3918027 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -4550,31 +4550,191 @@ static inline void ensure_writable_pages(CPUMIPSState 
*env,
 #endif
 }
 
-#define MSA_ST_DF(DF, TYPE, ST_INSN, ...)   \
-void helper_msa_st_ ## TYPE(CPUMIPSState *env, uint32_t wd, \
-target_ulong addr)  \
-{   \
-wr_t *pwd = &(env->active_fpu.fpr[wd].wr);  \
-int mmu_idx = cpu_mmu_index(env, false);   \
-int i;  \
-MEMOP_IDX(DF)   \
-ensure_writable_pages(env, addr, mmu_idx, GETPC()); \
-for (i = 0; i < DF_ELEMENTS(DF); i++) { \
-ST_INSN(env, addr + (i << DF), pwd->TYPE[i], ##__VA_ARGS__);\
-}   \
+void helper_msa_st_b(CPUMIPSState *env, uint32_t wd,
+ target_ulong addr)
+{
+wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+int mmu_idx = cpu_mmu_index(env, false);
+
+MEMOP_IDX(DF_BYTE)
+ensure_writable_pages(env, addr, mmu_idx, GETPC());
+#if !defined(CONFIG_USER_ONLY)
+#if !defined(HOST_WORDS_BIGENDIAN)
+helper_ret_stb_mmu(env, addr + (0  << DF_BYTE), pwd->b[0],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (1  << DF_BYTE), pwd->b[1],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (2  << DF_BYTE), pwd->b[2],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (3  << DF_BYTE), pwd->b[3],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (4  << DF_BYTE), pwd->b[4],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (5  << DF_BYTE), pwd->b[5],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (6  << DF_BYTE), pwd->b[6],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (7  << DF_BYTE), pwd->b[7],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (8  << DF_BYTE), pwd->b[8],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (9  << DF_BYTE), pwd->b[9],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[10], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[11], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[12], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[13], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[14], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[15], oi, GETPC());
+#else
+helper_ret_stb_mmu(env, addr + (7  << DF_BYTE), pwd->b[0],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (6  << DF_BYTE), pwd->b[1],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (5  << DF_BYTE), pwd->b[2],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (4  << DF_BYTE), pwd->b[3],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (3  << DF_BYTE), pwd->b[4],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (2  << DF_BYTE), pwd->b[5],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (1  << DF_BYTE), pwd->b[6],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (0  << DF_BYTE), pwd->b[7],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[8],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[9],  oi, GETPC());
+helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[10], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[11], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[12], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[13], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (9  << DF_BYTE), pwd->b[14], oi, GETPC());
+helper_ret_stb_mmu(env, addr + (8  << DF_BYTE), pwd->b[15], oi, GETPC());
+#endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+cpu_stb_data(env, addr + (0  << DF_BYTE), pwd->b[0]);
+cpu_stb_data(env, addr + (1  << DF_BYTE), pwd->b[1]);
+cpu_stb_data(env, addr + (2  << DF_BYTE), pwd->b[2]);
+cpu_stb_data(env, addr + (3  << DF_BYTE), pwd->b[3]);
+cpu_stb_data(env, addr + (4  << DF_BYTE), pwd->b[4]);
+cpu_stb_data(env, addr + (5  << DF_BYTE), pwd->b[5]);
+cpu_stb_data(env, addr + (6  << DF_BYTE), pwd->b[6]);
+cpu_stb_data(env, addr + (7  << DF_BYTE), 

[Qemu-devel] [PULL v2 00/11] MIPS queue for May 19th, 2019 - v2

2019-05-22 Thread Aleksandar Markovic
From: Aleksandar Markovic 

The following changes since commit a4f667b6714916683408b983cfe0a615a725775f:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190521-3' into 
staging (2019-05-21 16:30:13 +0100)

are available in the git repository at:

  https://github.com/AMarkovic/qemu tags/mips-queue-may-19-2019-v2

for you to fetch changes up to 9a89468145b8a3e53e508992f54061427c52780f:

  BootLinuxSshTest: Test some userspace commands on Malta (2019-05-22 20:10:46 
+0200)



MIPS queue for May 19th, 2019 - v2

v1-v2:
   - fixed missing invocations in patch on ST. that caused
 clang build error
   - added a patch on acceptance test for Malta

overall content:

   * Improved usage of object_initialize() and object_initialize_child()
   * Added an acceptance test for Malta board
   * Better handling of memory pages (flag PAGE_EXEC)
   * A set of fixes for emulation of MSA ASE on big endian hosts
   * Better handling of 'div by zero' cases of MSA ASE instructions



Jakub Jermář (1):
  mips: Decide to map PAGE_EXEC in map_address

Mateja Marjanovic (7):
  target/mips: Make the results of DIV_. the same as on
hardware
  target/mips: Make the results of MOD_. the same as on
hardware
  target/mips: Fix MSA instructions LD. on big endian host
  target/mips: Fix MSA instructions ST. on big endian host
  target/mips: Refactor and fix COPY_S. instructions
  target/mips: Refactor and fix COPY_U. instructions
  target/mips: Refactor and fix INSERT. instructions

Philippe Mathieu-Daudé (3):
  hw/mips: Use object_initialize() on MIPSCPSState
  hw/mips: Use object_initialize_child for correct reference counting
  BootLinuxSshTest: Test some userspace commands on Malta

 MAINTAINERS  |   1 +
 hw/mips/boston.c |  25 +-
 hw/mips/cps.c|  20 +-
 hw/mips/mips_malta.c |  17 +-
 target/mips/helper.c |  13 +-
 target/mips/helper.h |  16 +-
 target/mips/msa_helper.c | 191 ++-
 target/mips/op_helper.c  | 388 +++
 target/mips/translate.c  |  59 -
 tests/acceptance/linux_ssh_mips_malta.py | 229 ++
 tests/requirements.txt   |   1 +
 11 files changed, 817 insertions(+), 143 deletions(-)
 create mode 100644 tests/acceptance/linux_ssh_mips_malta.py

-- 
2.7.4




[Qemu-devel] [PULL 15/25] linux-user/aarch64: Use qemu_guest_getrandom for PAUTH keys

2019-05-22 Thread Richard Henderson
Use a better interface for random numbers than rand() * 3.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_syscall.h |  2 --
 linux-user/aarch64/cpu_loop.c   | 29 ++-
 linux-user/syscall.c| 31 -
 3 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/linux-user/aarch64/target_syscall.h 
b/linux-user/aarch64/target_syscall.h
index b595e5da82..995e475c73 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -29,6 +29,4 @@ struct target_pt_regs {
 # define TARGET_PR_PAC_APDBKEY   (1 << 3)
 # define TARGET_PR_PAC_APGAKEY   (1 << 4)
 
-void arm_init_pauth_key(ARMPACKey *key);
-
 #endif /* AARCH64_TARGET_SYSCALL_H */
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index d75fd9d3e2..cedad39ca0 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu.h"
 #include "cpu_loop-common.h"
+#include "qemu/guest-random.h"
 
 #define get_user_code_u32(x, gaddr, env)\
 ({ abi_long __r = get_user_u32((x), (gaddr));   \
@@ -147,24 +148,6 @@ void cpu_loop(CPUARMState *env)
 }
 }
 
-static uint64_t arm_rand64(void)
-{
-int shift = 64 - clz64(RAND_MAX);
-int i, n = 64 / shift + (64 % shift != 0);
-uint64_t ret = 0;
-
-for (i = 0; i < n; i++) {
-ret = (ret << shift) | rand();
-}
-return ret;
-}
-
-void arm_init_pauth_key(ARMPACKey *key)
-{
-key->lo = arm_rand64();
-key->hi = arm_rand64();
-}
-
 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
 {
 ARMCPU *cpu = arm_env_get_cpu(env);
@@ -192,11 +175,11 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs)
 #endif
 
 if (cpu_isar_feature(aa64_pauth, cpu)) {
-arm_init_pauth_key(>apia_key);
-arm_init_pauth_key(>apib_key);
-arm_init_pauth_key(>apda_key);
-arm_init_pauth_key(>apdb_key);
-arm_init_pauth_key(>apga_key);
+qemu_guest_getrandom_nofail(>apia_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>apib_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>apda_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>apdb_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>apga_key, sizeof(ARMPACKey));
 }
 
 ts->stack_base = info->start_stack;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f3ea9cac21..72e43b517a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -108,6 +108,7 @@
 
 #include "qemu.h"
 #include "qemu/guest-random.h"
+#include "qapi/error.h"
 #include "fd-trans.h"
 
 #ifndef CLONE_IO
@@ -9765,25 +9766,45 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY |
TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY |
TARGET_PR_PAC_APGAKEY);
+int ret = 0;
+Error *err = NULL;
+
 if (arg2 == 0) {
 arg2 = all;
 } else if (arg2 & ~all) {
 return -TARGET_EINVAL;
 }
 if (arg2 & TARGET_PR_PAC_APIAKEY) {
-arm_init_pauth_key(>apia_key);
+ret |= qemu_guest_getrandom(>apia_key,
+sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APIBKEY) {
-arm_init_pauth_key(>apib_key);
+ret |= qemu_guest_getrandom(>apib_key,
+sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APDAKEY) {
-arm_init_pauth_key(>apda_key);
+ret |= qemu_guest_getrandom(>apda_key,
+sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APDBKEY) {
-arm_init_pauth_key(>apdb_key);
+ret |= qemu_guest_getrandom(>apdb_key,
+sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APGAKEY) {
-arm_init_pauth_key(>apga_key);
+ret |= qemu_guest_getrandom(>apga_key,
+sizeof(ARMPACKey), );
+}
+if (ret != 0) {
+/*
+ * Some unknown failure in the crypto.  The best
+ * we can do is log it and fail the syscall.
+  

[Qemu-devel] [PULL 12/25] linux-user: Initialize pseudo-random seeds for all guest cpus

2019-05-22 Thread Richard Henderson
When the -seed option is given, call qemu_guest_random_seed_main,
putting the subsystem into deterministic mode.  Pass derived seeds
to each cpu created during clone; which is a no-op unless the
subsystem is in deterministic mode.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/main.c| 30 +++---
 linux-user/syscall.c |  3 +++
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 3d2230320b..7e704845c0 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -34,6 +34,7 @@
 #include "tcg.h"
 #include "qemu/timer.h"
 #include "qemu/envlist.h"
+#include "qemu/guest-random.h"
 #include "elf.h"
 #include "trace/control.h"
 #include "target_elf.h"
@@ -48,6 +49,7 @@ static int gdbstub_port;
 static envlist_t *envlist;
 static const char *cpu_model;
 static const char *cpu_type;
+static const char *seed_optarg;
 unsigned long mmap_min_addr;
 unsigned long guest_base;
 int have_guest_base;
@@ -290,15 +292,9 @@ static void handle_arg_pagesize(const char *arg)
 }
 }
 
-static void handle_arg_randseed(const char *arg)
+static void handle_arg_seed(const char *arg)
 {
-unsigned long long seed;
-
-if (parse_uint_full(arg, , 0) != 0 || seed > UINT_MAX) {
-fprintf(stderr, "Invalid seed number: %s\n", arg);
-exit(EXIT_FAILURE);
-}
-srand(seed);
+seed_optarg = arg;
 }
 
 static void handle_arg_gdb(const char *arg)
@@ -433,7 +429,7 @@ static const struct qemu_argument arg_table[] = {
  "",   "run in singlestep mode"},
 {"strace", "QEMU_STRACE",  false, handle_arg_strace,
  "",   "log system calls"},
-{"seed",   "QEMU_RAND_SEED",   true,  handle_arg_randseed,
+{"seed",   "QEMU_RAND_SEED",   true,  handle_arg_seed,
  "",   "Seed for pseudo-random number generator"},
 {"trace",  "QEMU_TRACE",   true,  handle_arg_trace,
  "",   "[[enable=]][,events=][,file=]"},
@@ -689,8 +685,20 @@ int main(int argc, char **argv, char **envp)
 do_strace = 1;
 }
 
-if (getenv("QEMU_RAND_SEED")) {
-handle_arg_randseed(getenv("QEMU_RAND_SEED"));
+if (seed_optarg == NULL) {
+seed_optarg = getenv("QEMU_RAND_SEED");
+}
+if (seed_optarg != NULL) {
+unsigned long long seed;
+
+/* This will go away with the last user of rand(). */
+if (parse_uint_full(seed_optarg, , 0) != 0) {
+fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
+exit(EXIT_FAILURE);
+}
+srand(seed);
+
+qemu_guest_random_seed_main(seed_optarg, _fatal);
 }
 
 target_environ = envlist_to_environ(envlist, NULL);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index efa3ec2837..f3ea9cac21 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -107,6 +107,7 @@
 #include "uname.h"
 
 #include "qemu.h"
+#include "qemu/guest-random.h"
 #include "fd-trans.h"
 
 #ifndef CLONE_IO
@@ -5482,6 +5483,7 @@ static void *clone_func(void *arg)
 put_user_u32(info->tid, info->child_tidptr);
 if (info->parent_tidptr)
 put_user_u32(info->tid, info->parent_tidptr);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 /* Enable signals.  */
 sigprocmask(SIG_SETMASK, >sigmask, NULL);
 /* Signal to the parent that we're ready.  */
@@ -5568,6 +5570,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, 
abi_ulong newsp,
initializing, so temporarily block all signals.  */
 sigfillset();
 sigprocmask(SIG_BLOCK, , );
+cpu->random_seed = qemu_guest_random_seed_thread_part1();
 
 /* If this is our first additional thread, we need to ensure we
  * generate code for parallel execution and flush old translations.
-- 
2.17.1




[Qemu-devel] [PULL 00/25] Add qemu_getrandom and ARMv8.5-RNG etc

2019-05-22 Thread Richard Henderson
This is v8, rebased to avoid a conflict with 8d5d515a0fb
("build: chardev is only needed for softmmu targets"),
which affected patch 2.

Daniel and Laurent gave me acks for issuing a pull request
touching their subsystems.  The reasonable thing seemed to
be to put those into the log for the signed tag itself.


r~


The following changes since commit a4f667b6714916683408b983cfe0a615a725775f:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190521-3' into 
staging (2019-05-21 16:30:13 +0100)

are available in the Git repository at:

  https://github.com/rth7680/qemu.git tags/pull-rng-20190522

for you to fetch changes up to 369fd5ca66810b2ddb16e23a497eabe59385eceb:

  target/i386: Implement CPUID_EXT_RDRAND (2019-05-22 12:38:54 -0400)


Introduce qemu_guest_getrandom.
Use qemu_guest_getrandom in aspeed, nrf51, bcm2835, exynos4210 rng devices.
Use qemu_guest_getrandom in target/ppc darn instruction.
Support ARMv8.5-RNG extension.
Support x86 RDRAND extension.

Acked-by: Daniel P. Berrangé 
Acked-by: Laurent Vivier 


Richard Henderson (25):
  configure: Link test before auto-enabling crypto libraries
  build: Link user-only with crypto random number objects
  crypto: Reverse code blocks in random-platform.c
  crypto: Do not fail for EINTR during qcrypto_random_bytes
  crypto: Use O_CLOEXEC in qcrypto_random_init
  crypto: Use getrandom for qcrypto_random_bytes
  crypto: Change the qcrypto_random_bytes buffer type to void*
  ui/vnc: Split out authentication_failed
  ui/vnc: Use gcrypto_random_bytes for start_auth_vnc
  util: Add qemu_guest_getrandom and associated routines
  cpus: Initialize pseudo-random seeds for all guest cpus
  linux-user: Initialize pseudo-random seeds for all guest cpus
  linux-user: Call qcrypto_init if not using -seed
  linux-user: Use qemu_guest_getrandom_nofail for AT_RANDOM
  linux-user/aarch64: Use qemu_guest_getrandom for PAUTH keys
  linux-user: Remove srand call
  aspeed/scu: Use qemu_guest_getrandom_nofail
  hw/misc/nrf51_rng: Use qemu_guest_getrandom_nofail
  hw/misc/bcm2835_rng: Use qemu_guest_getrandom_nofail
  hw/misc/exynos4210_rng: Use qemu_guest_getrandom
  target/arm: Put all PAC keys into a structure
  target/arm: Implement ARMv8.5-RNG
  target/ppc: Use gen_io_start/end around DARN
  target/ppc: Use qemu_guest_getrandom for DARN
  target/i386: Implement CPUID_EXT_RDRAND

 Makefile|   4 +-
 Makefile.objs   |   2 +-
 Makefile.target |   4 +-
 include/crypto/random.h |   2 +-
 include/qemu/guest-random.h |  68 +++
 include/qom/cpu.h   |   1 +
 linux-user/aarch64/target_syscall.h |   2 -
 target/arm/cpu.h|  17 --
 target/i386/helper.h|   2 +
 cpus.c  |   9 
 crypto/random-gcrypt.c  |   2 +-
 crypto/random-gnutls.c  |   2 +-
 crypto/random-platform.c| 104 +---
 hw/misc/aspeed_scu.c|  10 +---
 hw/misc/bcm2835_rng.c   |  32 +--
 hw/misc/exynos4210_rng.c|  11 ++--
 hw/misc/nrf51_rng.c |   4 +-
 linux-user/aarch64/cpu_loop.c   |  25 +
 linux-user/elfload.c|   8 ++-
 linux-user/main.c   |  33 +++-
 linux-user/syscall.c|  34 ++--
 target/arm/cpu64.c  |   1 +
 target/arm/helper.c |  64 ++
 target/arm/pauth_helper.c   |  18 +++
 target/i386/cpu.c   |   5 +-
 target/i386/int_helper.c|  21 
 target/i386/translate.c |  62 +++--
 target/ppc/int_helper.c |  39 +-
 target/ppc/translate.c  |  21 +---
 ui/vnc.c|  53 --
 util/guest-random.c |  93 
 vl.c|   4 ++
 configure   |  87 --
 crypto/Makefile.objs|  11 ++--
 qemu-options.hx |  10 
 util/Makefile.objs  |   1 +
 36 files changed, 610 insertions(+), 256 deletions(-)
 create mode 100644 include/qemu/guest-random.h
 create mode 100644 util/guest-random.c



[Qemu-devel] [PULL v2 01/11] target/mips: Make the results of DIV_. the same as on hardware

2019-05-22 Thread Aleksandar Markovic
From: Mateja Marjanovic 

MSA instructions DIV_. when dividing by zero,
didn't return the same value when executed on a referent hardware
(FPGA MIPS 64 r6, little endian) and when executed on QEMU, which
is not a real bug, because the result when dividing by zero is
UNPREDICTABLE [1] (page 141, 142).

[1] MIPS Architecture for Programmers
Volume IV-j: The MIPS64 SIMD
Architecture Module, Revision 1.12

Signed-off-by: Mateja Marjanovic 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Message-Id: <1554207110-9113-2-git-send-email-mateja.marjano...@rt-rk.com>
---
 target/mips/msa_helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index c74e3cd..596190b 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -641,14 +641,15 @@ static inline int64_t msa_div_s_df(uint32_t df, int64_t 
arg1, int64_t arg2)
 if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
 return DF_MIN_INT(df);
 }
-return arg2 ? arg1 / arg2 : 0;
+return arg2 ? arg1 / arg2
+: arg1 >= 0 ? -1 : 1;
 }
 
 static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
 uint64_t u_arg1 = UNSIGNED(arg1, df);
 uint64_t u_arg2 = UNSIGNED(arg2, df);
-return u_arg2 ? u_arg1 / u_arg2 : 0;
+return arg2 ? u_arg1 / u_arg2 : -1;
 }
 
 static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
-- 
2.7.4




[Qemu-devel] [PULL 21/25] target/arm: Put all PAC keys into a structure

2019-05-22 Thread Richard Henderson
This allows us to use a single syscall to initialize them all.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h  | 12 +++-
 linux-user/aarch64/cpu_loop.c |  6 +-
 linux-user/syscall.c  | 10 +-
 target/arm/helper.c   | 20 ++--
 target/arm/pauth_helper.c | 18 +-
 5 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 733b840a71..892f9a4ad2 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -636,11 +636,13 @@ typedef struct CPUARMState {
 } iwmmxt;
 
 #ifdef TARGET_AARCH64
-ARMPACKey apia_key;
-ARMPACKey apib_key;
-ARMPACKey apda_key;
-ARMPACKey apdb_key;
-ARMPACKey apga_key;
+struct {
+ARMPACKey apia;
+ARMPACKey apib;
+ARMPACKey apda;
+ARMPACKey apdb;
+ARMPACKey apga;
+} keys;
 #endif
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index cedad39ca0..2f2f63e3e8 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -175,11 +175,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs)
 #endif
 
 if (cpu_isar_feature(aa64_pauth, cpu)) {
-qemu_guest_getrandom_nofail(>apia_key, sizeof(ARMPACKey));
-qemu_guest_getrandom_nofail(>apib_key, sizeof(ARMPACKey));
-qemu_guest_getrandom_nofail(>apda_key, sizeof(ARMPACKey));
-qemu_guest_getrandom_nofail(>apdb_key, sizeof(ARMPACKey));
-qemu_guest_getrandom_nofail(>apga_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>keys, sizeof(env->keys));
 }
 
 ts->stack_base = info->start_stack;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 72e43b517a..3de792a04c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9775,23 +9775,23 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return -TARGET_EINVAL;
 }
 if (arg2 & TARGET_PR_PAC_APIAKEY) {
-ret |= qemu_guest_getrandom(>apia_key,
+ret |= qemu_guest_getrandom(>keys.apia,
 sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APIBKEY) {
-ret |= qemu_guest_getrandom(>apib_key,
+ret |= qemu_guest_getrandom(>keys.apib,
 sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APDAKEY) {
-ret |= qemu_guest_getrandom(>apda_key,
+ret |= qemu_guest_getrandom(>keys.apda,
 sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APDBKEY) {
-ret |= qemu_guest_getrandom(>apdb_key,
+ret |= qemu_guest_getrandom(>keys.apdb,
 sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APGAKEY) {
-ret |= qemu_guest_getrandom(>apga_key,
+ret |= qemu_guest_getrandom(>keys.apga,
 sizeof(ARMPACKey), );
 }
 if (ret != 0) {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index e2d5c8e34f..6b91082b8b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5707,43 +5707,43 @@ static const ARMCPRegInfo pauth_reginfo[] = {
 { .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
   .access = PL1_RW, .accessfn = access_pauth,
-  .fieldoffset = offsetof(CPUARMState, apda_key.lo) },
+  .fieldoffset = offsetof(CPUARMState, keys.apda.lo) },
 { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
   .access = PL1_RW, .accessfn = access_pauth,
-  .fieldoffset = offsetof(CPUARMState, apda_key.hi) },
+  .fieldoffset = offsetof(CPUARMState, keys.apda.hi) },
 { .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
   .access = PL1_RW, .accessfn = access_pauth,
-  .fieldoffset = offsetof(CPUARMState, apdb_key.lo) },
+  .fieldoffset = offsetof(CPUARMState, keys.apdb.lo) },
 { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
   .access = PL1_RW, .accessfn = access_pauth,
-  .fieldoffset = offsetof(CPUARMState, apdb_key.hi) },
+  .fieldoffset = offsetof(CPUARMState, keys.apdb.hi) },
 { .name = "APGAKEYLO_EL1", .state = 

[Qemu-devel] [PULL 22/25] target/arm: Implement ARMv8.5-RNG

2019-05-22 Thread Richard Henderson
Use the newly introduced infrastructure for guest random numbers.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h|  5 +
 target/arm/cpu64.c  |  1 +
 target/arm/helper.c | 44 
 3 files changed, 50 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 892f9a4ad2..c34207611b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3521,6 +3521,11 @@ static inline bool isar_feature_aa64_condm_5(const 
ARMISARegisters *id)
 return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
 }
 
+static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
+{
+return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
+}
+
 static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
 {
 return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 228906f267..835f73cceb 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -310,6 +310,7 @@ static void aarch64_max_initfn(Object *obj)
 t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
 t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
 t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
+t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
 cpu->isar.id_aa64isar0 = t;
 
 t = cpu->isar.id_aa64isar1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6b91082b8b..acd23c53ca 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -22,6 +22,8 @@
 #include "fpu/softfloat.h"
 #include "qemu/range.h"
 #include "qapi/qapi-commands-target.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
 
 #define ARM_CPU_FREQ 10 /* FIXME: 1 GHz, should be configurable */
 
@@ -5746,6 +5748,45 @@ static const ARMCPRegInfo pauth_reginfo[] = {
   .fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
 REGINFO_SENTINEL
 };
+
+static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+Error *err = NULL;
+uint64_t ret;
+
+/* Success sets NZCV = .  */
+env->NF = env->CF = env->VF = 0, env->ZF = 1;
+
+if (qemu_guest_getrandom(, sizeof(ret), ) < 0) {
+/*
+ * ??? Failed, for unknown reasons in the crypto subsystem.
+ * The best we can do is log the reason and return the
+ * timed-out indication to the guest.  There is no reason
+ * we know to expect this failure to be transitory, so the
+ * guest may well hang retrying the operation.
+ */
+qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
+  ri->name, error_get_pretty(err));
+error_free(err);
+
+env->ZF = 0; /* NZCF = 0100 */
+return 0;
+}
+return ret;
+}
+
+/* We do not support re-seeding, so the two registers operate the same.  */
+static const ARMCPRegInfo rndr_reginfo[] = {
+{ .name = "RNDR", .state = ARM_CP_STATE_AA64,
+  .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
+  .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
+  .access = PL0_R, .readfn = rndr_readfn },
+{ .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
+  .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
+  .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
+  .access = PL0_R, .readfn = rndr_readfn },
+REGINFO_SENTINEL
+};
 #endif
 
 static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -6690,6 +6731,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 if (cpu_isar_feature(aa64_pauth, cpu)) {
 define_arm_cp_regs(cpu, pauth_reginfo);
 }
+if (cpu_isar_feature(aa64_rndr, cpu)) {
+define_arm_cp_regs(cpu, rndr_reginfo);
+}
 #endif
 
 /*
-- 
2.17.1




[Qemu-devel] [PULL 20/25] hw/misc/exynos4210_rng: Use qemu_guest_getrandom

2019-05-22 Thread Richard Henderson
The random number is intended for use by the guest.  As such, we should
honor the -seed argument for reproducibility.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 hw/misc/exynos4210_rng.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/misc/exynos4210_rng.c b/hw/misc/exynos4210_rng.c
index 4ecbebd2d7..0e70ffb404 100644
--- a/hw/misc/exynos4210_rng.c
+++ b/hw/misc/exynos4210_rng.c
@@ -18,10 +18,10 @@
  */
 
 #include "qemu/osdep.h"
-#include "crypto/random.h"
 #include "hw/sysbus.h"
 #include "qapi/error.h"
 #include "qemu/log.h"
+#include "qemu/guest-random.h"
 
 #define DEBUG_EXYNOS_RNG 0
 
@@ -109,7 +109,6 @@ static void exynos4210_rng_set_seed(Exynos4210RngState *s, 
unsigned int i,
 static void exynos4210_rng_run_engine(Exynos4210RngState *s)
 {
 Error *err = NULL;
-int ret;
 
 /* Seed set? */
 if ((s->reg_status & EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE) == 0) {
@@ -127,13 +126,11 @@ static void exynos4210_rng_run_engine(Exynos4210RngState 
*s)
 }
 
 /* Get randoms */
-ret = qcrypto_random_bytes((uint8_t *)s->randr_value,
-   sizeof(s->randr_value), );
-if (!ret) {
+if (qemu_guest_getrandom(s->randr_value, sizeof(s->randr_value), )) {
+error_report_err(err);
+} else {
 /* Notify that PRNG is ready */
 s->reg_status |= EXYNOS4210_RNG_STATUS_PRNG_DONE;
-} else {
-error_report_err(err);
 }
 
 out:
-- 
2.17.1




[Qemu-devel] [PULL 02/25] build: Link user-only with crypto random number objects

2019-05-22 Thread Richard Henderson
For user-only, we require only the random number bits of the
crypto subsystem.  Rename crypto-aes-obj-y to crypto-user-obj-y,
and add the random number objects, plus init.o to handle any
extra stuff the crypto library requires.

Move the crypto libraries from libs_softmmu and libs_tools to
LIBS, so that they are universally used.

Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 Makefile |  4 ++--
 Makefile.objs|  2 +-
 Makefile.target  |  4 ++--
 configure|  9 +++--
 crypto/Makefile.objs | 11 ++-
 5 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/Makefile b/Makefile
index 155f066a20..3dbe82a9e4 100644
--- a/Makefile
+++ b/Makefile
@@ -412,7 +412,7 @@ dummy := $(call unnest-vars,, \
 block-obj-y \
 block-obj-m \
 crypto-obj-y \
-crypto-aes-obj-y \
+crypto-user-obj-y \
 qom-obj-y \
 io-obj-y \
 common-obj-y \
@@ -486,7 +486,7 @@ subdir-slirp: .git-submodule-status
$(call quiet-command,$(MAKE) -C $(SRC_PATH)/slirp 
BUILD_DIR="$(BUILD_DIR)/slirp" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(QEMU_CFLAGS) $(CFLAGS)" LDFLAGS="$(LDFLAGS)")
 
 $(SUBDIR_RULES): libqemuutil.a $(common-obj-y) \
-   $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
+   $(qom-obj-y) $(crypto-user-obj-$(CONFIG_USER_ONLY))
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
 # Only keep -O and -g cflags
diff --git a/Makefile.objs b/Makefile.objs
index 2b0793ecc9..dcba4429c8 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -25,7 +25,7 @@ block-obj-m = block/
 # crypto-obj-y is code used by both qemu system emulation and qemu-img
 
 crypto-obj-y = crypto/
-crypto-aes-obj-y = crypto/
+crypto-user-obj-y = crypto/
 
 ###
 # qom-obj-y is code used by both qemu system emulation and qemu-img
diff --git a/Makefile.target b/Makefile.target
index fdbe7c89f4..4ef4ce5996 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -180,7 +180,7 @@ dummy := $(call unnest-vars,.., \
block-obj-m \
chardev-obj-y \
crypto-obj-y \
-   crypto-aes-obj-y \
+   crypto-user-obj-y \
qom-obj-y \
io-obj-y \
common-obj-y \
@@ -189,7 +189,7 @@ all-obj-y += $(common-obj-y)
 all-obj-y += $(qom-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(authz-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
-all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
+all-obj-$(CONFIG_USER_ONLY) += $(crypto-user-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
 
diff --git a/configure b/configure
index 571dd94ee2..54fa78c4dc 100755
--- a/configure
+++ b/configure
@@ -2792,8 +2792,7 @@ if test "$gnutls" != "no"; then
 # At least ubuntu 18.04 ships only shared libraries.
 write_c_skeleton
 if compile_prog "" "$gnutls_libs" ; then
-libs_softmmu="$gnutls_libs $libs_softmmu"
-libs_tools="$gnutls_libs $libs_tools"
+LIBS="$gnutls_libs $LIBS"
 QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
 pass="yes"
 fi
@@ -2864,8 +2863,7 @@ if test "$nettle" != "no"; then
 # Link test to make sure the given libraries work (e.g for static).
 write_c_skeleton
 if compile_prog "" "$nettle_libs" ; then
-libs_softmmu="$nettle_libs $libs_softmmu"
-libs_tools="$nettle_libs $libs_tools"
+LIBS="$nettle_libs $LIBS"
 QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
 if test -z "$gcrypt"; then
gcrypt="no"
@@ -2896,8 +2894,7 @@ if test "$gcrypt" != "no"; then
 # Link test to make sure the given libraries work (e.g for static).
 write_c_skeleton
 if compile_prog "" "$gcrypt_libs" ; then
-libs_softmmu="$gcrypt_libs $libs_softmmu"
-libs_tools="$gcrypt_libs $libs_tools"
+LIBS="$gcrypt_libs $LIBS"
 QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
 pass="yes"
 fi
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 256c9aca1f..7fe2fa9da2 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -19,9 +19,10 @@ crypto-obj-y += tlscredspsk.o
 crypto-obj-y += tlscredsx509.o
 crypto-obj-y += tlssession.o
 crypto-obj-y += secret.o
-crypto-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += 
random-platform.o
+crypto-rng-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
+crypto-rng-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
+crypto-rng-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += 
random-platform.o
+crypto-obj-y += 

[Qemu-devel] [PULL 05/25] crypto: Use O_CLOEXEC in qcrypto_random_init

2019-05-22 Thread Richard Henderson
Avoids leaking the /dev/urandom fd into any child processes.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 crypto/random-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 260b64564d..6df40744c7 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -42,9 +42,9 @@ int qcrypto_random_init(Error **errp)
 #else
 /* TBD perhaps also add support for BSD getentropy / Linux
  * getrandom syscalls directly */
-fd = open("/dev/urandom", O_RDONLY);
+fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
 if (fd == -1 && errno == ENOENT) {
-fd = open("/dev/random", O_RDONLY);
+fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
 }
 
 if (fd < 0) {
-- 
2.17.1




[Qemu-devel] [Bug 1826422] Re: Regression: QEMU 4.0 hangs the host (*bisect included*)

2019-05-22 Thread Alex Williamson
Just to provide an update, patches are posted to revert this change in
both the q35 4.1 machine type for the next release as well as introduce
a q35 4.0.1 machine type making the same change for 4.0-stable.
References:

https://patchwork.ozlabs.org/patch/1099695/
https://patchwork.ozlabs.org/patch/1099659/

** Changed in: qemu
   Status: New => In Progress

** Changed in: qemu
 Assignee: (unassigned) => Alex Williamson (alex-l-williamson)

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

Title:
  Regression: QEMU 4.0 hangs the host (*bisect included*)

Status in QEMU:
  In Progress

Bug description:
  The commit b2fc91db84470a78f8e93f5b5f913c17188792c8 seemingly
  introduced a regression on my system.

  When I start QEMU, the guest and the host hang (I need a hard reset to
  get back to a working system), before anything shows on the guest.

  I use QEMU with GPU passthrough (which worked perfectly until the
  commit above). This is the command I use:

  ```
  /path/to/qemu-system-x86_64
-drive if=pflash,format=raw,readonly,file=/path/to/OVMF_CODE.fd
-drive if=pflash,format=raw,file=/tmp/OVMF_VARS.fd.tmp
-enable-kvm
-machine q35,accel=kvm,mem-merge=off
-cpu 
host,kvm=off,hv_vendor_id=vgaptrocks,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time
-smp 4,cores=4,sockets=1,threads=1
-m 10240
-vga none
-rtc base=localtime
-serial none
-parallel none
-usb
-device usb-tablet
-device vfio-pci,host=01:00.0,multifunction=on
-device vfio-pci,host=01:00.1
-device usb-host,vendorid=,productid=
-device usb-host,vendorid=,productid=
-device usb-host,vendorid=,productid=
-device usb-host,vendorid=,productid=
-device usb-host,vendorid=,productid=
-device usb-host,vendorid=,productid=
-device virtio-scsi-pci,id=scsi
-drive file=/path/to/guest.img,id=hdd1,format=qcow2,if=none,cache=writeback
-device scsi-hd,drive=hdd1
-net nic,model=virtio
-net user,smb=/path/to/shared
  ```

  If I run QEMU without GPU passthrough, it runs fine.

  Some details about my system:

  - O/S: Mint 19.1 x86-64 (it's based on Ubuntu 18.04)
  - Kernel: 4.15
  - `configure` options: `--target-list=x86_64-softmmu --enable-gtk 
--enable-spice --audio-drv-list=pa`
  - EDK2 version: 1a734ed85fda71630c795832e6d24ea560caf739 (20/Apr/2019)
  - CPU: i7-6700k
  - Motherboard: ASRock Z170 Gaming-ITX/ac
  - VGA: Gigabyte GTX 960 Mini-ITX

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



[Qemu-devel] [PULL 18/25] hw/misc/nrf51_rng: Use qemu_guest_getrandom_nofail

2019-05-22 Thread Richard Henderson
The random number is intended for use by the guest.  As such, we should
honor the -seed argument for reproducibility.  Use the *_nofail routine
instead of error_abort directly.

Reviewed-by: Laurent Vivier 
Reviewed-by: Joel Stanley 
Signed-off-by: Richard Henderson 
---
 hw/misc/nrf51_rng.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c
index d188f044f4..3400e90a9b 100644
--- a/hw/misc/nrf51_rng.c
+++ b/hw/misc/nrf51_rng.c
@@ -14,7 +14,7 @@
 #include "qapi/error.h"
 #include "hw/arm/nrf51.h"
 #include "hw/misc/nrf51_rng.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.h"
 
 static void update_irq(NRF51RNGState *s)
 {
@@ -145,7 +145,7 @@ static void nrf51_rng_timer_expire(void *opaque)
 {
 NRF51RNGState *s = NRF51_RNG(opaque);
 
-qcrypto_random_bytes(>value, 1, _abort);
+qemu_guest_getrandom_nofail(>value, 1);
 
 s->event_valrdy = 1;
 qemu_set_irq(s->eep_valrdy, 1);
-- 
2.17.1




[Qemu-devel] [PULL 09/25] ui/vnc: Use gcrypto_random_bytes for start_auth_vnc

2019-05-22 Thread Richard Henderson
Use a better interface for random numbers than rand().
Fail gracefully if for some reason we cannot use the crypto system.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Gerd Hoffmann 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 ui/vnc.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 785edf3af1..d83f4a6ff9 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -43,6 +43,7 @@
 #include "crypto/hash.h"
 #include "crypto/tlscredsanon.h"
 #include "crypto/tlscredsx509.h"
+#include "crypto/random.h"
 #include "qom/object_interfaces.h"
 #include "qemu/cutils.h"
 #include "io/dns-resolver.h"
@@ -2547,16 +2548,6 @@ static void authentication_failed(VncState *vs)
 vnc_client_error(vs);
 }
 
-static void make_challenge(VncState *vs)
-{
-int i;
-
-srand(time(NULL)+getpid()+getpid()*987654+rand());
-
-for (i = 0 ; i < sizeof(vs->challenge) ; i++)
-vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
-}
-
 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
 {
 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
@@ -2628,7 +2619,16 @@ reject:
 
 void start_auth_vnc(VncState *vs)
 {
-make_challenge(vs);
+Error *err = NULL;
+
+if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), )) {
+trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
+error_get_pretty(err));
+error_free(err);
+authentication_failed(vs);
+return;
+}
+
 /* Send client a 'random' challenge */
 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
 vnc_flush(vs);
-- 
2.17.1




[Qemu-devel] [PULL 23/25] target/ppc: Use gen_io_start/end around DARN

2019-05-22 Thread Richard Henderson
Generating a random number counts as I/O, as it cannot be
replayed and produce the same results.

Acked-by: David Gibson 
Reviewed-by: Laurent Vivier 
Suggested-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/ppc/translate.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index b5217f632f..4a5de28036 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1847,13 +1847,22 @@ static void gen_darn(DisasContext *ctx)
 {
 int l = L(ctx->opcode);
 
-if (l == 0) {
-gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
-} else if (l <= 2) {
-/* Return 64-bit random for both CRN and RRN */
-gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
-} else {
+if (l > 2) {
 tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
+} else {
+if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+gen_io_start();
+}
+if (l == 0) {
+gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
+} else {
+/* Return 64-bit random for both CRN and RRN */
+gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
+}
+if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+gen_io_end();
+gen_stop_exception(ctx);
+}
 }
 }
 #endif
-- 
2.17.1




[Qemu-devel] [PULL 25/25] target/i386: Implement CPUID_EXT_RDRAND

2019-05-22 Thread Richard Henderson
We now have an interface for guest visible random numbers.

Reviewed-by: Eduardo Habkost 
Signed-off-by: Richard Henderson 
---
 target/i386/helper.h |  2 ++
 target/i386/cpu.c|  5 ++--
 target/i386/int_helper.c | 21 ++
 target/i386/translate.c  | 62 ++--
 4 files changed, 73 insertions(+), 17 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 6fb8fb9b74..8f9e1905c3 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -226,3 +226,5 @@ DEF_HELPER_3(rcrl, tl, env, tl, tl)
 DEF_HELPER_3(rclq, tl, env, tl, tl)
 DEF_HELPER_3(rcrq, tl, env, tl, tl)
 #endif
+
+DEF_HELPER_1(rdrand, tl, env)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 2df56fa977..357d3c43a1 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -730,13 +730,14 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t 
vendor1,
   CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
   CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
   CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */   \
-  CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
+  CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \
+  CPUID_EXT_RDRAND)
   /* missing:
   CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
   CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
   CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
   CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
-  CPUID_EXT_F16C, CPUID_EXT_RDRAND */
+  CPUID_EXT_F16C */
 
 #ifdef TARGET_X86_64
 #define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
diff --git a/target/i386/int_helper.c b/target/i386/int_helper.c
index 4dc5c65991..334469ca8c 100644
--- a/target/i386/int_helper.c
+++ b/target/i386/int_helper.c
@@ -22,6 +22,8 @@
 #include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
 
 //#define DEBUG_MULDIV
 
@@ -470,3 +472,22 @@ void helper_cr4_testbit(CPUX86State *env, uint32_t bit)
 raise_exception_ra(env, EXCP06_ILLOP, GETPC());
 }
 }
+
+target_ulong HELPER(rdrand)(CPUX86State *env)
+{
+Error *err = NULL;
+target_ulong ret;
+
+if (qemu_guest_getrandom(, sizeof(ret), ) < 0) {
+qemu_log_mask(LOG_UNIMP, "rdrand: Crypto failure: %s",
+  error_get_pretty(err));
+error_free(err);
+/* Failure clears CF and all other flags, and returns 0.  */
+env->cc_src = 0;
+return 0;
+}
+
+/* Success sets CF and clears all others.  */
+env->cc_src = CC_C;
+return ret;
+}
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 77d6b73e42..03150a86e2 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -5332,31 +5332,63 @@ static target_ulong disas_insn(DisasContext *s, 
CPUState *cpu)
 case 0x1c7: /* cmpxchg8b */
 modrm = x86_ldub_code(env, s);
 mod = (modrm >> 6) & 3;
-if ((mod == 3) || ((modrm & 0x38) != 0x8))
-goto illegal_op;
-#ifdef TARGET_X86_64
-if (dflag == MO_64) {
-if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
+switch ((modrm >> 3) & 7) {
+case 1: /* CMPXCHG8, CMPXCHG16 */
+if (mod == 3) {
 goto illegal_op;
-gen_lea_modrm(env, s, modrm);
-if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) & 
CF_PARALLEL)) {
-gen_helper_cmpxchg16b(cpu_env, s->A0);
-} else {
-gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
 }
-} else
+#ifdef TARGET_X86_64
+if (dflag == MO_64) {
+if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
+goto illegal_op;
+}
+gen_lea_modrm(env, s, modrm);
+if ((s->prefix & PREFIX_LOCK) &&
+(tb_cflags(s->base.tb) & CF_PARALLEL)) {
+gen_helper_cmpxchg16b(cpu_env, s->A0);
+} else {
+gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
+}
+set_cc_op(s, CC_OP_EFLAGS);
+break;
+}
 #endif
-{
-if (!(s->cpuid_features & CPUID_CX8))
+if (!(s->cpuid_features & CPUID_CX8)) {
 goto illegal_op;
+}
 gen_lea_modrm(env, s, modrm);
-if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) & 
CF_PARALLEL)) {
+if ((s->prefix & PREFIX_LOCK) &&
+(tb_cflags(s->base.tb) & CF_PARALLEL)) {
 gen_helper_cmpxchg8b(cpu_env, s->A0);
 } else {
 gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0);
 }
+set_cc_op(s, CC_OP_EFLAGS);
+   

[Qemu-devel] [PULL 19/25] hw/misc/bcm2835_rng: Use qemu_guest_getrandom_nofail

2019-05-22 Thread Richard Henderson
The random number is intended for use by the guest.  As such, we should
honor the -seed argument for reproducibility.  Use the *_nofail routine
instead of rolling our own error handling locally.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 hw/misc/bcm2835_rng.c | 32 ++--
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/hw/misc/bcm2835_rng.c b/hw/misc/bcm2835_rng.c
index 4d62143b24..fe59c868f5 100644
--- a/hw/misc/bcm2835_rng.c
+++ b/hw/misc/bcm2835_rng.c
@@ -9,30 +9,26 @@
 
 #include "qemu/osdep.h"
 #include "qemu/log.h"
-#include "qapi/error.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.h"
 #include "hw/misc/bcm2835_rng.h"
 
 static uint32_t get_random_bytes(void)
 {
 uint32_t res;
-Error *err = NULL;
 
-if (qcrypto_random_bytes((uint8_t *), sizeof(res), ) < 0) {
-/* On failure we don't want to return the guest a non-random
- * value in case they're really using it for cryptographic
- * purposes, so the best we can do is die here.
- * This shouldn't happen unless something's broken.
- * In theory we could implement this device's full FIFO
- * and interrupt semantics and then just stop filling the
- * FIFO. That's a lot of work, though, so we assume any
- * errors are systematic problems and trust that if we didn't
- * fail as the guest inited then we won't fail later on
- * mid-run.
- */
-error_report_err(err);
-exit(1);
-}
+/*
+ * On failure we don't want to return the guest a non-random
+ * value in case they're really using it for cryptographic
+ * purposes, so the best we can do is die here.
+ * This shouldn't happen unless something's broken.
+ * In theory we could implement this device's full FIFO
+ * and interrupt semantics and then just stop filling the
+ * FIFO. That's a lot of work, though, so we assume any
+ * errors are systematic problems and trust that if we didn't
+ * fail as the guest inited then we won't fail later on
+ * mid-run.
+ */
+qemu_guest_getrandom_nofail(, sizeof(res));
 return res;
 }
 
-- 
2.17.1




[Qemu-devel] [PULL 13/25] linux-user: Call qcrypto_init if not using -seed

2019-05-22 Thread Richard Henderson
When not using -seed, we will use the crypto subsystem
for random numbers.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/main.c | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 7e704845c0..66c909a1a6 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -39,6 +39,7 @@
 #include "trace/control.h"
 #include "target_elf.h"
 #include "cpu_loop-common.h"
+#include "crypto/init.h"
 
 char *exec_path;
 
@@ -688,17 +689,26 @@ int main(int argc, char **argv, char **envp)
 if (seed_optarg == NULL) {
 seed_optarg = getenv("QEMU_RAND_SEED");
 }
-if (seed_optarg != NULL) {
-unsigned long long seed;
+{
+Error *err = NULL;
+if (seed_optarg != NULL) {
+unsigned long long seed;
 
-/* This will go away with the last user of rand(). */
-if (parse_uint_full(seed_optarg, , 0) != 0) {
-fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
-exit(EXIT_FAILURE);
+/* This will go away with the last user of rand(). */
+if (parse_uint_full(seed_optarg, , 0) != 0) {
+fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
+exit(EXIT_FAILURE);
+}
+srand(seed);
+
+qemu_guest_random_seed_main(seed_optarg, );
+} else {
+qcrypto_init();
+}
+if (err) {
+error_reportf_err(err, "cannot initialize crypto: ");
+exit(1);
 }
-srand(seed);
-
-qemu_guest_random_seed_main(seed_optarg, _fatal);
 }
 
 target_environ = envlist_to_environ(envlist, NULL);
-- 
2.17.1




[Qemu-devel] [PATCH 3/5] linux-user: Add functionality for tracking target signal mask

2019-05-22 Thread Aleksandar Markovic
From: Miloš Stojanović 

Add two inline functions that work with the signal set of the target.

target_sigdelset() removes a signal from target_sigset_t.
target_sigorset() creates a union of two target_sigset_t.

These functions will be used for introducing support for tracking the
target signal set. Functions for emptying and adding into a target signal
set already exist so this commit will serve as a supplement.

Add functions tswapal_target_sigset(), target_to_abi_ulong_old_sigset()
and abi_ulong_to_target_old_sigset().

The tswapal_target_sigset() function transforms target signal sets
from target to host endianness. This is helpful for tracking and working
with the target signal masks in the host endianness rather then keeping
it in the target endianness.

The target_to_abi_ulong_old_sigset() and abi_ulong_to_target_old_sigset()
functions are used for translating the signal set between the old way of
storing it in abi_ulong and the new target_sigset_t structure. They can
be used for expanding old implementations of certain system calls to
include the tracking of the target signal masks.

Add support for tracking the larger target signal mask in system calls
sigprocmask()/rt_sigprocmask(), sigsuspend()/rt_sigsuspend(),
sgetmask()/ssetmask() and in functions do_sigreturn(), do_rt_sigreturn(),
handle_pending_signal(), process_pending_signals().
Add a new function do_target_sigprocmask() which is based on
do_sigprocmask() and extends its functionallity.

It can happen that the host machine has a smaller range of signals
compared to the target machine that it's emulating. Currently the signals
that are in the target range but out of the host range are treated like
faulty signals and can't be used. In this patch, support is added for
tracking the target signal mask, alongside and in the same manner as the
host signal mask.

Signed-off-by: Miloš Stojanović 
Signed-off-by: Aleksandar Markovic 
---
 linux-user/mips/signal.c   |  16 +
 linux-user/qemu.h  |   6 ++
 linux-user/signal-common.h |   5 ++
 linux-user/signal.c| 158 -
 linux-user/syscall.c   |  94 +++
 linux-user/syscall_defs.h  |   4 ++
 6 files changed, 282 insertions(+), 1 deletion(-)

diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
index 6aa303e..37922d9 100644
--- a/linux-user/mips/signal.c
+++ b/linux-user/mips/signal.c
@@ -253,6 +253,9 @@ long do_sigreturn(CPUMIPSState *regs)
 abi_ulong frame_addr;
 sigset_t blocked;
 target_sigset_t target_set;
+#ifdef TRACK_TARGET_SIGMASK
+target_sigset_t target_blocked;
+#endif
 int i;
 
 frame_addr = regs->active_tc.gpr[29];
@@ -265,7 +268,12 @@ long do_sigreturn(CPUMIPSState *regs)
 }
 
 target_to_host_sigset_internal(, _set);
+#ifdef TRACK_TARGET_SIGMASK
+tswapal_target_sigset(_blocked, _set);
+target_set_sigmask(, _blocked);
+#else
 set_sigmask();
+#endif
 
 restore_sigcontext(regs, >sf_sc);
 
@@ -358,6 +366,9 @@ long do_rt_sigreturn(CPUMIPSState *env)
 struct target_rt_sigframe *frame;
 abi_ulong frame_addr;
 sigset_t blocked;
+#ifdef TRACK_TARGET_SIGMASK
+target_sigset_t target_blocked;
+#endif
 
 frame_addr = env->active_tc.gpr[29];
 trace_user_do_rt_sigreturn(env, frame_addr);
@@ -366,7 +377,12 @@ long do_rt_sigreturn(CPUMIPSState *env)
 }
 
 target_to_host_sigset(, >rs_uc.tuc_sigmask);
+#ifdef TRACK_TARGET_SIGMASK
+tswapal_target_sigset(_blocked, >rs_uc.tuc_sigmask);
+target_set_sigmask(, _blocked);
+#else
 set_sigmask();
+#endif
 
 restore_sigcontext(env, >rs_uc.tuc_mcontext);
 
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 9f70996..75ba2a5 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -401,12 +401,18 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, 
const siginfo_t *info);
 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
 int target_to_host_signal(int sig);
 int host_to_target_signal(int sig);
+void tswapal_target_sigset(target_sigset_t *d, const target_sigset_t *s);
 long do_sigreturn(CPUArchState *env);
 long do_rt_sigreturn(CPUArchState *env);
 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
 int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
 abi_long do_swapcontext(CPUArchState *env, abi_ulong uold_ctx,
 abi_ulong unew_ctx, abi_long ctx_size);
+#ifdef TRACK_TARGET_SIGMASK
+int do_target_sigprocmask(int how, const target_sigset_t *target_set,
+  target_sigset_t *target_oldset,
+  const sigset_t *set, sigset_t *oldset);
+#endif
 /**
  * block_signals: block all signals while handling this guest syscall
  *
diff --git a/linux-user/signal-common.h b/linux-user/signal-common.h
index 51030a9..6332931 100644
--- a/linux-user/signal-common.h
+++ b/linux-user/signal-common.h
@@ -37,7 +37,12 @@ void 

[Qemu-devel] [PULL 24/25] target/ppc: Use qemu_guest_getrandom for DARN

2019-05-22 Thread Richard Henderson
We now have an interface for guest visible random numbers.

Acked-by: David Gibson 
Reviewed-by: Laurent Vivier 
Signed-off-by: Richard Henderson 
---
 target/ppc/int_helper.c | 39 +++
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index f6a088ac08..9af779ad38 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -23,6 +23,8 @@
 #include "exec/helper-proto.h"
 #include "crypto/aes.h"
 #include "fpu/softfloat.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
 
 #include "helper_regs.h"
 /*/
@@ -158,25 +160,38 @@ uint32_t helper_cmpeqb(target_ulong ra, target_ulong rb)
 #undef hasvalue
 
 /*
- * Return invalid random number.
- *
- * FIXME: Add rng backend or other mechanism to get cryptographically suitable
- * random number
+ * Return a random number.
  */
-target_ulong helper_darn32(void)
+uint64_t helper_darn32(void)
 {
-return -1;
+Error *err = NULL;
+uint32_t ret;
+
+if (qemu_guest_getrandom(, sizeof(ret), ) < 0) {
+qemu_log_mask(LOG_UNIMP, "darn: Crypto failure: %s",
+  error_get_pretty(err));
+error_free(err);
+return -1;
+}
+
+return ret;
 }
 
-target_ulong helper_darn64(void)
+uint64_t helper_darn64(void)
 {
-return -1;
+Error *err = NULL;
+uint64_t ret;
+
+if (qemu_guest_getrandom(, sizeof(ret), ) < 0) {
+qemu_log_mask(LOG_UNIMP, "darn: Crypto failure: %s",
+  error_get_pretty(err));
+error_free(err);
+return -1;
+}
+
+return ret;
 }
 
-#endif
-
-#if defined(TARGET_PPC64)
-
 uint64_t helper_bpermd(uint64_t rs, uint64_t rb)
 {
 int i;
-- 
2.17.1




[Qemu-devel] [PULL 14/25] linux-user: Use qemu_guest_getrandom_nofail for AT_RANDOM

2019-05-22 Thread Richard Henderson
Use a better interface for random numbers than rand * 16.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/elfload.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ef42e02d82..1e06b908b7 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -7,6 +7,7 @@
 #include "qemu.h"
 #include "disas/disas.h"
 #include "qemu/path.h"
+#include "qemu/guest-random.h"
 
 #ifdef _ARCH_PPC64
 #undef ARCH_DLINFO
@@ -1883,12 +1884,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int 
argc, int envc,
 }
 
 /*
- * Generate 16 random bytes for userspace PRNG seeding (not
- * cryptically secure but it's not the aim of QEMU).
+ * Generate 16 random bytes for userspace PRNG seeding.
  */
-for (i = 0; i < 16; i++) {
-k_rand_bytes[i] = rand();
-}
+qemu_guest_getrandom_nofail(k_rand_bytes, sizeof(k_rand_bytes));
 if (STACK_GROWS_DOWN) {
 sp -= 16;
 u_rand_bytes = sp;
-- 
2.17.1




Re: [Qemu-devel] [PATCH v1 1/5] s390x/tcg: Implement VECTOR FIND ANY ELEMENT EQUAL

2019-05-22 Thread Richard Henderson
On 5/22/19 2:16 PM, David Hildenbrand wrote:
> On 22.05.19 17:59, Richard Henderson wrote:
>> On Wed, 22 May 2019 at 07:16, David Hildenbrand  wrote:
 Also plausible.  I guess it would be good to know, anyway.
>>>
>>> I'll dump the parameters when booting Linux. My gut feeling is that the
>>> cc option is basically never used ...
>>
>> It looks like our intuition is wrong about that.
> 
> Thanks for checking!
> 
>>
>> rth@cloudburst:~/glibc/src/sysdeps/s390$ grep -r vfaezbs * | wc -l
>> 15
>>
>> These set cc, use zs, and do not use rt.
>>
>> rth@cloudburst:~/glibc/src/sysdeps/s390$ grep -r 'vfaeb' * | wc -l
>> 3
>>
>> These do not set cc, do not use zs, and do use rt.
>>
>> Those are the only two VFAE forms used by glibc (note that the same
>> variants as 'f' are used by the wide-character strings).
>>
> 
> I guess "rt" and "cc" make the biggest difference. Maybe special case
> these two, result in 4 variants for each of the 3 element sizes?

Sounds good.


r~




[Qemu-devel] [PATCH 1/5] linux-user: Fix sigismember() check

2019-05-22 Thread Aleksandar Markovic
From: Miloš Stojanović 

Fix copying between the host and target signal sets for the case when
the target set is larger than the host set.

sigismember() returns 1 if the specified signal number is a member of
the specified signal set, but it can also return -1 if an error occurs
(e.g. an out of range signal number is specified). All non-zero values
would cause the signal to be added, so a comparison with 1 is added to
assure that only the signals which are really in the set get added to
the other set.

Signed-off-by: Miloš Stojanović 
Signed-off-by: Aleksandar Markovic 
---
 linux-user/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 44b2d3b..c08a7fe 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -116,7 +116,7 @@ void host_to_target_sigset_internal(target_sigset_t *d,
 int i;
 target_sigemptyset(d);
 for (i = 1; i <= TARGET_NSIG; i++) {
-if (sigismember(s, i)) {
+if (sigismember(s, i) == 1) {
 target_sigaddset(d, host_to_target_signal(i));
 }
 }
-- 
2.7.4




[Qemu-devel] [PATCH 4/5] linux-user: Add support for multiplexing larger target signals

2019-05-22 Thread Aleksandar Markovic
From: Miloš Stojanović 

Add MUX_SIG as a multiplex signal number for all target signals which are
out of the host range. Add support for multiplexing in do_sigaction(),
process_pending_signals(), target_set_sigmask() and do_target_sigprocmask().

This patch solves the problem of unusable target signals which are out of
the host range. This is done by enabling the usage of one of the host
signals (MUX_SIG) as a multiplex for all the target signals that are out
of range. In order to have the target signal masks available
TRACK_TARGET_MASK is defined which enables the tracking of the target
signals masks.

The table of signal handlers already supports the whole range of target
signals. In the do_sigaction() function the signal number of signals which
are out of range are replaced by MUX_SIG which bypasses the error from the
host system and doesn't interfere with signal handling on the target.
Since the MUX_SIG is used as a multiplex, it must never be blocked on host,
so support for emulating the blocking of this signal is added. This is done
by only blocking MUX_SIG in the target mask and retrieving its status from
there when it's needed.

Signed-off-by: Miloš Stojanović 
Signed-off-by: Aleksandar Markovic 
---
 linux-user/signal.c   | 32 
 linux-user/syscall_defs.h | 20 
 2 files changed, 52 insertions(+)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9a73bfa..601de3e 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -291,6 +291,15 @@ int do_target_sigprocmask(int how, const target_sigset_t 
*target_set,
 }
 if (oldset) {
 *oldset = ts->signal_mask;
+#ifdef MUX_SIG
+/*
+ * The emulation of MUX_SIG being blocked is done using the
+ * target_signal_mask, so the status of MUX_SIG is taken from there.
+ */
+if (target_sigismember(>target_signal_mask, MUX_SIG) == 1) {
+sigaddset(oldset, MUX_SIG);
+}
+#endif
 }
 
 if (target_set && set) {
@@ -331,6 +340,15 @@ int do_target_sigprocmask(int how, const target_sigset_t 
*target_set,
 target_sigdelset(>target_signal_mask, SIGSTOP);
 sigdelset(>signal_mask, SIGKILL);
 sigdelset(>signal_mask, SIGSTOP);
+#ifdef MUX_SIG
+/*
+ * Since MUX_SIG is used for all the target signals out of the host
+ * range it must never be blocked on host. The emulation of MUX_SIG
+ * being blocked is done using the target_signal_mask. The status
+ * of MUX_SIG is taken form the target_signal_mask.
+ */
+sigdelset(>signal_mask, MUX_SIG);
+#endif
 }
 return 0;
 }
@@ -355,6 +373,10 @@ void target_set_sigmask(const sigset_t *set,
 
 ts->signal_mask = *set;
 ts->target_signal_mask = *target_set;
+#ifdef MUX_SIG
+/* MUX_SIG can't be blocked on host */
+sigdelset(>signal_mask, MUX_SIG);
+#endif
 }
 #endif
 #endif
@@ -929,6 +951,12 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 
 /* we update the host linux signal state */
 host_sig = target_to_host_signal(sig);
+#ifdef MUX_SIG
+/* put the out of host range signal into the multiplex */
+if (sig >= _NSIG && sig < TARGET_NSIG) {
+host_sig = MUX_SIG;
+}
+#endif
 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
 sigfillset(_mask);
 act1.sa_flags = SA_SIGINFO;
@@ -1141,6 +1169,10 @@ void process_pending_signals(CPUArchState *cpu_env)
 set = ts->signal_mask;
 sigdelset(, SIGSEGV);
 sigdelset(, SIGBUS);
+#ifdef MUX_SIG
+/* MUX_SIG can't be blocked on host */
+sigdelset(>signal_mask, MUX_SIG);
+#endif
 sigprocmask(SIG_SETMASK, , 0);
 }
 ts->in_sigsuspend = 0;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 64edec2..0c72509 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -387,6 +387,26 @@ struct target_dirent64 {
 #define TARGET_NSIG_BPW   TARGET_ABI_BITS
 #define TARGET_NSIG_WORDS  (TARGET_NSIG / TARGET_NSIG_BPW)
 
+#if _NSIG <= TARGET_NSIG
+/*
+ * MUX_SIG is used as a multiplex signal number - signals that are
+ * out of the host range and in the target range are sent through it.
+ * It is defined as the maximal available real-time signal in order to
+ * comply with the rule that low-numbered signals have highest priority.
+ * (signals using it will have the same priority but it will be smaller
+ * than all the other real-time signals)
+ * SIGRMTAX is avoided so it doesn't interfere with the hack of reversing
+ * __SIGRTMIN and __SIGRTMAX in the host_to_target_signal_table.
+ */
+#define MUX_SIG (SIGRTMAX - 1)
+
+/*
+ * The target signal masks must be tracked since they are larger than
+ * the host signal masks.
+ */
+#define TRACK_TARGET_SIGMASK
+#endif
+
 typedef struct {
 abi_ulong sig[TARGET_NSIG_WORDS];
 } target_sigset_t;
-- 
2.7.4




  1   2   3   4   >