[PATCH for-6.0 9/9] spapr: spapr_drc_attach() cannot fail

2020-11-20 Thread Greg Kurz
All users are passing _abort already. Document the fact
that spapr_drc_attach() should only be passed a free DRC, which
is supposedly the case if appropriate checking is done earlier.

Signed-off-by: Greg Kurz 
---
 include/hw/ppc/spapr_drc.h | 8 +++-
 hw/ppc/spapr.c | 6 +++---
 hw/ppc/spapr_drc.c | 8 ++--
 hw/ppc/spapr_nvdimm.c  | 2 +-
 hw/ppc/spapr_pci.c | 2 +-
 5 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index 165b281496bb..def3593adc8b 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -235,7 +235,13 @@ SpaprDrc *spapr_drc_by_index(uint32_t index);
 SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id);
 int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask);
 
-bool spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error **errp);
+/*
+ * These functions respectively abort if called with a device already
+ * attached or no device attached. In the case of spapr_drc_attach(),
+ * this means that the attachability of the DRC *must* be checked
+ * beforehand (eg. check drc->dev at pre-plug).
+ */
+void spapr_drc_attach(SpaprDrc *drc, DeviceState *d);
 void spapr_drc_detach(SpaprDrc *drc);
 
 /* Returns true if a hot plug/unplug request is pending */
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 5e32d1d396b4..e0047f41073e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3399,7 +3399,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t 
addr_start, uint64_t size,
  * that doesn't overlap with any existing mapping at pre-plug. The
  * corresponding LMB DRCs are thus assumed to be all attachable.
  */
-spapr_drc_attach(drc, dev, _abort);
+spapr_drc_attach(drc, dev);
 if (!hotplugged) {
 spapr_drc_reset(drc);
 }
@@ -3767,7 +3767,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, 
DeviceState *dev)
  * core being plugged into a free slot. Nothing should already
  * be attached to the corresponding DRC.
  */
-spapr_drc_attach(drc, dev, _abort);
+spapr_drc_attach(drc, dev);
 
 if (hotplugged) {
 /*
@@ -3920,7 +3920,7 @@ static void spapr_phb_plug(HotplugHandler *hotplug_dev, 
DeviceState *dev)
 assert(drc);
 
 /* spapr_phb_pre_plug() already checked the DRC is attachable */
-spapr_drc_attach(drc, dev, _abort);
+spapr_drc_attach(drc, dev);
 
 if (hotplugged) {
 spapr_hotplug_req_add_by_index(drc);
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 77718cde1ff2..f991cf89a08a 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -369,14 +369,11 @@ static void prop_get_fdt(Object *obj, Visitor *v, const 
char *name,
 } while (fdt_depth != 0);
 }
 
-bool spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error **errp)
+void spapr_drc_attach(SpaprDrc *drc, DeviceState *d)
 {
 trace_spapr_drc_attach(spapr_drc_index(drc));
 
-if (drc->dev) {
-error_setg(errp, "an attached device is still awaiting release");
-return false;
-}
+g_assert(!drc->dev);
 g_assert((drc->state == SPAPR_DRC_STATE_LOGICAL_UNUSABLE)
  || (drc->state == SPAPR_DRC_STATE_PHYSICAL_POWERON));
 
@@ -386,7 +383,6 @@ bool spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error 
**errp)
  object_get_typename(OBJECT(drc->dev)),
  (Object **)(>dev),
  NULL, 0);
-return true;
 }
 
 static void spapr_drc_release(SpaprDrc *drc)
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index 2f1c196e1b76..73ee006541a6 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -101,7 +101,7 @@ void spapr_add_nvdimm(DeviceState *dev, uint64_t slot)
  * pc_dimm_get_free_slot() provided a free slot at pre-plug. The
  * corresponding DRC is thus assumed to be attachable.
  */
-spapr_drc_attach(drc, dev, _abort);
+spapr_drc_attach(drc, dev);
 
 if (hotplugged) {
 spapr_hotplug_req_add_by_index(drc);
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 2829f298d9c1..e946bd5055cc 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1601,7 +1601,7 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
 }
 
 /* spapr_pci_pre_plug() already checked the DRC is attachable */
-spapr_drc_attach(drc, DEVICE(pdev), _abort);
+spapr_drc_attach(drc, DEVICE(pdev));
 
 /* If this is function 0, signal hotplug for all the device functions.
  * Otherwise defer sending the hotplug event.
-- 
2.26.2




[PATCH for-6.0 4/9] spapr: Set compat mode in spapr_reset_vcpu()

2020-11-20 Thread Greg Kurz
When it comes to resetting the compat mode of the vCPUS, there are
two situations to consider:
(1) machine reset should set the compat mode back to the machine default,
ie. spapr->max_compat_pvr
(2) hot plugged vCPUs should set their compat mode to mach the boot vCPU,
ie. POWERPC_CPU(first_cpu)->compat_pvr

This is currently handled in two separate places: globally for all vCPUs
from the machine reset code for (1) and for each thread of a core from
the hotplug path for (2).

Since the machine reset code already resets all vCPUs, starting with boot
vCPU, consolidate the logic in spapr_reset_vcpu(). Special case the boot
vCPU so that it resets its compat mode back to the machine default. Any
other vCPU just need to match the compat mode of the boot vCPU.

Failing to set the compat mode during machine reset is a fatal error,
but not for hot plugged vCPUs. This is arguable because if we've been
able to set the boot vCPU compat mode at CAS or during machine reset,
it should definitely not fail for other vCPUs. Since spapr_reset_vcpu()
already has a fatal error path for kvm_check_mmu() failures, do the
same for ppc_set_compat().

This gets rid of an error path in spapr_core_plug(). It will allow
further simplifications.

Signed-off-by: Greg Kurz 
---
 hw/ppc/spapr.c  | 16 
 hw/ppc/spapr_cpu_core.c | 13 +
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f58f77389e8e..da7586f548df 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1606,8 +1606,6 @@ static void spapr_machine_reset(MachineState *machine)
 spapr_ovec_cleanup(spapr->ov5_cas);
 spapr->ov5_cas = spapr_ovec_new();
 
-ppc_set_compat_all(spapr->max_compat_pvr, _fatal);
-
 /*
  * This is fixing some of the default configuration of the XIVE
  * devices. To be called after the reset of the machine devices.
@@ -3785,20 +3783,6 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, 
DeviceState *dev,
 
 core_slot->cpu = OBJECT(dev);
 
-/*
- * Set compatibility mode to match the boot CPU, which was either set
- * by the machine reset code or by CAS.
- */
-if (hotplugged) {
-for (i = 0; i < cc->nr_threads; i++) {
-if (ppc_set_compat(core->threads[i],
-   POWERPC_CPU(first_cpu)->compat_pvr,
-   errp) < 0) {
-return;
-}
-}
-}
-
 if (smc->pre_2_10_has_unused_icps) {
 for (i = 0; i < cc->nr_threads; i++) {
 cs = CPU(core->threads[i]);
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 2f7dc3c23ded..17741a3fb77f 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -27,6 +27,7 @@
 
 static void spapr_reset_vcpu(PowerPCCPU *cpu)
 {
+PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
@@ -69,6 +70,18 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
 kvm_check_mmu(cpu, _fatal);
 
 spapr_irq_cpu_intc_reset(spapr, cpu);
+
+/*
+ * The boot CPU is only reset during machine reset : reset its
+ * compatibility mode to the machine default. For other CPUs,
+ * either cold plugged or hot plugged, set the compatibility mode
+ * to match the boot CPU, which was either set by the machine reset
+ * code or by CAS.
+ */
+ppc_set_compat(cpu,
+   cpu == first_ppc_cpu ?
+   spapr->max_compat_pvr : first_ppc_cpu->compat_pvr,
+   _fatal);
 }
 
 void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip,
-- 
2.26.2




[PATCH for-6.0 8/9] spapr: Do TPM proxy hotplug sanity checks at pre-plug

2020-11-20 Thread Greg Kurz
There can be only one TPM proxy at a time. This is currently
checked at plug time. But this can be detected at pre-plug in
order to error out earlier.

This allows to get rid of error handling in the plug handler.

Signed-off-by: Greg Kurz 
---
 hw/ppc/spapr.c | 23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index bded059d59c8..5e32d1d396b4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3957,17 +3957,28 @@ static void spapr_phb_unplug_request(HotplugHandler 
*hotplug_dev,
 }
 }
 
-static void spapr_tpm_proxy_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
- Error **errp)
+static
+bool spapr_tpm_proxy_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+  Error **errp)
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
-SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(dev);
 
 if (spapr->tpm_proxy != NULL) {
 error_setg(errp, "Only one TPM proxy can be specified for this 
machine");
-return;
+return false;
 }
 
+return true;
+}
+
+static void spapr_tpm_proxy_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
+{
+SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(dev);
+
+/* Already checked in spapr_tpm_proxy_pre_plug() */
+g_assert(spapr->tpm_proxy == NULL);
+
 spapr->tpm_proxy = tpm_proxy;
 }
 
@@ -3990,7 +4001,7 @@ static void spapr_machine_device_plug(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
 spapr_phb_plug(hotplug_dev, dev);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
-spapr_tpm_proxy_plug(hotplug_dev, dev, errp);
+spapr_tpm_proxy_plug(hotplug_dev, dev);
 }
 }
 
@@ -4053,6 +4064,8 @@ static void spapr_machine_device_pre_plug(HotplugHandler 
*hotplug_dev,
 spapr_core_pre_plug(hotplug_dev, dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
 spapr_phb_pre_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
+spapr_tpm_proxy_pre_plug(hotplug_dev, dev, errp);
 }
 }
 
-- 
2.26.2




[PATCH for-6.0 3/9] spapr: Fix pre-2.10 dummy ICP hack

2020-11-20 Thread Greg Kurz
This hack registers dummy VMState entries of ICPs in order to
support migration of old pseries machine types that used to
create all smp.max_cpus possible ICPs at machine init.

Part of the work is to unregister the dummy entries when plugging
an actual vCPU core, and to register them back when unplugging the
core. The code that unregisters the dummy ICPs in spapr_core_plug()
is misplaced: if ppc_set_compat() fails afterwards, the hotplug
operation will be cancelled and the dummy ICPs won't be registered
back since the unplug handler isn't called.

Unregister the dummy ICPs at the end of spapr_core_plug().

Signed-off-by: Greg Kurz 
---

The next patch makes this patch a bit useless. I post it
anyway for the records because it is a programming error.
---
 hw/ppc/spapr.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 394d28d9e081..f58f77389e8e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3785,13 +3785,6 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, 
DeviceState *dev,
 
 core_slot->cpu = OBJECT(dev);
 
-if (smc->pre_2_10_has_unused_icps) {
-for (i = 0; i < cc->nr_threads; i++) {
-cs = CPU(core->threads[i]);
-pre_2_10_vmstate_unregister_dummy_icp(cs->cpu_index);
-}
-}
-
 /*
  * Set compatibility mode to match the boot CPU, which was either set
  * by the machine reset code or by CAS.
@@ -3805,6 +3798,13 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, 
DeviceState *dev,
 }
 }
 }
+
+if (smc->pre_2_10_has_unused_icps) {
+for (i = 0; i < cc->nr_threads; i++) {
+cs = CPU(core->threads[i]);
+pre_2_10_vmstate_unregister_dummy_icp(cs->cpu_index);
+}
+}
 }
 
 static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
-- 
2.26.2




[PATCH for-6.0 7/9] spapr: Do PHB hoplug sanity check at pre-plug

2020-11-20 Thread Greg Kurz
We currently detect that a PHB index is already in use at plug time.
But this can be decteted at pre-plug in order to error out earlier.

This allows to pass _abort to spapr_drc_attach() and to end
up with a plug handler that doesn't need to report errors anymore.

Signed-off-by: Greg Kurz 
---
 hw/ppc/spapr.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 81bac59887ab..bded059d59c8 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3872,6 +3872,7 @@ static bool spapr_phb_pre_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(dev);
 SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
 const unsigned windows_supported = spapr_phb_windows_supported(sphb);
+SpaprDrc *drc;
 
 if (dev->hotplugged && !smc->dr_phb_enabled) {
 error_setg(errp, "PHB hotplug not supported for this machine");
@@ -3883,6 +3884,12 @@ static bool spapr_phb_pre_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 return false;
 }
 
+drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PHB, sphb->index);
+if (drc && drc->dev) {
+error_setg(errp, "PHB %d already attached", sphb->index);
+return false;
+}
+
 /*
  * This will check that sphb->index doesn't exceed the maximum number of
  * PHBs for the current machine type.
@@ -3896,8 +3903,7 @@ static bool spapr_phb_pre_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
errp);
 }
 
-static void spapr_phb_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
-   Error **errp)
+static void spapr_phb_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
 SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
@@ -3913,9 +3919,8 @@ static void spapr_phb_plug(HotplugHandler *hotplug_dev, 
DeviceState *dev,
 /* hotplug hooks should check it's enabled before getting this far */
 assert(drc);
 
-if (!spapr_drc_attach(drc, dev, errp)) {
-return;
-}
+/* spapr_phb_pre_plug() already checked the DRC is attachable */
+spapr_drc_attach(drc, dev, _abort);
 
 if (hotplugged) {
 spapr_hotplug_req_add_by_index(drc);
@@ -3983,7 +3988,7 @@ static void spapr_machine_device_plug(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
 spapr_core_plug(hotplug_dev, dev);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
-spapr_phb_plug(hotplug_dev, dev, errp);
+spapr_phb_plug(hotplug_dev, dev);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
 spapr_tpm_proxy_plug(hotplug_dev, dev, errp);
 }
-- 
2.26.2




[PATCH for-6.0 1/9] spapr: Do PCI device hotplug sanity checks at pre-plug only

2020-11-20 Thread Greg Kurz
The PHB acts as the hotplug handler for PCI devices. It does some
sanity checks on DR enablement, PCI bridge chassis numbers and
multifunction. These checks are currently performed at plug time,
but they would best sit in a pre-plug handler in order to error
out as early as possible.

Create a spapr_pci_pre_plug() handler and move all the checking
there. Add a check that the associated DRC doesn't already have
an attached device. This is equivalent to the slot availability
check performed by do_pci_register_device() upon realization of
the PCI device.

This allows to pass _abort to spapr_drc_attach() and to end
up with a plug handler that doesn't need to report errors anymore.

Signed-off-by: Greg Kurz 
---
 hw/ppc/spapr_pci.c | 43 +--
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 88ce87f130a5..2829f298d9c1 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1532,8 +1532,8 @@ static bool bridge_has_valid_chassis_nr(Object *bridge, 
Error **errp)
 return true;
 }
 
-static void spapr_pci_plug(HotplugHandler *plug_handler,
-   DeviceState *plugged_dev, Error **errp)
+static void spapr_pci_pre_plug(HotplugHandler *plug_handler,
+   DeviceState *plugged_dev, Error **errp)
 {
 SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
 PCIDevice *pdev = PCI_DEVICE(plugged_dev);
@@ -1542,9 +1542,6 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
 PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
 uint32_t slotnr = PCI_SLOT(pdev->devfn);
 
-/* if DR is disabled we don't need to do anything in the case of
- * hotplug or coldplug callbacks
- */
 if (!phb->dr_enabled) {
 /* if this is a hotplug operation initiated by the user
  * we need to let them know it's not enabled
@@ -1552,17 +1549,14 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
 if (plugged_dev->hotplugged) {
 error_setg(errp, QERR_BUS_NO_HOTPLUG,
object_get_typename(OBJECT(phb)));
+return;
 }
-return;
 }
 
-g_assert(drc);
-
 if (pc->is_bridge) {
 if (!bridge_has_valid_chassis_nr(OBJECT(plugged_dev), errp)) {
 return;
 }
-spapr_pci_bridge_plug(phb, PCI_BRIDGE(plugged_dev));
 }
 
 /* Following the QEMU convention used for PCIe multifunction
@@ -1574,13 +1568,41 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
 error_setg(errp, "PCI: slot %d function 0 already occupied by %s,"
" additional functions can no longer be exposed to guest.",
slotnr, bus->devices[PCI_DEVFN(slotnr, 0)]->name);
+}
+
+if (drc && drc->dev) {
+error_setg(errp, "PCI: slot %d already occupied by %s", slotnr,
+   pci_get_function_0(PCI_DEVICE(drc->dev))->name);
 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);
+uint32_t slotnr = PCI_SLOT(pdev->devfn);
 
-if (!spapr_drc_attach(drc, DEVICE(pdev), errp)) {
+/*
+ * If DR is disabled we don't need to do anything in the case of
+ * hotplug or coldplug callbacks.
+ */
+if (!phb->dr_enabled) {
 return;
 }
 
+g_assert(drc);
+
+if (pc->is_bridge) {
+spapr_pci_bridge_plug(phb, PCI_BRIDGE(plugged_dev));
+}
+
+/* spapr_pci_pre_plug() already checked the DRC is attachable */
+spapr_drc_attach(drc, DEVICE(pdev), _abort);
+
 /* If this is function 0, signal hotplug for all the device functions.
  * Otherwise defer sending the hotplug event.
  */
@@ -2223,6 +2245,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void 
*data)
 /* Supported by TYPE_SPAPR_MACHINE */
 dc->user_creatable = true;
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+hp->pre_plug = spapr_pci_pre_plug;
 hp->plug = spapr_pci_plug;
 hp->unplug = spapr_pci_unplug;
 hp->unplug_request = spapr_pci_unplug_request;
-- 
2.26.2




[PATCH for-6.0 5/9] spapr: Simplify error path of spapr_core_plug()

2020-11-20 Thread Greg Kurz
spapr_core_pre_plug() already guarantees that the slot for the given core
ID is available. It is thus safe to assume that spapr_find_cpu_slot()
returns a slot during plug. Turn the error path into an assertion.
It is also safe to assume that no device is attached to the corresponding
DRC and that spapr_drc_attach() shouldn't fail.

Pass _abort to spapr_drc_attach() and simplify error handling.

Signed-off-by: Greg Kurz 
---
 hw/ppc/spapr.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index da7586f548df..cfca033c7b14 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3739,8 +3739,7 @@ int spapr_core_dt_populate(SpaprDrc *drc, 
SpaprMachineState *spapr,
 return 0;
 }
 
-static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
-Error **errp)
+static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
 MachineClass *mc = MACHINE_GET_CLASS(spapr);
@@ -3755,20 +3754,20 @@ static void spapr_core_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 int i;
 
 core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, );
-if (!core_slot) {
-error_setg(errp, "Unable to find CPU core with core-id: %d",
-   cc->core_id);
-return;
-}
+g_assert(core_slot); /* Already checked in spapr_core_pre_plug() */
+
 drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU,
   spapr_vcpu_id(spapr, cc->core_id));
 
 g_assert(drc || !mc->has_hotpluggable_cpus);
 
 if (drc) {
-if (!spapr_drc_attach(drc, dev, errp)) {
-return;
-}
+/*
+ * spapr_core_pre_plug() already buys us this is a brand new
+ * core being plugged into a free slot. Nothing should already
+ * be attached to the corresponding DRC.
+ */
+spapr_drc_attach(drc, dev, _abort);
 
 if (hotplugged) {
 /*
@@ -3981,7 +3980,7 @@ static void spapr_machine_device_plug(HotplugHandler 
*hotplug_dev,
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 spapr_memory_plug(hotplug_dev, dev);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
-spapr_core_plug(hotplug_dev, dev, errp);
+spapr_core_plug(hotplug_dev, dev);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
 spapr_phb_plug(hotplug_dev, dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) {
-- 
2.26.2




[PATCH for-6.0 2/9] spapr: Do NVDIMM/PC-DIMM device hotplug sanity checks at pre-plug only

2020-11-20 Thread Greg Kurz
Pre-plug of a memory device, be it an NVDIMM or a PC-DIMM, ensures
that the memory slot is available and that addresses don't overlap
with existing memory regions. The corresponding DRCs in the LMB
and PMEM namespaces are thus necessarily attachable at plug time.

Pass _abort to spapr_drc_attach() in spapr_add_lmbs() and
spapr_add_nvdimm(). This allows to greatly simplify error handling
on the plug path.

Signed-off-by: Greg Kurz 
---
 include/hw/ppc/spapr_nvdimm.h |  2 +-
 hw/ppc/spapr.c| 40 ---
 hw/ppc/spapr_nvdimm.c | 11 +-
 3 files changed, 20 insertions(+), 33 deletions(-)

diff --git a/include/hw/ppc/spapr_nvdimm.h b/include/hw/ppc/spapr_nvdimm.h
index 344582d2f5f7..73be250e2ac9 100644
--- a/include/hw/ppc/spapr_nvdimm.h
+++ b/include/hw/ppc/spapr_nvdimm.h
@@ -30,6 +30,6 @@ int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState 
*spapr,
 void spapr_dt_persistent_memory(SpaprMachineState *spapr, void *fdt);
 bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
uint64_t size, Error **errp);
-bool spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp);
+void spapr_add_nvdimm(DeviceState *dev, uint64_t slot);
 
 #endif
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 12a012d9dd09..394d28d9e081 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3382,8 +3382,8 @@ int spapr_lmb_dt_populate(SpaprDrc *drc, 
SpaprMachineState *spapr,
 return 0;
 }
 
-static bool spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t 
size,
-   bool dedicated_hp_event_source, Error **errp)
+static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t 
size,
+   bool dedicated_hp_event_source)
 {
 SpaprDrc *drc;
 uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE;
@@ -3396,15 +3396,12 @@ static bool spapr_add_lmbs(DeviceState *dev, uint64_t 
addr_start, uint64_t size,
   addr / SPAPR_MEMORY_BLOCK_SIZE);
 g_assert(drc);
 
-if (!spapr_drc_attach(drc, dev, errp)) {
-while (addr > addr_start) {
-addr -= SPAPR_MEMORY_BLOCK_SIZE;
-drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
-  addr / SPAPR_MEMORY_BLOCK_SIZE);
-spapr_drc_detach(drc);
-}
-return false;
-}
+/*
+ * memory_device_get_free_addr() provided a range of free addresses
+ * that doesn't overlap with any existing mapping at pre-plug. The
+ * corresponding LMB DRCs are thus assumed to be all attachable.
+ */
+spapr_drc_attach(drc, dev, _abort);
 if (!hotplugged) {
 spapr_drc_reset(drc);
 }
@@ -3425,11 +3422,9 @@ static bool spapr_add_lmbs(DeviceState *dev, uint64_t 
addr_start, uint64_t size,
nr_lmbs);
 }
 }
-return true;
 }
 
-static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
-  Error **errp)
+static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
 {
 SpaprMachineState *ms = SPAPR_MACHINE(hotplug_dev);
 PCDIMMDevice *dimm = PC_DIMM(dev);
@@ -3444,24 +3439,15 @@ static void spapr_memory_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 if (!is_nvdimm) {
 addr = object_property_get_uint(OBJECT(dimm),
 PC_DIMM_ADDR_PROP, _abort);
-if (!spapr_add_lmbs(dev, addr, size,
-spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT), errp)) {
-goto out_unplug;
-}
+spapr_add_lmbs(dev, addr, size,
+   spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT));
 } else {
 slot = object_property_get_int(OBJECT(dimm),
PC_DIMM_SLOT_PROP, _abort);
 /* We should have valid slot number at this point */
 g_assert(slot >= 0);
-if (!spapr_add_nvdimm(dev, slot, errp)) {
-goto out_unplug;
-}
+spapr_add_nvdimm(dev, slot);
 }
-
-return;
-
-out_unplug:
-pc_dimm_unplug(dimm, MACHINE(ms));
 }
 
 static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState 
*dev,
@@ -4009,7 +3995,7 @@ static void spapr_machine_device_plug(HotplugHandler 
*hotplug_dev,
   DeviceState *dev, Error **errp)
 {
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
-spapr_memory_plug(hotplug_dev, dev, errp);
+spapr_memory_plug(hotplug_dev, dev);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
 spapr_core_plug(hotplug_dev, dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index a833a63b5ed3..2f1c196e1b76 100644
--- 

[PATCH for-6.0 6/9] spapr: Make PHB placement functions and spapr_pre_plug_phb() return status

2020-11-20 Thread Greg Kurz
Read documentation in "qapi/error.h" and changelog of commit
e3fe3988d785 ("error: Document Error API usage rules") for
rationale.

Signed-off-by: Greg Kurz 
---
 include/hw/ppc/spapr.h |  2 +-
 hw/ppc/spapr.c | 40 +++-
 2 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 2e89e36cfbdc..b7ced9faebf5 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -140,7 +140,7 @@ struct SpaprMachineClass {
 bool pre_5_1_assoc_refpoints;
 bool pre_5_2_numa_associativity;
 
-void (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
+bool (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
   uint64_t *buid, hwaddr *pio, 
   hwaddr *mmio32, hwaddr *mmio64,
   unsigned n_dma, uint32_t *liobns, hwaddr *nv2gpa,
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index cfca033c7b14..81bac59887ab 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3865,7 +3865,7 @@ int spapr_phb_dt_populate(SpaprDrc *drc, 
SpaprMachineState *spapr,
 return 0;
 }
 
-static void spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+static bool spapr_phb_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
 {
 SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
@@ -3875,24 +3875,25 @@ static void spapr_phb_pre_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 
 if (dev->hotplugged && !smc->dr_phb_enabled) {
 error_setg(errp, "PHB hotplug not supported for this machine");
-return;
+return false;
 }
 
 if (sphb->index == (uint32_t)-1) {
 error_setg(errp, "\"index\" for PAPR PHB is mandatory");
-return;
+return false;
 }
 
 /*
  * This will check that sphb->index doesn't exceed the maximum number of
  * PHBs for the current machine type.
  */
-smc->phb_placement(spapr, sphb->index,
-   >buid, >io_win_addr,
-   >mem_win_addr, >mem64_win_addr,
-   windows_supported, sphb->dma_liobn,
-   >nv2_gpa_win_addr, >nv2_atsd_win_addr,
-   errp);
+return
+smc->phb_placement(spapr, sphb->index,
+   >buid, >io_win_addr,
+   >mem_win_addr, >mem64_win_addr,
+   windows_supported, sphb->dma_liobn,
+   >nv2_gpa_win_addr, >nv2_atsd_win_addr,
+   errp);
 }
 
 static void spapr_phb_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
@@ -4130,7 +4131,7 @@ static const CPUArchIdList 
*spapr_possible_cpu_arch_ids(MachineState *machine)
 return machine->possible_cpus;
 }
 
-static void spapr_phb_placement(SpaprMachineState *spapr, uint32_t index,
+static bool spapr_phb_placement(SpaprMachineState *spapr, uint32_t index,
 uint64_t *buid, hwaddr *pio,
 hwaddr *mmio32, hwaddr *mmio64,
 unsigned n_dma, uint32_t *liobns,
@@ -4168,7 +4169,7 @@ static void spapr_phb_placement(SpaprMachineState *spapr, 
uint32_t index,
 if (index >= SPAPR_MAX_PHBS) {
 error_setg(errp, "\"index\" for PAPR PHB is too large (max %llu)",
SPAPR_MAX_PHBS - 1);
-return;
+return false;
 }
 
 *buid = base_buid + index;
@@ -4182,6 +4183,7 @@ static void spapr_phb_placement(SpaprMachineState *spapr, 
uint32_t index,
 
 *nv2gpa = SPAPR_PCI_NV2RAM64_WIN_BASE + index * 
SPAPR_PCI_NV2RAM64_WIN_SIZE;
 *nv2atsd = SPAPR_PCI_NV2ATSD_WIN_BASE + index * SPAPR_PCI_NV2ATSD_WIN_SIZE;
+return true;
 }
 
 static ICSState *spapr_ics_get(XICSFabric *dev, int irq)
@@ -4561,18 +4563,21 @@ DEFINE_SPAPR_MACHINE(4_1, "4.1", false);
 /*
  * pseries-4.0
  */
-static void phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
+static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
   uint64_t *buid, hwaddr *pio,
   hwaddr *mmio32, hwaddr *mmio64,
   unsigned n_dma, uint32_t *liobns,
   hwaddr *nv2gpa, hwaddr *nv2atsd, Error **errp)
 {
-spapr_phb_placement(spapr, index, buid, pio, mmio32, mmio64, n_dma, liobns,
-nv2gpa, nv2atsd, errp);
+if (!spapr_phb_placement(spapr, index, buid, pio, mmio32, mmio64, n_dma,
+ liobns, nv2gpa, nv2atsd, errp)) {
+return false;
+}
+
 *nv2gpa = 0;
 *nv2atsd = 0;
+return true;
 }
-
 static void spapr_machine_4_0_class_options(MachineClass *mc)
 {
 SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
@@ -4732,7 +4737,7 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", false);
  * pseries-2.7
  */
 
-static void 

[PATCH for-6.0 0/9] spapr: Perform hotplug sanity checks at pre-plug

2020-11-20 Thread Greg Kurz
Igor recently suggested that instead of failing in spapr_drc_attach()
at plug time we should rather check that the DRC is attachable at
pre-plug time. This allows to error out before the hot-plugged device
is even realized and to come up with simpler plug callbacks.

sPAPR currently supports hotplug of PCI devices, PHBs, CPU cores,
PC-DIMM/NVDIMM memory and TPM proxy devices. Some of these already
do sanity checks at pre-plug that are sufficient to ensure the DRC
are attachables. Some others don't even have a pre-plug handler.

This series adds the missing pieces so that all failing conditions
are caught at pre-plug time instead of plug time for all devices.

Greg Kurz (9):
  spapr: Do PCI device hotplug sanity checks at pre-plug only
  spapr: Do NVDIMM/PC-DIMM device hotplug sanity checks at pre-plug only
  spapr: Fix pre-2.10 dummy ICP hack
  spapr: Set compat mode in spapr_reset_vcpu()
  spapr: Simplify error path of spapr_core_plug()
  spapr: Make PHB placement functions and spapr_pre_plug_phb() return
status
  spapr: Do PHB hoplug sanity check at pre-plug
  spapr: Do TPM proxy hotplug sanity checks at pre-plug
  spapr: spapr_drc_attach() cannot fail

 include/hw/ppc/spapr.h|   2 +-
 include/hw/ppc/spapr_drc.h|   8 +-
 include/hw/ppc/spapr_nvdimm.h |   2 +-
 hw/ppc/spapr.c| 157 --
 hw/ppc/spapr_cpu_core.c   |  13 +++
 hw/ppc/spapr_drc.c|   8 +-
 hw/ppc/spapr_nvdimm.c |  11 +--
 hw/ppc/spapr_pci.c|  43 +++---
 8 files changed, 138 insertions(+), 106 deletions(-)

-- 
2.26.2





Re: [PATCH v2] drivers/virt: vmgenid: add vm generation id driver

2020-11-20 Thread Jann Horn
On Mon, Nov 16, 2020 at 4:35 PM Catangiu, Adrian Costin
 wrote:
> This patch is a driver that exposes a monotonic incremental Virtual
> Machine Generation u32 counter via a char-dev FS interface that
> provides sync and async VmGen counter updates notifications. It also
> provides VmGen counter retrieval and confirmation mechanisms.
>
> The hw provided UUID is not exposed to userspace, it is internally
> used by the driver to keep accounting for the exposed VmGen counter.
> The counter starts from zero when the driver is initialized and
> monotonically increments every time the hw UUID changes (the VM
> generation changes).
>
> On each hw UUID change, the new hypervisor-provided UUID is also fed
> to the kernel RNG.

As for v1:

Is there a reasonable usecase for the "confirmation" mechanism? It
doesn't seem very useful to me.

How do you envision integrating this with libraries that have to work
in restrictive seccomp sandboxes? If this was in the vDSO, that would
be much easier.



[PULL 2/2] qboot: update to latest upstream

2020-11-20 Thread Paolo Bonzini
This also brings in two patches that Debian had to include,
qboot_stop_using_inttypes.patch and qboot_no_jump_tables.diff.

Reported-by: Michael Tokarev 
Signed-off-by: Paolo Bonzini 
Message-Id: <20201120152408.164346-1-pbonz...@redhat.com>
Signed-off-by: Paolo Bonzini 
---
 pc-bios/qboot.rom | Bin 65536 -> 65536 bytes
 roms/Makefile |   8 ++--
 roms/qboot|   2 +-
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/pc-bios/qboot.rom b/pc-bios/qboot.rom
index 
45eabc516692e2d134bbb630d133c7c2dcc9a9b6..7634106a0766913077e88dfcb1021c1168dcad3c
 100644
GIT binary patch
literal 65536
zcmeI4eRx#Wwg1mdCNN-hB7#OmjTRLuXi!_B;B`Pou{9cAqWFTM!a!TCRuaHof}z7p
zPR69^i+!}!dwFY1du>Zwiy>0)1TaBK>!@j)Vzg5n?TIt$sHvoN%K3fPK4;!AQG1`~
z-amfNNy}MhukYG>uf6u#YrmX5R_m{Y;;B%w)VSd!O>3An#^y3j+Y-Cc
zr`4|>=hJG6jjJYUnvopKqhlnGhyRVo;?sD9&+^608pDuLVO%?@~RG
zZip^z2n;N3EfmO%!-zwI#kM09UAoQq)YWZ!PbEyv0>*wO|u|VLFJv=wJtQw^;9UC
z=K@k_u-)+H6}OPnk^CWFRZbW@_lPCQ7$(z2RSkQ_}vB$3khByl
z?U}tt@q=$7a)gqOdkJsb$%H=bF-mXXWXX(l`A_HNC2H$SU!qo$k
z)#7K_C3^LMUfC~*?}iET!Tow$@5L+GI7k
z|Kn5~C57&+?xzL5osn#zd-0{C?eK9$b&|(w=v}-WWyFum+(;I5$ZuH5zh25LtCakf
z{0u*~btz+L8)bNRxVqmJ&0}KGuy*OOzrdjDYVm99b>k1@wM23K+1HKVkk?}r*PDIa
zc%QtERNNPF0qb?+9l{-sk;2C^1f2UrGZsr<>~i`
z&-@5GWo7%`vdSxvxJ)FTuuJRf8bl(7VKJmW)7$q`8}@sBJNF-5R}i_ra8BZh4@o4_
z#DO~{-)vF5Ko4E8D#d+dZ|j)cWtnfiPHy#*V=H4p#F(OLyJ*0F>zdBhG+H$
zTjYN)8pr$t`=-rT7UI8k1IdDc%0`*(6=c#EO>hG`rviUoAZNngL8uO
zf>l917Bt@e2h-Dn;7!3Bf;R?l4lWGd61+8dMsRr0xA{3K@8j~1`pEnPkN7qXJN^3W
zs^`z0Gp|aI8K1+p3vRmM#+w)3a_bqxeVZRWVC(ExI`j=`?zH}UJu%o{AxXCZ=
z(zH^ot=#L=c4&_t*s(SzZnfAD&)U17YSMZ{B;Nj`KXC+dy^2?uKB`wHB~*ng2^gtx
zby7c|Kd=8;-}By``Um>Le}6U3he~E{x*d|3T!v{yIyGluoskMz}V`^uXk-
zzlQ?PzxNY8B{kn-Rjq_e(bN`Rh{{YShQ2VaA4KUt>aXbS?`;bQ;-P(|nM|RiLJ%`g(+_gZ{eJP@fy
z^n3`342k@(5XpsoyRHqHy3$r1E37oNjtJPSJ2I@_wnx0SB|J~}*ekPKPSw#evsWjZ0_k0{_*fJy

[PULL 1/2] usb: fix kconfig for usb-xhci-sysbus

2020-11-20 Thread Paolo Bonzini
Remove the "default y" for USB_XHCI_SYSBUS because
sysbus devices are not user creatable; boards that use them will
specify them manually with "imply" or "select" clauses.

It would be nice to keep the ability to remove PCIe and USB from microvm,
since thos can be disabled on the command line and therefore should not
be included if QEMU is configured --without-default-devices.  However
it's too late for 5.2 to figure out a place for the DSDT creation code.

Reported-by: Bruce Rogers 
Cc: Gerd Hoffmann 
Signed-off-by: Paolo Bonzini 
---
 hw/usb/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index 3b07d9cf68..7fbae18bc8 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -47,7 +47,6 @@ config USB_XHCI_NEC
 
 config USB_XHCI_SYSBUS
 bool
-default y
 select USB_XHCI
 
 config USB_MUSB
-- 
2.26.2





[PULL 0/2] Kconfig, qboot changes for 2020-11-20

2020-11-20 Thread Paolo Bonzini
The following changes since commit 7fbd7e710323c8f4c5f6a38a8ae0e6726b5a4599:

  Merge remote-tracking branch 
'remotes/stefanha-gitlab/tags/tracing-pull-request' into staging (2020-11-19 
17:08:42 +)

are available in the Git repository at:

  https://gitlab.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to 5983021eb6cd0fb8dfbac5211892f5231758d60b:

  qboot: update to latest upstream (2020-11-20 10:48:53 -0500)


Bug fixes


Paolo Bonzini (2):
  usb: fix kconfig for usb-xhci-sysbus
  qboot: update to latest upstream

 hw/usb/Kconfig|   1 -
 pc-bios/qboot.rom | Bin 65536 -> 65536 bytes
 roms/Makefile |   8 ++--
 roms/qboot|   2 +-
 4 files changed, 7 insertions(+), 4 deletions(-)
-- 
2.26.2




Re: [PATCH RFC] vfio: Move the saving of the config space to the right place in VFIO migration

2020-11-20 Thread Alex Williamson
On Fri, 20 Nov 2020 22:05:49 +0800
Shenming Lu  wrote:

> On 2020/11/20 1:41, Alex Williamson wrote:
> > On Thu, 19 Nov 2020 14:13:24 +0530
> > Kirti Wankhede  wrote:
> >   
> >> On 11/14/2020 2:47 PM, Shenming Lu wrote:  
> >>> When running VFIO migration, I found that the restoring of VFIO PCI 
> >>> device’s
> >>> config space is before VGIC on ARM64 target. But generally, interrupt 
> >>> controllers
> >>> need to be restored before PCI devices. 
> >>
> >> Is there any other way by which VGIC can be restored before PCI device?  
> 
> As far as I know, it seems to have to depend on priorities in the 
> non-iterable process.
> 
> >>  
> >>> Besides, if a VFIO PCI device is
> >>> configured to have directly-injected MSIs (VLPIs), the restoring of its 
> >>> config
> >>> space will trigger the configuring of these VLPIs (in kernel), where it 
> >>> would
> >>> return an error as I saw due to the dependency on kvm’s vgic.
> >>> 
> >>
> >> Can this be fixed in kernel to re-initialize the kernel state?  
> 
> Did you mean to reconfigure these VLPIs when restoring kvm's vgic?
> But the fact is that this error is not caused by kernel, it is due to the 
> incorrect
> calling order of qemu...
> 
> >>  
> >>> To avoid this, we can move the saving of the config space from the 
> >>> iterable
> >>> process to the non-iterable process, so that it will be called after VGIC
> >>> according to their priorities.
> >>> 
> >>
> >> With this change, at resume side, pre-copy phase data would reach 
> >> destination without restored config space. VFIO device on destination 
> >> might need it's config space setup and validated before it can accept 
> >> further VFIO device specific migration state.
> >>
> >> This also changes bit-stream, so it would break migration with original 
> >> migration patch-set.  
> > 
> > Config space can continue to change while in pre-copy, if we're only
> > sending config space at the initiation of pre-copy, how are any changes
> > that might occur before the VM is stopped conveyed to the target?  For
> > example the guest might reboot and a device returned to INTx mode from
> > MSI during pre-copy.  Thanks,  
> 
> What I see is that the config space is only saved once in 
> save_live_complete_precopy
> currently...
> As you said, a VFIO device might need it's config space setup first, and
> the config space can continue to change while in pre-copy, Did you mean we
> have to migrate the config space in save_live_iterate?
> However, I still have a little doubt about the restoring dependence between
> the qemu emulated config space and the device data...
> 
> Besides, if we surely can't move the saving of the config space back, can we
> just move some actions which are triggered by the restoring of the config 
> space
> back (such as vfio_msix_enable())?

It seems that the significant benefit to enabling interrupts during
pre-copy would be to reduce the latency and failure potential during
the final phase of migration.  Do we have any data for how much it adds
to the device contributed downtime to configure interrupts only at the
final stage?  My guess is that it's a measurable delay on its own.  At
the same time, we can't ignore the differences in machine specific
dependencies and if we don't even sync the config space once the VM is
stopped... this all seems not ready to call supported, especially if we
have concerns already about migration bit-stream compatibility.

Given our timing relative to QEMU 5.2, the only path I feel comfortable
with is to move forward with downgrading vfio migration support to be
enabled via an experimental option.  Objections?  Thanks,

Alex

> 
> The demo patch is as follows (but it seems that .save_state is not a 
> appropriate
> place to do it. -_-):
> 
> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> index 55261562d4..9cf0310148 100644
> --- a/hw/vfio/migration.c
> +++ b/hw/vfio/migration.c
> @@ -44,6 +44,7 @@
>  #define VFIO_MIG_FLAG_DEV_CONFIG_STATE  (0xef12ULL)
>  #define VFIO_MIG_FLAG_DEV_SETUP_STATE   (0xef13ULL)
>  #define VFIO_MIG_FLAG_DEV_DATA_STATE(0xef14ULL)
> +#define VFIO_MIG_FLAG_DEV_STATE_TRIGGER (0xef15ULL)
> 
>  static int64_t bytes_transferred;
> 
> @@ -368,6 +369,15 @@ static int vfio_save_device_config_state(QEMUFile *f, 
> void *opaque)
>  return qemu_file_get_error(f);
>  }
> 
> +static void vfio_device_state_trigger(void *opaque)
> +{
> +VFIODevice *vbasedev = opaque;
> +
> +if (vbasedev->ops && vbasedev->ops->vfio_trigger_config) {
> +vbasedev->ops->vfio_trigger_config(vbasedev);
> +}
> +}
> +
>  static int vfio_load_device_config_state(QEMUFile *f, void *opaque)
>  {
>  VFIODevice *vbasedev = opaque;
> @@ -620,6 +630,13 @@ static int vfio_save_complete_precopy(QEMUFile *f, void 
> *opaque)
>  return ret;
>  }
> 
> +static void vfio_save_state_trigger(QEMUFile *f, void *opaque)
> +{
> +qemu_put_be64(f, 

Re: [PATCH v2] drivers/virt: vmgenid: add vm generation id driver

2020-11-20 Thread Dmitry Safonov
Hello,

+Cc Eric, Adrian

On 11/19/20 6:36 PM, Alexander Graf wrote:
> On 19.11.20 18:38, Mike Rapoport wrote:
>> On Thu, Nov 19, 2020 at 01:51:18PM +0100, Alexander Graf wrote:
>>> On 19.11.20 13:02, Christian Borntraeger wrote:
 On 16.11.20 16:34, Catangiu, Adrian Costin wrote:
> - Background
>
> The VM Generation ID is a feature defined by Microsoft (paper:
> http://go.microsoft.com/fwlink/?LinkId=260709) and supported by
> multiple hypervisor vendors.
>
> The feature is required in virtualized environments by apps that work
> with local copies/caches of world-unique data such as random values,
> uuids, monotonically increasing counters, etc.
> Such apps can be negatively affected by VM snapshotting when the VM
> is either cloned or returned to an earlier point in time.
>
> The VM Generation ID is a simple concept meant to alleviate the issue
> by providing a unique ID that changes each time the VM is restored
> from a snapshot. The hw provided UUID value can be used to
> differentiate between VMs or different generations of the same VM.
>
> - Problem
>
> The VM Generation ID is exposed through an ACPI device by multiple
> hypervisor vendors but neither the vendors or upstream Linux have no
> default driver for it leaving users to fend for themselves.
[..]

>>> The only piece where I'm unsure is how this will interact with CRIU.
>>
>> To C/R applications that use /dev/vmgenid CRIU need to be aware of it.
>> Checkpointing and restoring withing the same "VM generation" shouldn't be
>> a problem, but IMHO, making restore work after genid bump could be
>> challenging.
>>
>> Alex, what scenario involving CRIU did you have in mind?
> 
> You can in theory run into the same situation with containers that this
> patch is solving for virtual machines. You could for example do a
> snapshot of a prewarmed Java runtime with CRIU to get full JIT speeds
> starting from the first request.
> 
> That however means you run into the problem of predictable randomness
> again.
> 
>>
>>> Can containers emulate ioctls and device nodes?
>>
>> Containers do not emulate ioctls but they can have /dev/vmgenid inside
>> the container, so applications can use it the same way as outside the
>> container.
> 
> Hm. I suppose we could add a CAP_ADMIN ioctl interface to /dev/vmgenid
> (when container people get to the point of needing it) that sets the
> generation to "at least X". That way on restore, you could just call
> that with "generation at snapshot"+1.
> 
> That also means we need to have this interface available without virtual
> machines then though, right?

Sounds like a good idea.
I guess, genvmid can be global on host, rather than per-userns or
per-process for simplicity. Later if somebody will have a bottleneck on
restore when every process on the machine wakes up from read() it could
be virtualized, but doing it now sounds too early.

ioctl() probably should go under
checkpoint_restore_ns_capable(current_user_ns()), rather than
CAP_SYS_ADMIN (I believe it should be safe from DOS as only CRIU should
run with this capability, but worth to document this).

Thanks,
 Dmitry



[PATCH 24/26] MAINTAINERS: Add entry for MIPS Loongson TCG

2020-11-20 Thread Philippe Mathieu-Daudé
Add an entry for the TCG core related to Loongson.

Signed-off-by: Philippe Mathieu-Daudé 
---
Adding Huacai and Jiaxun in case they want to be notified of
changes, patch conditional to their individual approval.
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ce7fe949036..be42b56300f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -240,6 +240,13 @@ F: include/hw/timer/mips_gictimer.h
 F: tests/tcg/mips/
 K: ^Subject:.*(?i)mips
 
+MIPS TCG CPUs (Loongson)
+M: Philippe Mathieu-Daudé 
+R: Huacai Chen 
+R: Jiaxun Yang 
+S: Odd Fixes
+F: target/mips/vendor-loong*
+
 MIPS TCG CPUs (nanoMIPS ISA)
 S: Orphan
 F: disas/nanomips.*
-- 
2.26.2




[PATCH 22/26] target/mips: Extract Toshiba TXx9 translation routines

2020-11-20 Thread Philippe Mathieu-Daudé
Extract 300 lines of the Toshiba TX19/TX39/TX49/TX79
translation routines to 'vendor-tx_translate.c.inc'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c   | 302 +---
 target/mips/vendor-tx_translate.c.inc | 315 ++
 2 files changed, 316 insertions(+), 301 deletions(-)
 create mode 100644 target/mips/vendor-tx_translate.c.inc

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 6b35498dd3d..a1cf1fe7f23 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -730,31 +730,6 @@ enum {
  * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
  * or sixteen 8-bit paths.
  *
- * Reference:
- *
- * The Toshiba TX System RISC TX79 Core Architecture manual,
- * https://wiki.qemu.org/File:C790.pdf
- *
- * Three-Operand Multiply and Multiply-Add (4 instructions)
- * 
- * MADD[rd,] rs, rt  Multiply/Add
- * MADDU   [rd,] rs, rt  Multiply/Add Unsigned
- * MULT[rd,] rs, rt  Multiply (3-operand)
- * MULTU   [rd,] rs, rt  Multiply Unsigned (3-operand)
- *
- * Multiply Instructions for Pipeline 1 (10 instructions)
- * --
- * MULT1   [rd,] rs, rt  Multiply Pipeline 1
- * MULTU1  [rd,] rs, rt  Multiply Unsigned Pipeline 1
- * DIV1rs, rtDivide Pipeline 1
- * DIVU1   rs, rtDivide Unsigned Pipeline 1
- * MADD1   [rd,] rs, rt  Multiply-Add Pipeline 1
- * MADDU1  [rd,] rs, rt  Multiply-Add Unsigned Pipeline 1
- * MFHI1   rdMove From HI1 Register
- * MFLO1   rdMove From LO1 Register
- * MTHI1   rsMove To HI1 Register
- * MTLO1   rsMove To LO1 Register
- *
  * Arithmetic (19 instructions)
  * 
  * PADDB   rd, rs, rtParallel Add Byte
@@ -3046,44 +3021,6 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
 tcg_temp_free(t1);
 }
 
-#if defined(TARGET_MIPS64)
-/* Copy GPR to and from TX79 HI1/LO1 register. */
-static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
-{
-if (reg == 0 && (opc == OPC_MFHI1 || opc == OPC_MFLO1)) {
-/* Treat as NOP. */
-return;
-}
-
-switch (opc) {
-case OPC_MFHI1:
-tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
-break;
-case OPC_MFLO1:
-tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
-break;
-case OPC_MTHI1:
-if (reg != 0) {
-tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
-} else {
-tcg_gen_movi_tl(cpu_HI[1], 0);
-}
-break;
-case OPC_MTLO1:
-if (reg != 0) {
-tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
-} else {
-tcg_gen_movi_tl(cpu_LO[1], 0);
-}
-break;
-default:
-MIPS_INVAL("mfthilo1 TX79");
-generate_exception_end(ctx, EXCP_RI);
-break;
-}
-}
-#endif
-
 /* Arithmetic on HI/LO registers */
 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
 {
@@ -3432,65 +3369,6 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, 
int rd, int rs, int rt)
 tcg_temp_free(t1);
 }
 
-#if defined(TARGET_MIPS64)
-static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
-{
-TCGv t0, t1;
-
-t0 = tcg_temp_new();
-t1 = tcg_temp_new();
-
-gen_load_gpr(t0, rs);
-gen_load_gpr(t1, rt);
-
-switch (opc) {
-case OPC_DIV1:
-{
-TCGv t2 = tcg_temp_new();
-TCGv t3 = tcg_temp_new();
-tcg_gen_ext32s_tl(t0, t0);
-tcg_gen_ext32s_tl(t1, t1);
-tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
-tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
-tcg_gen_and_tl(t2, t2, t3);
-tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
-tcg_gen_or_tl(t2, t2, t3);
-tcg_gen_movi_tl(t3, 0);
-tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
-tcg_gen_div_tl(cpu_LO[1], t0, t1);
-tcg_gen_rem_tl(cpu_HI[1], t0, t1);
-tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
-tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
-tcg_temp_free(t3);
-tcg_temp_free(t2);
-}
-break;
-case OPC_DIVU1:
-{
-TCGv t2 = tcg_const_tl(0);
-TCGv t3 = tcg_const_tl(1);
-tcg_gen_ext32u_tl(t0, t0);
-tcg_gen_ext32u_tl(t1, t1);
-tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
-tcg_gen_divu_tl(cpu_LO[1], t0, t1);
-tcg_gen_remu_tl(cpu_HI[1], t0, t1);
-tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
-tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
-tcg_temp_free(t3);
-tcg_temp_free(t2);
-}
-break;
-default:
-MIPS_INVAL("div1 TX79");
-  

[PATCH 21/26] target/mips: Make pipeline 1 multiply opcodes generic

2020-11-20 Thread Philippe Mathieu-Daudé
Special2 multiply opcodes are not specific to Toshiba TX79,
and are not part of its multimedia extension.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 75 +
 1 file changed, 38 insertions(+), 37 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 0914b89eae6..6b35498dd3d 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -330,6 +330,19 @@ enum {
 OPC_MUL  = 0x02 | OPC_SPECIAL2,
 OPC_MSUB = 0x04 | OPC_SPECIAL2,
 OPC_MSUBU= 0x05 | OPC_SPECIAL2,
+
+/* Multiply Instructions for Pipeline 1 */
+OPC_MFHI1= 0x10 | OPC_SPECIAL2,
+OPC_MTHI1= 0x11 | OPC_SPECIAL2,
+OPC_MFLO1= 0x12 | OPC_SPECIAL2,
+OPC_MTLO1= 0x13 | OPC_SPECIAL2,
+OPC_MULT1= 0x18 | OPC_SPECIAL2,
+OPC_MULTU1   = 0x19 | OPC_SPECIAL2,
+OPC_DIV1 = 0x1A | OPC_SPECIAL2,
+OPC_DIVU1= 0x1B | OPC_SPECIAL2,
+OPC_MADD1= 0x20 | OPC_SPECIAL2,
+OPC_MADDU1   = 0x21 | OPC_SPECIAL2,
+
 /* Misc */
 OPC_CLZ  = 0x20 | OPC_SPECIAL2,
 OPC_CLO  = 0x21 | OPC_SPECIAL2,
@@ -933,21 +946,9 @@ enum {
 
 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
 enum {
-MMI_OPC_MADD   = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
-MMI_OPC_MADDU  = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
 MMI_OPC_PLZCW  = 0x04 | MMI_OPC_CLASS_MMI,
 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
-MMI_OPC_MFHI1  = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
-MMI_OPC_MTHI1  = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
-MMI_OPC_MFLO1  = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
-MMI_OPC_MTLO1  = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
-MMI_OPC_MULT1  = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
-MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
-MMI_OPC_DIV1   = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
-MMI_OPC_DIVU1  = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
-MMI_OPC_MADD1  = 0x20 | MMI_OPC_CLASS_MMI,
-MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
 MMI_OPC_PMFHL  = 0x30 | MMI_OPC_CLASS_MMI,
@@ -3049,26 +3050,26 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
 /* Copy GPR to and from TX79 HI1/LO1 register. */
 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
 {
-if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
+if (reg == 0 && (opc == OPC_MFHI1 || opc == OPC_MFLO1)) {
 /* Treat as NOP. */
 return;
 }
 
 switch (opc) {
-case MMI_OPC_MFHI1:
+case OPC_MFHI1:
 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
 break;
-case MMI_OPC_MFLO1:
+case OPC_MFLO1:
 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
 break;
-case MMI_OPC_MTHI1:
+case OPC_MTHI1:
 if (reg != 0) {
 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
 } else {
 tcg_gen_movi_tl(cpu_HI[1], 0);
 }
 break;
-case MMI_OPC_MTLO1:
+case OPC_MTLO1:
 if (reg != 0) {
 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
 } else {
@@ -3443,7 +3444,7 @@ static void gen_div1_tx79(DisasContext *ctx, uint32_t 
opc, int rs, int rt)
 gen_load_gpr(t1, rt);
 
 switch (opc) {
-case MMI_OPC_DIV1:
+case OPC_DIV1:
 {
 TCGv t2 = tcg_temp_new();
 TCGv t3 = tcg_temp_new();
@@ -3464,7 +3465,7 @@ static void gen_div1_tx79(DisasContext *ctx, uint32_t 
opc, int rs, int rt)
 tcg_temp_free(t2);
 }
 break;
-case MMI_OPC_DIVU1:
+case OPC_DIVU1:
 {
 TCGv t2 = tcg_const_tl(0);
 TCGv t3 = tcg_const_tl(1);
@@ -3719,7 +3720,7 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
 gen_load_gpr(t1, rt);
 
 switch (opc) {
-case MMI_OPC_MULT1:
+case OPC_MULT1:
 acc = 1;
 /* Fall through */
 case OPC_MULT:
@@ -3738,7 +3739,7 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
 tcg_temp_free_i32(t3);
 }
 break;
-case MMI_OPC_MULTU1:
+case OPC_MULTU1:
 acc = 1;
 /* Fall through */
 case OPC_MULTU:
@@ -3757,10 +3758,10 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t 
opc,
 tcg_temp_free_i32(t3);
 }
 break;
-case MMI_OPC_MADD1:
+case OPC_MADD1:
 acc = 1;
 /* Fall through */
-case MMI_OPC_MADD:
+case OPC_MADD:
 {
 TCGv_i64 t2 = tcg_temp_new_i64();
 TCGv_i64 t3 = tcg_temp_new_i64();
@@ -3779,10 +3780,10 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t 
opc,
  

[PATCH 18/26] target/mips: Extract Loongson SIMD translation routines

2020-11-20 Thread Philippe Mathieu-Daudé
LoongSIMD (formerly LoongMMI in Loongson 2E/F) is the
128-bit SIMD extension from the LoongISA.

Extract 600 lines of translation routines to
'vendor-loong-simd_translate.c.inc'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c   | 598 +
 target/mips/vendor-loong-simd_translate.c.inc | 611 ++
 2 files changed, 612 insertions(+), 597 deletions(-)
 create mode 100644 target/mips/vendor-loong-simd_translate.c.inc

diff --git a/target/mips/translate.c b/target/mips/translate.c
index b01a16e9da4..105a104bb0c 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -330,19 +330,6 @@ enum {
 OPC_MUL  = 0x02 | OPC_SPECIAL2,
 OPC_MSUB = 0x04 | OPC_SPECIAL2,
 OPC_MSUBU= 0x05 | OPC_SPECIAL2,
-/* Loongson 2F */
-OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
-OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
-OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
-OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
-OPC_DIV_G_2F= 0x14 | OPC_SPECIAL2,
-OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
-OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
-OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
-OPC_MOD_G_2F= 0x1c | OPC_SPECIAL2,
-OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
-OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
-OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 /* Misc */
 OPC_CLZ  = 0x20 | OPC_SPECIAL2,
 OPC_CLO  = 0x21 | OPC_SPECIAL2,
@@ -4569,590 +4556,6 @@ static void gen_cl(DisasContext *ctx, uint32_t opc,
 }
 }
 
-/* Godson integer instructions */
-static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
- int rd, int rs, int rt)
-{
-TCGv t0, t1;
-
-if (rd == 0) {
-/* Treat as NOP. */
-return;
-}
-
-switch (opc) {
-case OPC_MULT_G_2E:
-case OPC_MULT_G_2F:
-case OPC_MULTU_G_2E:
-case OPC_MULTU_G_2F:
-#if defined(TARGET_MIPS64)
-case OPC_DMULT_G_2E:
-case OPC_DMULT_G_2F:
-case OPC_DMULTU_G_2E:
-case OPC_DMULTU_G_2F:
-#endif
-t0 = tcg_temp_new();
-t1 = tcg_temp_new();
-break;
-default:
-t0 = tcg_temp_local_new();
-t1 = tcg_temp_local_new();
-break;
-}
-
-gen_load_gpr(t0, rs);
-gen_load_gpr(t1, rt);
-
-switch (opc) {
-case OPC_MULT_G_2E:
-case OPC_MULT_G_2F:
-tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
-tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
-break;
-case OPC_MULTU_G_2E:
-case OPC_MULTU_G_2F:
-tcg_gen_ext32u_tl(t0, t0);
-tcg_gen_ext32u_tl(t1, t1);
-tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
-tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
-break;
-case OPC_DIV_G_2E:
-case OPC_DIV_G_2F:
-{
-TCGLabel *l1 = gen_new_label();
-TCGLabel *l2 = gen_new_label();
-TCGLabel *l3 = gen_new_label();
-tcg_gen_ext32s_tl(t0, t0);
-tcg_gen_ext32s_tl(t1, t1);
-tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
-tcg_gen_movi_tl(cpu_gpr[rd], 0);
-tcg_gen_br(l3);
-gen_set_label(l1);
-tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
-tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
-tcg_gen_mov_tl(cpu_gpr[rd], t0);
-tcg_gen_br(l3);
-gen_set_label(l2);
-tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
-tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
-gen_set_label(l3);
-}
-break;
-case OPC_DIVU_G_2E:
-case OPC_DIVU_G_2F:
-{
-TCGLabel *l1 = gen_new_label();
-TCGLabel *l2 = gen_new_label();
-tcg_gen_ext32u_tl(t0, t0);
-tcg_gen_ext32u_tl(t1, t1);
-tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
-tcg_gen_movi_tl(cpu_gpr[rd], 0);
-tcg_gen_br(l2);
-gen_set_label(l1);
-tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
-tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
-gen_set_label(l2);
-}
-break;
-case OPC_MOD_G_2E:
-case OPC_MOD_G_2F:
-{
-TCGLabel *l1 = gen_new_label();
-TCGLabel *l2 = gen_new_label();
-TCGLabel *l3 = gen_new_label();
-tcg_gen_ext32u_tl(t0, t0);
-tcg_gen_ext32u_tl(t1, t1);
-tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
-tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
-tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
-gen_set_label(l1);
-tcg_gen_movi_tl(cpu_gpr[rd], 0);
-tcg_gen_br(l3);
-gen_set_label(l2);
-tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
-tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
-gen_set_label(l3);
-}
-break;
-case OPC_MODU_G_2E:
-case OPC_MODU_G_2F:
-{
-TCGLabel *l1 = gen_new_label();
-   

[PATCH 10/26] target/mips: Extract the microMIPS ISA helper definitions

2020-11-20 Thread Philippe Mathieu-Daudé
Extract the microMIPS ISA helper definitions to
'isa-micromips_helper.h.inc'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/helper.h   | 10 ++
 target/mips/isa-micromips_helper.h.inc | 17 +
 2 files changed, 19 insertions(+), 8 deletions(-)
 create mode 100644 target/mips/isa-micromips_helper.h.inc

diff --git a/target/mips/helper.h b/target/mips/helper.h
index c15caed9fca..ee93c2de836 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -181,14 +181,6 @@ DEF_HELPER_2(dmtc0_entrylo1, void, env, i64)
 
 #endif /* !CONFIG_USER_ONLY */
 
-/* microMIPS functions */
-DEF_HELPER_4(lwm, void, env, tl, tl, i32)
-DEF_HELPER_4(swm, void, env, tl, tl, i32)
-#ifdef TARGET_MIPS64
-DEF_HELPER_4(ldm, void, env, tl, tl, i32)
-DEF_HELPER_4(sdm, void, env, tl, tl, i32)
-#endif
-
 /* CP1 functions */
 DEF_HELPER_2(cfc1, tl, env, i32)
 DEF_HELPER_4(ctc1, void, env, tl, i32, i32)
@@ -427,6 +419,8 @@ DEF_HELPER_FLAGS_1(pmovmskb, TCG_CALL_NO_RWG_SE, i64, i64)
 
 DEF_HELPER_3(cache, void, env, tl, i32)
 
+#include "isa-micromips_helper.h.inc"
+
 #include "mod-mips-dsp_helper.h.inc"
 #include "mod-mips-msa_helper.h.inc"
 #include "mod-mips-mt_helper.h.inc"
diff --git a/target/mips/isa-micromips_helper.h.inc 
b/target/mips/isa-micromips_helper.h.inc
new file mode 100644
index 000..66a764c4aac
--- /dev/null
+++ b/target/mips/isa-micromips_helper.h.inc
@@ -0,0 +1,17 @@
+/*
+ * microMIPS instruction emulation helpers for QEMU.
+ *
+ *  Copyright (c) 2004-2005 Jocelyn Mayer
+ *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+DEF_HELPER_4(lwm, void, env, tl, tl, i32)
+DEF_HELPER_4(swm, void, env, tl, tl, i32)
+#ifdef TARGET_MIPS64
+DEF_HELPER_4(ldm, void, env, tl, tl, i32)
+DEF_HELPER_4(sdm, void, env, tl, tl, i32)
+#endif
-- 
2.26.2




[PATCH 25/26] MAINTAINERS: Add entry for MIPS Ingenic Xburst TCG

2020-11-20 Thread Philippe Mathieu-Daudé
Add an entry for the TCG core related to Ingenic Xburst.

Signed-off-by: Philippe Mathieu-Daudé 
---
Adding Craig Janeczek in case he wants to be notified of changes,
patch conditional to his approval.
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index be42b56300f..b6d98b95c47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -247,6 +247,12 @@ R: Jiaxun Yang 
 S: Odd Fixes
 F: target/mips/vendor-loong*
 
+MIPS TCG CPUs (Ingenic Xburst)
+M: Philippe Mathieu-Daudé 
+R: Craig Janeczek 
+S: Odd Fixes
+F: target/mips/vendor-xburst*
+
 MIPS TCG CPUs (nanoMIPS ISA)
 S: Orphan
 F: disas/nanomips.*
-- 
2.26.2




[PATCH 26/26] MAINTAINERS: Add entry for MIPS Toshiba TCG

2020-11-20 Thread Philippe Mathieu-Daudé
Add an entry for the TCG core related to Toshiba TXx9.

Signed-off-by: Philippe Mathieu-Daudé 
---
Adding Fredrik Noring in case he wants to be notified of changes,
patch conditional to his approval.
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b6d98b95c47..d97f0f1d66e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -253,6 +253,12 @@ R: Craig Janeczek 
 S: Odd Fixes
 F: target/mips/vendor-xburst*
 
+MIPS TCG CPUs (Toshiba TX)
+M: Philippe Mathieu-Daudé 
+R: Fredrik Noring 
+S: Odd Fixes
+F: target/mips/vendor-tx*
+
 MIPS TCG CPUs (nanoMIPS ISA)
 S: Orphan
 F: disas/nanomips.*
-- 
2.26.2




[PATCH 23/26] target/mips: Extract Toshiba TX79 multimedia translation routines

2020-11-20 Thread Philippe Mathieu-Daudé
Extract 600 lines of the the Toshiba TX79 multimedia
translation routines to 'vendor-tx-mmi_translate.c.inc'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c   | 567 -
 target/mips/vendor-tx-mmi_translate.c.inc | 573 ++
 target/mips/vendor-tx_translate.c.inc |   2 +
 3 files changed, 575 insertions(+), 567 deletions(-)
 create mode 100644 target/mips/vendor-tx-mmi_translate.c.inc

diff --git a/target/mips/translate.c b/target/mips/translate.c
index a1cf1fe7f23..57e82079c50 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -719,405 +719,6 @@ enum {
 OPC_NMSUB_PS= 0x3E | OPC_CP3,
 };
 
-
-/*
- * Overview of the TX79-specific instruction set
- * =
- *
- * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
- * are only used by the specific quadword (128-bit) LQ/SQ load/store
- * instructions and certain multimedia instructions (MMIs). These MMIs
- * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
- * or sixteen 8-bit paths.
- *
- * Arithmetic (19 instructions)
- * 
- * PADDB   rd, rs, rtParallel Add Byte
- * PSUBB   rd, rs, rtParallel Subtract Byte
- * PADDH   rd, rs, rtParallel Add Halfword
- * PSUBH   rd, rs, rtParallel Subtract Halfword
- * PADDW   rd, rs, rtParallel Add Word
- * PSUBW   rd, rs, rtParallel Subtract Word
- * PADSBH  rd, rs, rtParallel Add/Subtract Halfword
- * PADDSB  rd, rs, rtParallel Add with Signed Saturation Byte
- * PSUBSB  rd, rs, rtParallel Subtract with Signed Saturation Byte
- * PADDSH  rd, rs, rtParallel Add with Signed Saturation Halfword
- * PSUBSH  rd, rs, rtParallel Subtract with Signed Saturation Halfword
- * PADDSW  rd, rs, rtParallel Add with Signed Saturation Word
- * PSUBSW  rd, rs, rtParallel Subtract with Signed Saturation Word
- * PADDUB  rd, rs, rtParallel Add with Unsigned saturation Byte
- * PSUBUB  rd, rs, rtParallel Subtract with Unsigned saturation Byte
- * PADDUH  rd, rs, rtParallel Add with Unsigned saturation Halfword
- * PSUBUH  rd, rs, rtParallel Subtract with Unsigned saturation 
Halfword
- * PADDUW  rd, rs, rtParallel Add with Unsigned saturation Word
- * PSUBUW  rd, rs, rtParallel Subtract with Unsigned saturation Word
- *
- * Min/Max (4 instructions)
- * 
- * PMAXH   rd, rs, rtParallel Maximum Halfword
- * PMINH   rd, rs, rtParallel Minimum Halfword
- * PMAXW   rd, rs, rtParallel Maximum Word
- * PMINW   rd, rs, rtParallel Minimum Word
- *
- * Absolute (2 instructions)
- * -
- * PABSH   rd, rtParallel Absolute Halfword
- * PABSW   rd, rtParallel Absolute Word
- *
- * Logical (4 instructions)
- * 
- * PANDrd, rs, rtParallel AND
- * POR rd, rs, rtParallel OR
- * PXORrd, rs, rtParallel XOR
- * PNORrd, rs, rtParallel NOR
- *
- * Shift (9 instructions)
- * --
- * PSLLH   rd, rt, saParallel Shift Left Logical Halfword
- * PSRLH   rd, rt, saParallel Shift Right Logical Halfword
- * PSRAH   rd, rt, saParallel Shift Right Arithmetic Halfword
- * PSLLW   rd, rt, saParallel Shift Left Logical Word
- * PSRLW   rd, rt, saParallel Shift Right Logical Word
- * PSRAW   rd, rt, saParallel Shift Right Arithmetic Word
- * PSLLVW  rd, rt, rsParallel Shift Left Logical Variable Word
- * PSRLVW  rd, rt, rsParallel Shift Right Logical Variable Word
- * PSRAVW  rd, rt, rsParallel Shift Right Arithmetic Variable Word
- *
- * Compare (6 instructions)
- * 
- * PCGTB   rd, rs, rtParallel Compare for Greater Than Byte
- * PCEQB   rd, rs, rtParallel Compare for Equal Byte
- * PCGTH   rd, rs, rtParallel Compare for Greater Than Halfword
- * PCEQH   rd, rs, rtParallel Compare for Equal Halfword
- * PCGTW   rd, rs, rtParallel Compare for Greater Than Word
- * PCEQW   rd, rs, rtParallel Compare for Equal Word
- *
- * LZC (1 instruction)
- * ---
- * PLZCW   rd, rsParallel Leading Zero or One Count Word
- *
- * Quadword Load and Store (2 instructions)
- * 
- * LQ  rt, offset(base)  Load Quadword
- * SQ  rt, offset(base)  Store Quadword
- *
- * Multiply and Divide (19 instructions)
- * -
- * PMULTW  rd, rs, rtParallel Multiply Word
- * PMULTUW rd, rs, rtParallel Multiply Unsigned Word
- * PDIVW   rs, rtParallel Divide Word
- * PDIVUW  rs, rtParallel Divide 

[PATCH 16/26] target/mips: Rename lmmi_helper.c as loong-simd_helper.c

2020-11-20 Thread Philippe Mathieu-Daudé
The LoongMMI extension has been renamed LoongSIMD
(part of the LoongISA). Rename the helper file accordingly.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/{lmmi_helper.c => vendor-loong-simd_helper.c} | 0
 target/mips/meson.build   | 2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename target/mips/{lmmi_helper.c => vendor-loong-simd_helper.c} (100%)

diff --git a/target/mips/lmmi_helper.c b/target/mips/vendor-loong-simd_helper.c
similarity index 100%
rename from target/mips/lmmi_helper.c
rename to target/mips/vendor-loong-simd_helper.c
diff --git a/target/mips/meson.build b/target/mips/meson.build
index b63ef41cb1d..e8f0c080099 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -4,10 +4,10 @@
   'fpu_helper.c',
   'gdbstub.c',
   'helper.c',
-  'lmmi_helper.c',
   'op_helper.c',
   'mod-mips-dsp_helper.c',
   'mod-mips-msa_helper.c',
+  'vendor-loong-simd_helper.c',
   'vendor-vr54xx_helper.c',
 
   'translate.c',
-- 
2.26.2




[PATCH 06/26] target/mips: Extract DSP helper definitions

2020-11-20 Thread Philippe Mathieu-Daudé
'MIPS DSP' is defined as a Module by MIPS. Extract the helper
definitions to 'mod-mips-dsp_helper.h.inc'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/helper.h  | 335 +
 target/mips/mod-mips-dsp_helper.h.inc | 344 ++
 2 files changed, 345 insertions(+), 334 deletions(-)
 create mode 100644 target/mips/mod-mips-dsp_helper.h.inc

diff --git a/target/mips/helper.h b/target/mips/helper.h
index a44f42c6201..bce869f3718 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -447,341 +447,8 @@ DEF_HELPER_FLAGS_2(pasubub, TCG_CALL_NO_RWG_SE, i64, i64, 
i64)
 DEF_HELPER_FLAGS_1(biadd, TCG_CALL_NO_RWG_SE, i64, i64)
 DEF_HELPER_FLAGS_1(pmovmskb, TCG_CALL_NO_RWG_SE, i64, i64)
 
-/*** MIPS DSP ***/
-/* DSP Arithmetic Sub-class insns */
-DEF_HELPER_FLAGS_3(addq_ph, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(addq_s_ph, 0, tl, tl, tl, env)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(addq_qh, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(addq_s_qh, 0, tl, tl, tl, env)
-#endif
-DEF_HELPER_FLAGS_3(addq_s_w, 0, tl, tl, tl, env)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(addq_pw, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(addq_s_pw, 0, tl, tl, tl, env)
-#endif
-DEF_HELPER_FLAGS_3(addu_qb, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(addu_s_qb, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_2(adduh_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(adduh_r_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_3(addu_ph, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(addu_s_ph, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_2(addqh_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(addqh_r_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(addqh_w, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(addqh_r_w, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(addu_ob, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(addu_s_ob, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_2(adduh_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(adduh_r_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_3(addu_qh, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(addu_s_qh, 0, tl, tl, tl, env)
-#endif
-DEF_HELPER_FLAGS_3(subq_ph, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(subq_s_ph, 0, tl, tl, tl, env)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(subq_qh, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(subq_s_qh, 0, tl, tl, tl, env)
-#endif
-DEF_HELPER_FLAGS_3(subq_s_w, 0, tl, tl, tl, env)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(subq_pw, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(subq_s_pw, 0, tl, tl, tl, env)
-#endif
-DEF_HELPER_FLAGS_3(subu_qb, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(subu_s_qb, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_2(subuh_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(subuh_r_qb, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_3(subu_ph, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(subu_s_ph, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_2(subqh_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(subqh_r_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(subqh_w, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(subqh_r_w, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(subu_ob, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(subu_s_ob, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_2(subuh_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(subuh_r_ob, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_3(subu_qh, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(subu_s_qh, 0, tl, tl, tl, env)
-#endif
-DEF_HELPER_FLAGS_3(addsc, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_3(addwc, 0, tl, tl, tl, env)
-DEF_HELPER_FLAGS_2(modsub, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_1(raddu_w_qb, TCG_CALL_NO_RWG_SE, tl, tl)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_1(raddu_l_ob, TCG_CALL_NO_RWG_SE, tl, tl)
-#endif
-DEF_HELPER_FLAGS_2(absq_s_qb, 0, tl, tl, env)
-DEF_HELPER_FLAGS_2(absq_s_ph, 0, tl, tl, env)
-DEF_HELPER_FLAGS_2(absq_s_w, 0, tl, tl, env)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_2(absq_s_ob, 0, tl, tl, env)
-DEF_HELPER_FLAGS_2(absq_s_qh, 0, tl, tl, env)
-DEF_HELPER_FLAGS_2(absq_s_pw, 0, tl, tl, env)
-#endif
-DEF_HELPER_FLAGS_2(precr_qb_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(precrq_qb_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_3(precr_sra_ph_w, TCG_CALL_NO_RWG_SE,
-   tl, i32, tl, tl)
-DEF_HELPER_FLAGS_3(precr_sra_r_ph_w, TCG_CALL_NO_RWG_SE,
-   tl, i32, tl, tl)
-DEF_HELPER_FLAGS_2(precrq_ph_w, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_3(precrq_rs_ph_w, 0, tl, tl, tl, env)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_2(precr_ob_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_3(precr_sra_qh_pw,
-   TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-DEF_HELPER_FLAGS_3(precr_sra_r_qh_pw,
-   TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-DEF_HELPER_FLAGS_2(precrq_ob_qh, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(precrq_qh_pw, 

[PATCH 15/26] target/mips: Extract NEC Vr54xx translation routines

2020-11-20 Thread Philippe Mathieu-Daudé
Extract the NEC Vr54xx translation routines to
'vendor-vr54xx_translate.c.inc'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c   | 86 +
 target/mips/vendor-vr54xx_translate.c.inc | 93 +++
 2 files changed, 95 insertions(+), 84 deletions(-)
 create mode 100644 target/mips/vendor-vr54xx_translate.c.inc

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 095ee31ab5f..b01a16e9da4 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -295,26 +295,6 @@ enum {
 OPC_DLSA = 0x15 | OPC_SPECIAL,
 };
 
-/* Multiplication variants of the vr54xx. */
-#define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
-
-enum {
-OPC_VR54XX_MULS= (0x03 << 6) | OPC_MULT,
-OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
-OPC_VR54XX_MACC= (0x05 << 6) | OPC_MULT,
-OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
-OPC_VR54XX_MSAC= (0x07 << 6) | OPC_MULT,
-OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
-OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
-OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
-OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
-OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
-OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
-OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
-OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
-OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
-};
-
 /* REGIMM (rt field) opcodes */
 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
 
@@ -4546,70 +4526,6 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
 tcg_temp_free(t1);
 }
 
-static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
-   int rd, int rs, int rt)
-{
-TCGv t0 = tcg_temp_new();
-TCGv t1 = tcg_temp_new();
-
-gen_load_gpr(t0, rs);
-gen_load_gpr(t1, rt);
-
-switch (opc) {
-case OPC_VR54XX_MULS:
-gen_helper_muls(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MULSU:
-gen_helper_mulsu(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MACC:
-gen_helper_macc(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MACCU:
-gen_helper_maccu(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MSAC:
-gen_helper_msac(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MSACU:
-gen_helper_msacu(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MULHI:
-gen_helper_mulhi(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MULHIU:
-gen_helper_mulhiu(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MULSHI:
-gen_helper_mulshi(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MULSHIU:
-gen_helper_mulshiu(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MACCHI:
-gen_helper_macchi(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MACCHIU:
-gen_helper_macchiu(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MSACHI:
-gen_helper_msachi(t0, cpu_env, t0, t1);
-break;
-case OPC_VR54XX_MSACHIU:
-gen_helper_msachiu(t0, cpu_env, t0, t1);
-break;
-default:
-MIPS_INVAL("mul vr54xx");
-generate_exception_end(ctx, EXCP_RI);
-goto out;
-}
-gen_store_gpr(t0, rd);
-
- out:
-tcg_temp_free(t0);
-tcg_temp_free(t1);
-}
-
 static void gen_cl(DisasContext *ctx, uint32_t opc,
int rd, int rs)
 {
@@ -13022,6 +12938,8 @@ out:
 
 #include "mod-mips-dsp_translate.c.inc"
 
+#include "vendor-vr54xx_translate.c.inc"
+
 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
 {
 int rs, rt, rd, sa;
diff --git a/target/mips/vendor-vr54xx_translate.c.inc 
b/target/mips/vendor-vr54xx_translate.c.inc
new file mode 100644
index 000..8c952a98ebc
--- /dev/null
+++ b/target/mips/vendor-vr54xx_translate.c.inc
@@ -0,0 +1,93 @@
+/*
+ *  MIPS NEC Vr54xx translation routines.
+ *
+ *  Copyright (c) 2004-2005 Jocelyn Mayer
+ *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+/* Multiplication variants of the vr54xx. */
+#define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
+
+enum {
+OPC_VR54XX_MULS= (0x03 << 6) | OPC_MULT,
+OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
+OPC_VR54XX_MACC= (0x05 << 6) | OPC_MULT,
+OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
+OPC_VR54XX_MSAC= (0x07 << 6) | OPC_MULT,
+OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
+OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
+OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
+OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
+OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
+OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
+OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,

[PATCH 05/26] target/mips: Rename dsp_helper.c as mod-mips-dsp_helper.c

2020-11-20 Thread Philippe Mathieu-Daudé
'MIPS DSP' is defined as a Module by MIPS, rename it as
mod-mips-dsp_helper.c.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/{dsp_helper.c => mod-mips-dsp_helper.c} | 0
 target/mips/meson.build | 2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename target/mips/{dsp_helper.c => mod-mips-dsp_helper.c} (100%)

diff --git a/target/mips/dsp_helper.c b/target/mips/mod-mips-dsp_helper.c
similarity index 100%
rename from target/mips/dsp_helper.c
rename to target/mips/mod-mips-dsp_helper.c
diff --git a/target/mips/meson.build b/target/mips/meson.build
index f2b1b599abc..cc4677d94dc 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -1,12 +1,12 @@
 mips_ss = ss.source_set()
 mips_ss.add(files(
   'cpu.c',
-  'dsp_helper.c',
   'fpu_helper.c',
   'gdbstub.c',
   'helper.c',
   'lmmi_helper.c',
   'op_helper.c',
+  'mod-mips-dsp_helper.c',
   'mod-mips-msa_helper.c',
 
   'translate.c',
-- 
2.26.2




[PATCH 17/26] target/mips: Extract Loongson SIMD helper definitions

2020-11-20 Thread Philippe Mathieu-Daudé
Extract the Loongson SIMD helper definitions to
'vendor-loong-simd_helper.h'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/helper.h   | 60 +--
 target/mips/vendor-loong-simd_helper.h.inc | 69 ++
 2 files changed, 70 insertions(+), 59 deletions(-)
 create mode 100644 target/mips/vendor-loong-simd_helper.h.inc

diff --git a/target/mips/helper.h b/target/mips/helper.h
index 77d66018c8c..134dcaf0d59 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -343,65 +343,6 @@ DEF_HELPER_1(rdhwr_xnp, tl, env)
 DEF_HELPER_2(pmon, void, env, int)
 DEF_HELPER_1(wait, void, env)
 
-/* Loongson multimedia functions.  */
-DEF_HELPER_FLAGS_2(paddsh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(paddush, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(paddh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(paddw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(paddsb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(paddusb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(paddb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(psubsh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psubush, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psubh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psubw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psubsb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psubusb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psubb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(pshufh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(packsswh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(packsshb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(packushb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(punpcklhw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(punpckhhw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(punpcklbh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(punpckhbh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(punpcklwd, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(punpckhwd, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(pavgh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pavgb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pmaxsh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pminsh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pmaxub, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pminub, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(pcmpeqw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pcmpgtw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pcmpeqh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pcmpgth, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pcmpeqb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pcmpgtb, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(psllw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psllh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psrlw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psrlh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psraw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(psrah, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(pmullh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pmulhh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pmulhuh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(pmaddhw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(pasubub, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_1(biadd, TCG_CALL_NO_RWG_SE, i64, i64)
-DEF_HELPER_FLAGS_1(pmovmskb, TCG_CALL_NO_RWG_SE, i64, i64)
-
 DEF_HELPER_3(cache, void, env, tl, i32)
 
 #include "isa-micromips_helper.h.inc"
@@ -411,3 +352,4 @@ DEF_HELPER_3(cache, void, env, tl, i32)
 #include "mod-mips-mt_helper.h.inc"
 
 #include "vendor-vr54xx_helper.h.inc"
+#include "vendor-loong-simd_helper.h.inc"
diff --git a/target/mips/vendor-loong-simd_helper.h.inc 
b/target/mips/vendor-loong-simd_helper.h.inc
new file mode 100644
index 000..30e5fda66e9
--- /dev/null
+++ b/target/mips/vendor-loong-simd_helper.h.inc
@@ -0,0 +1,69 @@
+/*
+ * Loongson SIMD instruction emulation helpers for QEMU.
+ *
+ *  Copyright (c) 2004-2005 Jocelyn Mayer
+ *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
+ *  Copyright (c) 2011 Richard Henderson 
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+DEF_HELPER_FLAGS_2(paddsh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(paddush, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(paddh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(paddw, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(paddsb, TCG_CALL_NO_RWG_SE, 

[PATCH 19/26] target/mips: Extract Loongson EXTensions translation routines

2020-11-20 Thread Philippe Mathieu-Daudé
LoongEXTs are general-purpose extensions from the LoongISA.

Extract 440 lines of translation routines to
'vendor-loong-lext_translate.c.inc'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c   | 440 +
 target/mips/vendor-loong-lext_translate.c.inc | 450 ++
 2 files changed, 451 insertions(+), 439 deletions(-)
 create mode 100644 target/mips/vendor-loong-lext_translate.c.inc

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 105a104bb0c..46306ab7e9c 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -399,48 +399,6 @@ enum {
 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
 };
 
-/* Loongson EXT load/store quad word opcodes */
-#define MASK_LOONGSON_GSLSQ(op)   (MASK_OP_MAJOR(op) | (op & 0x8020))
-enum {
-OPC_GSLQ= 0x0020 | OPC_LWC2,
-OPC_GSLQC1  = 0x8020 | OPC_LWC2,
-OPC_GSSHFL  = OPC_LWC2,
-OPC_GSSQ= 0x0020 | OPC_SWC2,
-OPC_GSSQC1  = 0x8020 | OPC_SWC2,
-OPC_GSSHFS  = OPC_SWC2,
-};
-
-/* Loongson EXT shifted load/store opcodes */
-#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
-enum {
-OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
-OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
-OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
-OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
-OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
-OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
-OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
-OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
-};
-
-/* Loongson EXT LDC2/SDC2 opcodes */
-#define MASK_LOONGSON_LSDC2(op)   (MASK_OP_MAJOR(op) | (op & 0x7))
-
-enum {
-OPC_GSLBX  = 0x0 | OPC_LDC2,
-OPC_GSLHX  = 0x1 | OPC_LDC2,
-OPC_GSLWX  = 0x2 | OPC_LDC2,
-OPC_GSLDX  = 0x3 | OPC_LDC2,
-OPC_GSLWXC1= 0x6 | OPC_LDC2,
-OPC_GSLDXC1= 0x7 | OPC_LDC2,
-OPC_GSSBX  = 0x0 | OPC_SDC2,
-OPC_GSSHX  = 0x1 | OPC_SDC2,
-OPC_GSSWX  = 0x2 | OPC_SDC2,
-OPC_GSSDX  = 0x3 | OPC_SDC2,
-OPC_GSSWXC1= 0x6 | OPC_SDC2,
-OPC_GSSDXC1= 0x7 | OPC_SDC2,
-};
-
 /* BSHFL opcodes */
 #define MASK_BSHFL(op)  (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 
@@ -4556,403 +4514,6 @@ static void gen_cl(DisasContext *ctx, uint32_t opc,
 }
 }
 
-static void gen_loongson_lswc2(DisasContext *ctx, int rt,
-   int rs, int rd)
-{
-TCGv t0, t1, t2;
-TCGv_i32 fp0;
-#if defined(TARGET_MIPS64)
-int lsq_rt1 = ctx->opcode & 0x1f;
-int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
-#endif
-int shf_offset = sextract32(ctx->opcode, 6, 8);
-
-t0 = tcg_temp_new();
-
-switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
-#if defined(TARGET_MIPS64)
-case OPC_GSLQ:
-t1 = tcg_temp_new();
-gen_base_offset_addr(ctx, t0, rs, lsq_offset);
-tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
-   ctx->default_tcg_memop_mask);
-gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
-tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
-   ctx->default_tcg_memop_mask);
-gen_store_gpr(t1, rt);
-gen_store_gpr(t0, lsq_rt1);
-tcg_temp_free(t1);
-break;
-case OPC_GSLQC1:
-check_cp1_enabled(ctx);
-t1 = tcg_temp_new();
-gen_base_offset_addr(ctx, t0, rs, lsq_offset);
-tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
-   ctx->default_tcg_memop_mask);
-gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
-tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
-   ctx->default_tcg_memop_mask);
-gen_store_fpr64(ctx, t1, rt);
-gen_store_fpr64(ctx, t0, lsq_rt1);
-tcg_temp_free(t1);
-break;
-case OPC_GSSQ:
-t1 = tcg_temp_new();
-gen_base_offset_addr(ctx, t0, rs, lsq_offset);
-gen_load_gpr(t1, rt);
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
-   ctx->default_tcg_memop_mask);
-gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
-gen_load_gpr(t1, lsq_rt1);
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
-   ctx->default_tcg_memop_mask);
-tcg_temp_free(t1);
-break;
-case OPC_GSSQC1:
-check_cp1_enabled(ctx);
-t1 = tcg_temp_new();
-gen_base_offset_addr(ctx, t0, rs, lsq_offset);
-gen_load_fpr64(ctx, t1, rt);
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
-   ctx->default_tcg_memop_mask);
-gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
-gen_load_fpr64(ctx, t1, lsq_rt1);
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
-   ctx->default_tcg_memop_mask);
-tcg_temp_free(t1);
-break;
-#endif
-case OPC_GSSHFL:
-switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
-

[PATCH 14/26] target/mips: Extract NEC Vr54xx helper definitions

2020-11-20 Thread Philippe Mathieu-Daudé
Extract the NEC Vr54xx helper definitions to
'vendor-vr54xx_helper.h'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/helper.h   | 17 ++---
 target/mips/vendor-vr54xx_helper.h.inc | 24 
 2 files changed, 26 insertions(+), 15 deletions(-)
 create mode 100644 target/mips/vendor-vr54xx_helper.h.inc

diff --git a/target/mips/helper.h b/target/mips/helper.h
index ee93c2de836..77d66018c8c 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -20,21 +20,6 @@ DEF_HELPER_3(lld, tl, env, tl, int)
 #endif
 #endif
 
-DEF_HELPER_3(muls, tl, env, tl, tl)
-DEF_HELPER_3(mulsu, tl, env, tl, tl)
-DEF_HELPER_3(macc, tl, env, tl, tl)
-DEF_HELPER_3(maccu, tl, env, tl, tl)
-DEF_HELPER_3(msac, tl, env, tl, tl)
-DEF_HELPER_3(msacu, tl, env, tl, tl)
-DEF_HELPER_3(mulhi, tl, env, tl, tl)
-DEF_HELPER_3(mulhiu, tl, env, tl, tl)
-DEF_HELPER_3(mulshi, tl, env, tl, tl)
-DEF_HELPER_3(mulshiu, tl, env, tl, tl)
-DEF_HELPER_3(macchi, tl, env, tl, tl)
-DEF_HELPER_3(macchiu, tl, env, tl, tl)
-DEF_HELPER_3(msachi, tl, env, tl, tl)
-DEF_HELPER_3(msachiu, tl, env, tl, tl)
-
 DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 #ifdef TARGET_MIPS64
 DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl)
@@ -424,3 +409,5 @@ DEF_HELPER_3(cache, void, env, tl, i32)
 #include "mod-mips-dsp_helper.h.inc"
 #include "mod-mips-msa_helper.h.inc"
 #include "mod-mips-mt_helper.h.inc"
+
+#include "vendor-vr54xx_helper.h.inc"
diff --git a/target/mips/vendor-vr54xx_helper.h.inc 
b/target/mips/vendor-vr54xx_helper.h.inc
new file mode 100644
index 000..50b1f5b818d
--- /dev/null
+++ b/target/mips/vendor-vr54xx_helper.h.inc
@@ -0,0 +1,24 @@
+/*
+ * MIPS NEC Vr54xx instruction emulation helpers for QEMU.
+ *
+ *  Copyright (c) 2004-2005 Jocelyn Mayer
+ *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+DEF_HELPER_3(muls, tl, env, tl, tl)
+DEF_HELPER_3(mulsu, tl, env, tl, tl)
+DEF_HELPER_3(macc, tl, env, tl, tl)
+DEF_HELPER_3(maccu, tl, env, tl, tl)
+DEF_HELPER_3(msac, tl, env, tl, tl)
+DEF_HELPER_3(msacu, tl, env, tl, tl)
+DEF_HELPER_3(mulhi, tl, env, tl, tl)
+DEF_HELPER_3(mulhiu, tl, env, tl, tl)
+DEF_HELPER_3(mulshi, tl, env, tl, tl)
+DEF_HELPER_3(mulshiu, tl, env, tl, tl)
+DEF_HELPER_3(macchi, tl, env, tl, tl)
+DEF_HELPER_3(macchiu, tl, env, tl, tl)
+DEF_HELPER_3(msachi, tl, env, tl, tl)
+DEF_HELPER_3(msachiu, tl, env, tl, tl)
-- 
2.26.2




[PATCH 13/26] target/mips: Extract NEC Vr54xx helpers to vendor-vr54xx_helper.c

2020-11-20 Thread Philippe Mathieu-Daudé
Extract NEC Vr54xx helpers from op_helper.c to a new file:
'vendor-vr54xx_helper.c'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/op_helper.c| 118 --
 target/mips/vendor-vr54xx_helper.c | 131 +
 target/mips/meson.build|   1 +
 3 files changed, 132 insertions(+), 118 deletions(-)
 create mode 100644 target/mips/vendor-vr54xx_helper.c

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index dd09a4c714a..a900c008b5a 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -54,124 +54,6 @@ static void raise_exception(CPUMIPSState *env, uint32_t 
exception)
 do_raise_exception(env, exception, 0);
 }
 
-/* 64 bits arithmetic for 32 bits hosts */
-static inline uint64_t get_HILO(CPUMIPSState *env)
-{
-return ((uint64_t)(env->active_tc.HI[0]) << 32) |
-   (uint32_t)env->active_tc.LO[0];
-}
-
-static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO)
-{
-env->active_tc.LO[0] = (int32_t)(HILO & 0x);
-return env->active_tc.HI[0] = (int32_t)(HILO >> 32);
-}
-
-static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO)
-{
-target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0x);
-env->active_tc.HI[0] = (int32_t)(HILO >> 32);
-return tmp;
-}
-
-/* Multiplication variants of the vr54xx. */
-target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1,
- target_ulong arg2)
-{
-return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 *
- (int64_t)(int32_t)arg2));
-}
-
-target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1,
-  target_ulong arg2)
-{
-return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 *
-   (uint64_t)(uint32_t)arg2);
-}
-
-target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1,
- target_ulong arg2)
-{
-return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 *
-   (int64_t)(int32_t)arg2);
-}
-
-target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1,
-   target_ulong arg2)
-{
-return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 *
-   (int64_t)(int32_t)arg2);
-}
-
-target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1,
-  target_ulong arg2)
-{
-return set_HI_LOT0(env, (uint64_t)get_HILO(env) +
-   (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
-}
-
-target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1,
-target_ulong arg2)
-{
-return set_HIT0_LO(env, (uint64_t)get_HILO(env) +
-   (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
-}
-
-target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1,
- target_ulong arg2)
-{
-return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 *
-   (int64_t)(int32_t)arg2);
-}
-
-target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1,
-   target_ulong arg2)
-{
-return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 *
-   (int64_t)(int32_t)arg2);
-}
-
-target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1,
-  target_ulong arg2)
-{
-return set_HI_LOT0(env, (uint64_t)get_HILO(env) -
-   (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
-}
-
-target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1,
-target_ulong arg2)
-{
-return set_HIT0_LO(env, (uint64_t)get_HILO(env) -
-   (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
-}
-
-target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1,
-  target_ulong arg2)
-{
-return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
-}
-
-target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1,
-   target_ulong arg2)
-{
-return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 *
-   (uint64_t)(uint32_t)arg2);
-}
-
-target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1,
-   target_ulong arg2)
-{
-return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 *
-   (int64_t)(int32_t)arg2);
-}
-
-target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1,
-target_ulong arg2)
-{
-return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 *
-   (uint64_t)(uint32_t)arg2);
-}
-
 static inline target_ulong bitswap(target_ulong v)
 {
 v = ((v >> 1) & (target_ulong)0xULL) |
diff --git a/target/mips/vendor-vr54xx_helper.c 
b/target/mips/vendor-vr54xx_helper.c
new file mode 100644
index 

[PATCH 04/26] target/mips: Extract MSA translation routines

2020-11-20 Thread Philippe Mathieu-Daudé
Extract 2200 lines from the huge translate.c to a new file,
'mod-mips-msa_translate.c.inc'. As there are too many inter-
dependencies we don't compile it as another object, but
keep including it in the big translate.o. We gain in code
maintainability.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c  | 2209 +
 target/mips/mod-mips-msa_translate.c.inc | 2218 ++
 2 files changed, 2219 insertions(+), 2208 deletions(-)
 create mode 100644 target/mips/mod-mips-msa_translate.c.inc

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 5ec9fd7e92a..0ad59731810 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1211,239 +1211,6 @@ enum {
 OPC_NMSUB_PS= 0x3E | OPC_CP3,
 };
 
-/* MSA Opcodes */
-#define MASK_MSA_MINOR(op)  (MASK_OP_MAJOR(op) | (op & 0x3F))
-enum {
-OPC_MSA_I8_00   = 0x00 | OPC_MSA,
-OPC_MSA_I8_01   = 0x01 | OPC_MSA,
-OPC_MSA_I8_02   = 0x02 | OPC_MSA,
-OPC_MSA_I5_06   = 0x06 | OPC_MSA,
-OPC_MSA_I5_07   = 0x07 | OPC_MSA,
-OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
-OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
-OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
-OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
-OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
-OPC_MSA_3R_10   = 0x10 | OPC_MSA,
-OPC_MSA_3R_11   = 0x11 | OPC_MSA,
-OPC_MSA_3R_12   = 0x12 | OPC_MSA,
-OPC_MSA_3R_13   = 0x13 | OPC_MSA,
-OPC_MSA_3R_14   = 0x14 | OPC_MSA,
-OPC_MSA_3R_15   = 0x15 | OPC_MSA,
-OPC_MSA_ELM = 0x19 | OPC_MSA,
-OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
-OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
-OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
-OPC_MSA_VEC = 0x1E | OPC_MSA,
-
-/* MI10 instruction */
-OPC_LD_B= (0x20) | OPC_MSA,
-OPC_LD_H= (0x21) | OPC_MSA,
-OPC_LD_W= (0x22) | OPC_MSA,
-OPC_LD_D= (0x23) | OPC_MSA,
-OPC_ST_B= (0x24) | OPC_MSA,
-OPC_ST_H= (0x25) | OPC_MSA,
-OPC_ST_W= (0x26) | OPC_MSA,
-OPC_ST_D= (0x27) | OPC_MSA,
-};
-
-enum {
-/* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
-OPC_ADDVI_df= (0x0 << 23) | OPC_MSA_I5_06,
-OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
-OPC_SUBVI_df= (0x1 << 23) | OPC_MSA_I5_06,
-OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
-OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
-OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
-OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
-OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
-OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
-OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
-OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
-OPC_LDI_df  = (0x6 << 23) | OPC_MSA_I5_07,
-
-/* I8 instruction */
-OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
-OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
-OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
-OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
-OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
-OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
-OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
-OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
-OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
-OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
-
-/* VEC/2R/2RF instruction */
-OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
-OPC_OR_V= (0x01 << 21) | OPC_MSA_VEC,
-OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
-OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
-OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
-OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
-OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
-
-OPC_MSA_2R  = (0x18 << 21) | OPC_MSA_VEC,
-OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
-
-/* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
-OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
-OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
-OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
-OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
-
-/* 2RF instruction df(bit 16) = _w, _d */
-OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
-OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
-OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
-OPC_FSQRT_df= (0x03 << 17) | OPC_MSA_2RF,
-OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
-OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
-OPC_FRINT_df= (0x06 << 17) | OPC_MSA_2RF,
-OPC_FLOG2_df= (0x07 << 17) | OPC_MSA_2RF,
-OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
-OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
-OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
-OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
-OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
-OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
-OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
-OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
-
-/* 3R instruction df(bits 22..21) = _b, _h, _w, d */
- 

[PATCH 08/26] target/mips: Extract Multi-Threading helper definitions

2020-11-20 Thread Philippe Mathieu-Daudé
'MIPS MT' is defined as a Module by MIPS. Extract the helper
definitions to 'mod-mips-mt_helper.h.inc'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/helper.h | 24 +--
 target/mips/mod-mips-mt_helper.h.inc | 36 
 2 files changed, 37 insertions(+), 23 deletions(-)
 create mode 100644 target/mips/mod-mips-mt_helper.h.inc

diff --git a/target/mips/helper.h b/target/mips/helper.h
index bce869f3718..c15caed9fca 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -179,25 +179,6 @@ DEF_HELPER_2(dmtc0_entrylo0, void, env, i64)
 DEF_HELPER_2(dmtc0_entrylo1, void, env, i64)
 #endif
 
-/* MIPS MT functions */
-DEF_HELPER_2(mftgpr, tl, env, i32)
-DEF_HELPER_2(mftlo, tl, env, i32)
-DEF_HELPER_2(mfthi, tl, env, i32)
-DEF_HELPER_2(mftacx, tl, env, i32)
-DEF_HELPER_1(mftdsp, tl, env)
-DEF_HELPER_3(mttgpr, void, env, tl, i32)
-DEF_HELPER_3(mttlo, void, env, tl, i32)
-DEF_HELPER_3(mtthi, void, env, tl, i32)
-DEF_HELPER_3(mttacx, void, env, tl, i32)
-DEF_HELPER_2(mttdsp, void, env, tl)
-DEF_HELPER_0(dmt, tl)
-DEF_HELPER_0(emt, tl)
-DEF_HELPER_1(dvpe, tl, env)
-DEF_HELPER_1(evpe, tl, env)
-
-/* R6 Multi-threading */
-DEF_HELPER_1(dvp, tl, env)
-DEF_HELPER_1(evp, tl, env)
 #endif /* !CONFIG_USER_ONLY */
 
 /* microMIPS functions */
@@ -208,9 +189,6 @@ DEF_HELPER_4(ldm, void, env, tl, tl, i32)
 DEF_HELPER_4(sdm, void, env, tl, tl, i32)
 #endif
 
-DEF_HELPER_2(fork, void, tl, tl)
-DEF_HELPER_2(yield, tl, env, tl)
-
 /* CP1 functions */
 DEF_HELPER_2(cfc1, tl, env, i32)
 DEF_HELPER_4(ctc1, void, env, tl, i32, i32)
@@ -451,4 +429,4 @@ DEF_HELPER_3(cache, void, env, tl, i32)
 
 #include "mod-mips-dsp_helper.h.inc"
 #include "mod-mips-msa_helper.h.inc"
-
+#include "mod-mips-mt_helper.h.inc"
diff --git a/target/mips/mod-mips-mt_helper.h.inc 
b/target/mips/mod-mips-mt_helper.h.inc
new file mode 100644
index 000..0db58e2a780
--- /dev/null
+++ b/target/mips/mod-mips-mt_helper.h.inc
@@ -0,0 +1,36 @@
+/*
+ * MIPS Multi-Threading helpers for QEMU.
+ *
+ *  Copyright (c) 2004-2005 Jocelyn Mayer
+ *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef CONFIG_USER_ONLY
+DEF_HELPER_2(mftgpr, tl, env, i32)
+DEF_HELPER_2(mftlo, tl, env, i32)
+DEF_HELPER_2(mfthi, tl, env, i32)
+DEF_HELPER_2(mftacx, tl, env, i32)
+DEF_HELPER_1(mftdsp, tl, env)
+DEF_HELPER_3(mttgpr, void, env, tl, i32)
+DEF_HELPER_3(mttlo, void, env, tl, i32)
+DEF_HELPER_3(mtthi, void, env, tl, i32)
+DEF_HELPER_3(mttacx, void, env, tl, i32)
+DEF_HELPER_2(mttdsp, void, env, tl)
+
+DEF_HELPER_0(dmt, tl)
+DEF_HELPER_0(emt, tl)
+
+DEF_HELPER_1(dvpe, tl, env)
+DEF_HELPER_1(evpe, tl, env)
+
+/* R6 Multi-threading */
+DEF_HELPER_1(dvp, tl, env)
+DEF_HELPER_1(evp, tl, env)
+#endif /* !CONFIG_USER_ONLY */
+
+DEF_HELPER_2(fork, void, tl, tl)
+DEF_HELPER_2(yield, tl, env, tl)
-- 
2.26.2




[PATCH 09/26] target/mips: Extract Code Compaction ASE translation routines

2020-11-20 Thread Philippe Mathieu-Daudé
Extract 1200 lines from the huge translate.c to a new file,
'ase-mips16e_translate.c.inc'. As there are too many inter-
dependencies we don't compile it as another object, but
keep including it in the big translate.o. We gain in code
maintainability.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 1161 +-
 target/mips/ase-mips16e_translate.c.inc | 1170 +++
 2 files changed, 1171 insertions(+), 1160 deletions(-)
 create mode 100644 target/mips/ase-mips16e_translate.c.inc

diff --git a/target/mips/translate.c b/target/mips/translate.c
index bc581a7a7a7..bae2064e7fa 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -13131,1167 +13131,8 @@ out:
 }
 
 /* ISA extensions (ASEs) */
-/* MIPS16 extension to MIPS32 */
 
-/* MIPS16 major opcodes */
-enum {
-  M16_OPC_ADDIUSP = 0x00,
-  M16_OPC_ADDIUPC = 0x01,
-  M16_OPC_B = 0x02,
-  M16_OPC_JAL = 0x03,
-  M16_OPC_BEQZ = 0x04,
-  M16_OPC_BNEQZ = 0x05,
-  M16_OPC_SHIFT = 0x06,
-  M16_OPC_LD = 0x07,
-  M16_OPC_RRIA = 0x08,
-  M16_OPC_ADDIU8 = 0x09,
-  M16_OPC_SLTI = 0x0a,
-  M16_OPC_SLTIU = 0x0b,
-  M16_OPC_I8 = 0x0c,
-  M16_OPC_LI = 0x0d,
-  M16_OPC_CMPI = 0x0e,
-  M16_OPC_SD = 0x0f,
-  M16_OPC_LB = 0x10,
-  M16_OPC_LH = 0x11,
-  M16_OPC_LWSP = 0x12,
-  M16_OPC_LW = 0x13,
-  M16_OPC_LBU = 0x14,
-  M16_OPC_LHU = 0x15,
-  M16_OPC_LWPC = 0x16,
-  M16_OPC_LWU = 0x17,
-  M16_OPC_SB = 0x18,
-  M16_OPC_SH = 0x19,
-  M16_OPC_SWSP = 0x1a,
-  M16_OPC_SW = 0x1b,
-  M16_OPC_RRR = 0x1c,
-  M16_OPC_RR = 0x1d,
-  M16_OPC_EXTEND = 0x1e,
-  M16_OPC_I64 = 0x1f
-};
-
-/* I8 funct field */
-enum {
-  I8_BTEQZ = 0x0,
-  I8_BTNEZ = 0x1,
-  I8_SWRASP = 0x2,
-  I8_ADJSP = 0x3,
-  I8_SVRS = 0x4,
-  I8_MOV32R = 0x5,
-  I8_MOVR32 = 0x7
-};
-
-/* RRR f field */
-enum {
-  RRR_DADDU = 0x0,
-  RRR_ADDU = 0x1,
-  RRR_DSUBU = 0x2,
-  RRR_SUBU = 0x3
-};
-
-/* RR funct field */
-enum {
-  RR_JR = 0x00,
-  RR_SDBBP = 0x01,
-  RR_SLT = 0x02,
-  RR_SLTU = 0x03,
-  RR_SLLV = 0x04,
-  RR_BREAK = 0x05,
-  RR_SRLV = 0x06,
-  RR_SRAV = 0x07,
-  RR_DSRL = 0x08,
-  RR_CMP = 0x0a,
-  RR_NEG = 0x0b,
-  RR_AND = 0x0c,
-  RR_OR = 0x0d,
-  RR_XOR = 0x0e,
-  RR_NOT = 0x0f,
-  RR_MFHI = 0x10,
-  RR_CNVT = 0x11,
-  RR_MFLO = 0x12,
-  RR_DSRA = 0x13,
-  RR_DSLLV = 0x14,
-  RR_DSRLV = 0x16,
-  RR_DSRAV = 0x17,
-  RR_MULT = 0x18,
-  RR_MULTU = 0x19,
-  RR_DIV = 0x1a,
-  RR_DIVU = 0x1b,
-  RR_DMULT = 0x1c,
-  RR_DMULTU = 0x1d,
-  RR_DDIV = 0x1e,
-  RR_DDIVU = 0x1f
-};
-
-/* I64 funct field */
-enum {
-  I64_LDSP = 0x0,
-  I64_SDSP = 0x1,
-  I64_SDRASP = 0x2,
-  I64_DADJSP = 0x3,
-  I64_LDPC = 0x4,
-  I64_DADDIU5 = 0x5,
-  I64_DADDIUPC = 0x6,
-  I64_DADDIUSP = 0x7
-};
-
-/* RR ry field for CNVT */
-enum {
-  RR_RY_CNVT_ZEB = 0x0,
-  RR_RY_CNVT_ZEH = 0x1,
-  RR_RY_CNVT_ZEW = 0x2,
-  RR_RY_CNVT_SEB = 0x4,
-  RR_RY_CNVT_SEH = 0x5,
-  RR_RY_CNVT_SEW = 0x6,
-};
-
-static int xlat(int r)
-{
-  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
-
-  return map[r];
-}
-
-static void gen_mips16_save(DisasContext *ctx,
-int xsregs, int aregs,
-int do_ra, int do_s0, int do_s1,
-int framesize)
-{
-TCGv t0 = tcg_temp_new();
-TCGv t1 = tcg_temp_new();
-TCGv t2 = tcg_temp_new();
-int args, astatic;
-
-switch (aregs) {
-case 0:
-case 1:
-case 2:
-case 3:
-case 11:
-args = 0;
-break;
-case 4:
-case 5:
-case 6:
-case 7:
-args = 1;
-break;
-case 8:
-case 9:
-case 10:
-args = 2;
-break;
-case 12:
-case 13:
-args = 3;
-break;
-case 14:
-args = 4;
-break;
-default:
-generate_exception_end(ctx, EXCP_RI);
-return;
-}
-
-switch (args) {
-case 4:
-gen_base_offset_addr(ctx, t0, 29, 12);
-gen_load_gpr(t1, 7);
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
-/* Fall through */
-case 3:
-gen_base_offset_addr(ctx, t0, 29, 8);
-gen_load_gpr(t1, 6);
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
-/* Fall through */
-case 2:
-gen_base_offset_addr(ctx, t0, 29, 4);
-gen_load_gpr(t1, 5);
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
-/* Fall through */
-case 1:
-gen_base_offset_addr(ctx, t0, 29, 0);
-gen_load_gpr(t1, 4);
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
-}
-
-gen_load_gpr(t0, 29);
-
-#define DECR_AND_STORE(reg) do { \
-tcg_gen_movi_tl(t2, -4); \
-gen_op_addr_add(ctx, t0, t0, t2);\
-gen_load_gpr(t1, reg);   \
-tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
-} while (0)
-
-if (do_ra) {
-DECR_AND_STORE(31);
-}
-
-switch (xsregs) {
-case 7:
- 

[PATCH 02/26] target/mips: Extract MSA helpers to mod-mips-msa_helper.c

2020-11-20 Thread Philippe Mathieu-Daudé
MSA means 'MIPS SIMD Architecture' and is defined as a Module by MIPS.
Rename msa_helper.c as mod-mips-msa_helper.c, merge other MSA helpers
from op_helper.c.

Signed-off-by: Philippe Mathieu-Daudé 
---
 .../{msa_helper.c => mod-mips-msa_helper.c}   | 392 +
 target/mips/op_helper.c   | 393 --
 target/mips/meson.build   |   3 +-
 3 files changed, 394 insertions(+), 394 deletions(-)
 rename target/mips/{msa_helper.c => mod-mips-msa_helper.c} (94%)

diff --git a/target/mips/msa_helper.c b/target/mips/mod-mips-msa_helper.c
similarity index 94%
rename from target/mips/msa_helper.c
rename to target/mips/mod-mips-msa_helper.c
index b89b4c44902..56fca86a242 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/mod-mips-msa_helper.c
@@ -8201,3 +8201,395 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 
 msa_move_v(pwd, pwx);
 }
+
+/* Data format min and max values */
+#define DF_BITS(df) (1 << ((df) + 3))
+
+/* Element-by-element access macros */
+#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
+
+#if !defined(CONFIG_USER_ONLY)
+#define MEMOP_IDX(DF)   \
+TCGMemOpIdx oi = make_memop_idx(MO_TE | DF | MO_UNALN,  \
+cpu_mmu_index(env, false));
+#else
+#define MEMOP_IDX(DF)
+#endif
+
+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  << DF_BYTE));
+pwd->b[8]  = cpu_ldub_data(env, addr + (8  << DF_BYTE));
+pwd->b[9]  = cpu_ldub_data(env, addr + (9  << DF_BYTE));
+pwd->b[10] = cpu_ldub_data(env, addr + (10 << DF_BYTE));
+pwd->b[11] = cpu_ldub_data(env, addr 

[PATCH 03/26] target/mips: Extract MSA helper definitions

2020-11-20 Thread Philippe Mathieu-Daudé
Keep all MSA-related code altogether.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/helper.h  | 437 +
 target/mips/mod-mips-msa_helper.h.inc | 443 ++
 2 files changed, 446 insertions(+), 434 deletions(-)
 create mode 100644 target/mips/mod-mips-msa_helper.h.inc

diff --git a/target/mips/helper.h b/target/mips/helper.h
index e97655dc0eb..a44f42c6201 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -781,438 +781,7 @@ DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env)
 DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env)
 DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env)
 
-/* MIPS SIMD Architecture */
-
-DEF_HELPER_3(msa_nloc_b, void, env, i32, i32)
-DEF_HELPER_3(msa_nloc_h, void, env, i32, i32)
-DEF_HELPER_3(msa_nloc_w, void, env, i32, i32)
-DEF_HELPER_3(msa_nloc_d, void, env, i32, i32)
-
-DEF_HELPER_3(msa_nlzc_b, void, env, i32, i32)
-DEF_HELPER_3(msa_nlzc_h, void, env, i32, i32)
-DEF_HELPER_3(msa_nlzc_w, void, env, i32, i32)
-DEF_HELPER_3(msa_nlzc_d, void, env, i32, i32)
-
-DEF_HELPER_3(msa_pcnt_b, void, env, i32, i32)
-DEF_HELPER_3(msa_pcnt_h, void, env, i32, i32)
-DEF_HELPER_3(msa_pcnt_w, void, env, i32, i32)
-DEF_HELPER_3(msa_pcnt_d, void, env, i32, i32)
-
-DEF_HELPER_4(msa_binsl_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsl_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsl_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsl_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_binsr_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsr_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsr_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsr_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_bclr_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bclr_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bclr_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bclr_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_bneg_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bneg_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bneg_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bneg_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_bset_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_add_a_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_add_a_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_add_a_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_add_a_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_adds_a_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_a_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_a_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_a_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_adds_s_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_s_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_s_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_s_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_adds_u_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_u_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_u_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_u_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_addv_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_addv_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_addv_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_addv_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_hadd_s_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_hadd_s_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_hadd_s_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_hadd_u_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_hadd_u_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_hadd_u_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_s_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_ave_u_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_u_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_u_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_u_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_aver_s_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_s_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_s_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_s_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_aver_u_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_u_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_u_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_u_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_ceq_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ceq_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ceq_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ceq_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_cle_s_b, void, env, i32, i32, i32)

[PATCH 01/26] target/mips: Extract FPU helpers to 'fpu_helper.h'

2020-11-20 Thread Philippe Mathieu-Daudé
Extract FPU specific helpers from "internal.h" to "fpu_helper.h".

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/fpu_helper.h   | 50 ++
 target/mips/internal.h | 42 
 linux-user/mips/cpu_loop.c |  1 +
 target/mips/fpu_helper.c   |  1 +
 target/mips/gdbstub.c  |  1 +
 target/mips/kvm.c  |  1 +
 target/mips/machine.c  |  1 +
 target/mips/msa_helper.c   |  1 +
 target/mips/translate.c|  1 +
 9 files changed, 57 insertions(+), 42 deletions(-)
 create mode 100644 target/mips/fpu_helper.h

diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
new file mode 100644
index 000..83c698d583f
--- /dev/null
+++ b/target/mips/fpu_helper.h
@@ -0,0 +1,50 @@
+/*
+ *  Helpers for emulation of FPU-related MIPS instructions.
+ *
+ *  Copyright (C) 2004-2005  Jocelyn Mayer
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+#include "fpu/softfloat-helpers.h"
+#include "cpu.h"
+
+extern unsigned int ieee_rm[];
+
+uint32_t float_class_s(uint32_t arg, float_status *fst);
+uint64_t float_class_d(uint64_t arg, float_status *fst);
+
+static inline void restore_rounding_mode(CPUMIPSState *env)
+{
+set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3],
+>active_fpu.fp_status);
+}
+
+static inline void restore_flush_mode(CPUMIPSState *env)
+{
+set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) != 0,
+  >active_fpu.fp_status);
+}
+
+static inline void restore_snan_bit_mode(CPUMIPSState *env)
+{
+set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == 0,
+>active_fpu.fp_status);
+}
+
+static inline void restore_fp_status(CPUMIPSState *env)
+{
+restore_rounding_mode(env);
+restore_flush_mode(env);
+restore_snan_bit_mode(env);
+}
+
+static inline void restore_msa_fp_status(CPUMIPSState *env)
+{
+float_status *status = >active_tc.msa_fp_status;
+int rounding_mode = (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM;
+bool flush_to_zero = (env->active_tc.msacsr & MSACSR_FS_MASK) != 0;
+
+set_float_rounding_mode(ieee_rm[rounding_mode], status);
+set_flush_to_zero(flush_to_zero, status);
+set_flush_inputs_to_zero(flush_to_zero, status);
+}
diff --git a/target/mips/internal.h b/target/mips/internal.h
index dd8a7809b64..7bea3af0b29 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -8,8 +8,6 @@
 #ifndef MIPS_INTERNAL_H
 #define MIPS_INTERNAL_H
 
-#include "fpu/softfloat-helpers.h"
-
 /*
  * MMU types, the first four entries have the same layout as the
  * CP0C0_MT field.
@@ -222,48 +220,8 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
bool probe, uintptr_t retaddr);
 
 /* op_helper.c */
-uint32_t float_class_s(uint32_t arg, float_status *fst);
-uint64_t float_class_d(uint64_t arg, float_status *fst);
-
-extern unsigned int ieee_rm[];
 void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask);
 
-static inline void restore_rounding_mode(CPUMIPSState *env)
-{
-set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3],
->active_fpu.fp_status);
-}
-
-static inline void restore_flush_mode(CPUMIPSState *env)
-{
-set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) != 0,
-  >active_fpu.fp_status);
-}
-
-static inline void restore_snan_bit_mode(CPUMIPSState *env)
-{
-set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == 0,
->active_fpu.fp_status);
-}
-
-static inline void restore_fp_status(CPUMIPSState *env)
-{
-restore_rounding_mode(env);
-restore_flush_mode(env);
-restore_snan_bit_mode(env);
-}
-
-static inline void restore_msa_fp_status(CPUMIPSState *env)
-{
-float_status *status = >active_tc.msa_fp_status;
-int rounding_mode = (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM;
-bool flush_to_zero = (env->active_tc.msacsr & MSACSR_FS_MASK) != 0;
-
-set_float_rounding_mode(ieee_rm[rounding_mode], status);
-set_flush_to_zero(flush_to_zero, status);
-set_flush_inputs_to_zero(flush_to_zero, status);
-}
-
 static inline void restore_pamask(CPUMIPSState *env)
 {
 if (env->hflags & MIPS_HFLAG_ELPA) {
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index cfe7ba5c47d..b58dbeb83d1 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -23,6 +23,7 @@
 #include "cpu_loop-common.h"
 #include "elf.h"
 #include "internal.h"
+#include "fpu_helper.h"
 
 # ifdef TARGET_ABI_MIPSO32
 #  define MIPS_SYSCALL_NUMBER_UNUSED -1
diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 020b768e87b..a74dc18d746 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -31,6 +31,7 @@
 #include "exec/memop.h"
 #include "sysemu/kvm.h"
 #include "fpu/softfloat.h"
+#include "fpu_helper.h"
 
 
 /* Complex FPU 

[PATCH 00/26] target/mips: Explode 60% of the 32K-lines translate.c

2020-11-20 Thread Philippe Mathieu-Daudé
Hi,

This series, while boring, helps maintainability.

I simply exploded 60% of the huge target/mips/translate.c,
reducing it from 32K lines of code to 13500.

The small overhead in the diffstat is due to entries added in
MAINTAINERS and license boilerplate addition:
20225 insertions(+), 19987 deletions(-)

While being a massive diff, it is a no-brain review using
'git-diff --color-moved=dimmed-zebra' which highlights very few
changes: #include and license lines.

The exploded new layout, which allows more useful filtering
with the get_maintainer.pl script, is:

- MIPS ISA, ASE and modules:

 . isa-micromips_helper.h.inc
 . isa-nanomips_translate.c.inc

 . ase-mips16e_translate.c.inc

 . mod-mips-dsp_helper.c
 . mod-mips-dsp_helper.h.inc
 . mod-mips-dsp_translate.c.inc
 . mod-mips-msa_helper.h.inc
 . mod-mips-msa_translate.c.inc
 . mod-mips-msa_helper.c
 . mod-mips-mt_helper.h.inc

- MIPS Vendor Specific:

 . vendor-loong-simd_helper.c
 . vendor-loong-lext_translate.c.inc
 . vendor-loong-simd_helper.h.inc
 . vendor-loong-simd_translate.c.inc

 . vendor-tx-mmi_translate.c.inc
 . vendor-tx_translate.c.inc

 . vendor-vr54xx_helper.c
 . vendor-vr54xx_helper.h.inc
 . vendor-vr54xx_translate.c.inc

 . vendor-xburst_translate.c.inc

There should be no logical code change (only code movement).

The series is available at:

  https://gitlab.com/philmd/qemu.git branches/mips_translate_explode

Regards,

Phil.

Philippe Mathieu-Daudé (26):
  target/mips: Extract FPU helpers to 'fpu_helper.h'
  target/mips: Extract MSA helpers to mod-mips-msa_helper.c
  target/mips: Extract MSA helper definitions
  target/mips: Extract MSA translation routines
  target/mips: Rename dsp_helper.c as mod-mips-dsp_helper.c
  target/mips: Extract DSP helper definitions
  target/mips: Extract DSP translation routines
  target/mips: Extract Multi-Threading helper definitions
  target/mips: Extract Code Compaction ASE translation routines
  target/mips: Extract the microMIPS ISA helper definitions
  target/mips: Extract the microMIPS ISA translation routines
  target/mips: Extract nanoMIPS ISA translation routines
  target/mips: Extract NEC Vr54xx helpers to vendor-vr54xx_helper.c
  target/mips: Extract NEC Vr54xx helper definitions
  target/mips: Extract NEC Vr54xx translation routines
  target/mips: Rename lmmi_helper.c as loong-simd_helper.c
  target/mips: Extract Loongson SIMD helper definitions
  target/mips: Extract Loongson SIMD translation routines
  target/mips: Extract Loongson EXTensions translation routines
  target/mips: Extract XBurst Media eXtension Unit translation routines
  target/mips: Make pipeline 1 multiply opcodes generic
  target/mips: Extract Toshiba TXx9 translation routines
  target/mips: Extract Toshiba TX79 multimedia translation routines
  MAINTAINERS: Add entry for MIPS Loongson TCG
  MAINTAINERS: Add entry for MIPS Ingenic Xburst TCG
  MAINTAINERS: Add entry for MIPS Toshiba TCG

 target/mips/fpu_helper.h  |50 +
 target/mips/helper.h  |   881 +-
 target/mips/internal.h|42 -
 linux-user/mips/cpu_loop.c| 1 +
 target/mips/fpu_helper.c  | 1 +
 target/mips/gdbstub.c | 1 +
 target/mips/kvm.c | 1 +
 target/mips/machine.c | 1 +
 .../{dsp_helper.c => mod-mips-dsp_helper.c}   | 2 +
 .../{msa_helper.c => mod-mips-msa_helper.c}   |   393 +
 target/mips/op_helper.c   |   511 -
 target/mips/translate.c   | 18598 +---
 ...mi_helper.c => vendor-loong-simd_helper.c} | 0
 target/mips/vendor-vr54xx_helper.c|   131 +
 MAINTAINERS   |20 +
 target/mips/ase-mips16e_translate.c.inc   |  1170 +
 target/mips/isa-micromips_helper.h.inc|17 +
 target/mips/isa-micromips_translate.c.inc |  3316 +++
 target/mips/isa-nanomips_translate.c.inc  |  4839 
 target/mips/meson.build   | 8 +-
 target/mips/mod-mips-dsp_helper.h.inc |   344 +
 target/mips/mod-mips-dsp_translate.c.inc  |  2158 ++
 target/mips/mod-mips-msa_helper.h.inc |   443 +
 target/mips/mod-mips-msa_translate.c.inc  |  2218 ++
 target/mips/mod-mips-mt_helper.h.inc  |36 +
 target/mips/vendor-loong-lext_translate.c.inc |   450 +
 target/mips/vendor-loong-simd_helper.h.inc|69 +
 target/mips/vendor-loong-simd_translate.c.inc |   611 +
 target/mips/vendor-tx-mmi_translate.c.inc |   573 +
 target/mips/vendor-tx_translate.c.inc |   317 +
 target/mips/vendor-vr54xx_helper.h.inc|24 +
 target/mips/vendor-vr54xx_translate.c.inc |93 +
 target/mips/vendor-xburst_translate.c.inc |  2893 +++
 33 files changed, 20225 insertions(+), 19987 deletions(-)
 create mode 100644 target/mips/fpu_helper.h
 rename target/mips/{dsp_helper.c => mod-mips-dsp_helper.c} 

Re: [PATCH v1 1/6] scripts/ci: clean up default args logic a little

2020-11-20 Thread Wainer dos Santos Moschetta



On 11/17/20 2:36 PM, Alex Bennée wrote:

This allows us to do:

   ./scripts/ci/gitlab-pipeline-status -w -b HEAD -p 2961854

to check out own pipeline status of a recently pushed branch.

Signed-off-by: Alex Bennée 
---
  scripts/ci/gitlab-pipeline-status | 24 +---
  1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/scripts/ci/gitlab-pipeline-status 
b/scripts/ci/gitlab-pipeline-status
index bac8233079..78e72f6008 100755
--- a/scripts/ci/gitlab-pipeline-status
+++ b/scripts/ci/gitlab-pipeline-status
@@ -31,7 +31,7 @@ class NoPipelineFound(Exception):
  """Communication is successfull but pipeline is not found."""
  
  
-def get_local_branch_commit(branch='staging'):

+def get_local_branch_commit(branch):
  """
  Returns the commit sha1 for the *local* branch named "staging"



Need to reword the method's docstring.

Otherwise,

Reviewed-by: Wainer dos Santos Moschetta 



  """
@@ -126,18 +126,16 @@ def create_parser():
  help=('The GitLab project ID. Defaults to the project 
'
'for https://gitlab.com/qemu-project/qemu, that 
'
'is, "%(default)s"'))
-try:
-default_commit = get_local_branch_commit()
-commit_required = False
-except ValueError:
-default_commit = ''
-commit_required = True
-parser.add_argument('-c', '--commit', required=commit_required,
-default=default_commit,
+parser.add_argument('-b', '--branch', type=str, default="staging",
+help=('Specify the branch to check. '
+  'Use HEAD for your current branch. '
+  'Otherwise looks at "%(default)s"'))
+parser.add_argument('-c', '--commit',
+default=None,
  help=('Look for a pipeline associated with the given '
'commit.  If one is not explicitly given, the '
-  'commit associated with the local branch named '
-  '"staging" is used.  Default: %(default)s'))
+  'commit associated with the default branch '
+  'is used.'))
  parser.add_argument('--verbose', action='store_true', default=False,
  help=('A minimal verbosity level that prints the '
'overall result of the check/wait'))
@@ -149,6 +147,10 @@ def main():
  """
  parser = create_parser()
  args = parser.parse_args()
+
+if not args.commit:
+args.commit = get_local_branch_commit(args.branch)
+
  success = False
  try:
  if args.wait:





Re: [PULL 0/4] docs + qtest patches

2020-11-20 Thread Peter Maydell
On Fri, 20 Nov 2020 at 17:18, Thomas Huth  wrote:
>
>  Hi Peter,
>
> the following changes since commit 7fbd7e710323c8f4c5f6a38a8ae0e6726b5a4599:
>
>   Merge remote-tracking branch 
> 'remotes/stefanha-gitlab/tags/tracing-pull-request' into staging (2020-11-19 
> 17:08:42 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/huth/qemu.git tags/pull-request-2020-11-20
>
> for you to fetch changes up to 88a8b27e556f5cb49a19d4c98a96590f61b74ed2:
>
>   qtest: do not return freed argument vector from qtest_rsp (2020-11-20 
> 15:04:16 +0100)
>
> gitlab-CI run: https://gitlab.com/huth/qemu/-/pipelines/219170774
>
> 
> * Some small qtest fixes
> * One documentation update



Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.2
for any user-visible changes.

-- PMM



[Bug 1674925] Re: Qemu PPC64 kvm no display if --device virtio-gpu-pci is selected

2020-11-20 Thread Thomas Huth
The QEMU project is currently considering to move its bug tracking to another 
system. For this we need to know which bugs are still valid and which could be 
closed already. Thus we are setting older bugs to "Incomplete" now.
If you still think this bug report here is valid, then please switch the state 
back to "New" within the next 60 days, otherwise this report will be marked as 
"Expired". Or mark it as "Fix Released" if the problem has been solved with a 
newer version of QEMU already. Thank you and sorry for the inconvenience.

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

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

Title:
  Qemu PPC64 kvm no display if  --device virtio-gpu-pci is selected

Status in QEMU:
  Incomplete

Bug description:
  Hi,
  i did many tests on qemu 2.8 on my BE machines and i found an issue that i 
think was need to be reported

  Test Machines BE 970MP

  if i setup qemu with

  qemu-system-ppc64 -M 1024 --display sdl(or gtk),gl=on --device virtio-
  gpu-pci,virgl --enable-kvm and so and so

  result is doubled window one is vga other is virtio-gpu-pci without
  any start of the VM . pratically i dont have any output of openbios
  and on the virtual serial output

  the same issue i found is if i select:
  qemu-system-ppc64 -M 1024 --display gtk(or sdl) --device virtio-gpu-pci 
--enable-kvm and so and so

  
  i had been try to change all the -M types of all kind of pseries without any 
positive result.

  Ciao 
  Luigi

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



[Bug 1619991] Re: Concurrent VMs crash w/ GPU passthrough and multiple disks

2020-11-20 Thread Thomas Huth
The QEMU project is currently considering to move its bug tracking to another 
system. For this we need to know which bugs are still valid and which could be 
closed already. Thus we are setting older bugs to "Incomplete" now.
If you still think this bug report here is valid, then please switch the state 
back to "New" within the next 60 days, otherwise this report will be marked as 
"Expired". Or mark it as "Fix Released" if the problem has been solved with a 
newer version of QEMU already. Thank you and sorry for the inconvenience.

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

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

Title:
  Concurrent VMs crash w/ GPU passthrough and multiple disks

Status in QEMU:
  Incomplete

Bug description:
  When running multiple VMs with GPU passthrugh, both VMs will crash
  unless all virtual disks are on the same physical volume as root,
  likely on all X58 chipset motherboards.  I've tested with 3.

  Expected Behavior:  No Crash
  Result:  Both VMs GPU drivers fail and the guest OS are unrecoverable, 
usually within seconds, though the degree of "fickleness" of it depends on the 
multidisk setup.
  Reproducibility:  100%

  Steps to reproduce:

  *  Install OS (In my case Debian Jessie/Proxmox), and update to latest
  *  Setup VMs
  *  Setup up GPU passthrough with 1 GPU per VM, and one for host, as per 
https://pve.proxmox.com/wiki/Pci_passthrough
  *  Setup up USB passthrough
  *  Launch both VM
  *  Observe "everything is working"
  *  Stop VMs
  *  Add a second disk to one of the VMs, which exists on a separate physical 
disk from Host OS /
  *  Observe both VMs crash when the virtual disk which exists on separate 
physical media is used (i.e. copy files to the disk)
  *  Stop VMs
  *  Remove new disk, and move Guest OS virtual root disk to separate physical 
media.
  *  Observe both VMs crash around the time GPU driver is loaded on one

  As I mentioned earlier, there is some degree of difference in how
  difficult it is to trigger a crash, depending on the multidisk setup.
  For instance, when / is ZFS, and the virtual disks exist on a separate
  ZFS raid-z volume, both VMs must be doing some relatively intensive HW
  3d acceleration in order to trigger the crash.

  Passing two GPU to one VM works fine all the time, and running either
  VM on its in general will not trigger a crash.

  There are many variables I have yet to test, such as using sata
  instead of virtio for the virtual disks, however unfortunately I do
  not have anything from std err or logs to indicate what the problem
  could be.

  kernel verion:  Linux test-ve 4.4.15-1-pve  (other versions >= 4.2.1 and <= 
4.7.? tested)
  qemu version:  2.6.0 pve-qemu-kvm_2.6-1
  motherboards tested:  rampage iii, ga-ex58-ud5, asus Psomething
  CPUs tested:  i7 920, X5670

  KVM invocation 1:

  /usr/bin/kvm \
  -id 101 \
  -chardev socket,id=qmp,path=/var/run/qemu-server/101.qmp,server,nowait \
  -mon chardev=qmp,mode=control \
  -pidfile /var/run/qemu-server/101.pid \
  -daemonize \
  -smbios type=1,uuid=450e337e-244c-429b-9aa8-afb7aee037e8 \
  -drive if=pflash,format=raw,readonly,file=/usr/share/kvm/OVMF-pure-efi.fd \
  -drive if=pflash,format=raw,file=/root/101-OVMF_VARS-pure-efi.fd \
  -name Madzia-PC \
  -smp 12,sockets=1,cores=12,maxcpus=12 \
  -nodefaults \
  -boot menu=on,strict=on,reboot-timeout=1000 \
  -vga none \
  -nographic \
  -no-hpet \
  -cpu 
host,hv_vendor_id=Nvidia43FIX,hv_spinlocks=0x1fff,hv_vapic,hv_time,hv_reset,hv_vpindex,hv_runtime,hv_relaxed,+kvm_pv_unhalt,+kvm_pv_eoi,kvm=off
 \
  -m 8192 \
  -object memory-backend-ram,id=ram-node0,size=8192M \
  -numa node,nodeid=0,cpus=0-11,memdev=ram-node0 \
  -k en-us -readconfig /usr/share/qemu-server/pve-q35.cfg \
  -device usb-tablet,id=tablet,bus=ehci.0,port=1 \
  -device vfio-pci,host=04:00.0,id=hostpci0,bus=ich9-pcie-port-1,addr=0x0 \
  -device vfio-pci,host=04:00.1,id=hostpci1,bus=ich9-pcie-port-2,addr=0x0 \
  -device usb-host,hostbus=1,hostport=6.1,id=usb0 \
  -device usb-host,hostbus=1,hostport=6.2.1,id=usb1 \
  -device usb-host,hostbus=1,hostport=6.2.2,id=usb2 \
  -device usb-host,hostbus=1,hostport=6.2.3,id=usb3 \
  -device usb-host,hostbus=1,hostport=6.2,id=usb4 \
  -device usb-host,hostbus=1,hostport=6.3,id=usb5 \
  -device usb-host,hostbus=1,hostport=6.4,id=usb6 \
  -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \
  -iscsi initiator-name=iqn.1993-08.org.debian:01:3f3df5515b13 \
  -drive 
file=/dev/pve/vm-101-disk-1,if=none,id=drive-virtio0,cache=writeback,format=raw,aio=threads,detect-zeroes=on
 \
  -device 
virtio-blk-pci,drive=drive-virtio0,id=virtio0,bus=pci.0,addr=0xa,bootindex=100 \
  -netdev 
type=tap,id=net0,ifname=tap101i0,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown,vhost=on
 \
  -device 

Re: [RFC PATCH 25/27] vhost: Do not commit vhost used idx on vhost_virtqueue_stop

2020-11-20 Thread Eugenio Perez Martin
On Fri, Nov 20, 2020 at 8:12 PM Eugenio Pérez  wrote:
>
> ... if sw lm is enabled
>
> Signed-off-by: Eugenio Pérez 
> ---
>  hw/virtio/vhost.c | 15 ++-
>  1 file changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index cb44b9997f..cf000b979f 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -1424,17 +1424,22 @@ static void vhost_virtqueue_stop(struct vhost_dev 
> *dev,
>  struct vhost_vring_state state = {
>  .index = vhost_vq_index,
>  };
> -int r;
> +int r = -1;
>
>  if (virtio_queue_get_desc_addr(vdev, idx) == 0) {
>  /* Don't stop the virtqueue which might have not been started */
>  return;
>  }
>
> -r = dev->vhost_ops->vhost_get_vring_base(dev, );
> -if (r < 0) {
> -VHOST_OPS_DEBUG("vhost VQ %u ring restore failed: %d", idx, r);
> -/* Connection to the backend is broken, so let's sync internal
> +if (!dev->sw_lm_enabled) {
> +r = dev->vhost_ops->vhost_get_vring_base(dev, );
> +if (r < 0) {
> +VHOST_OPS_DEBUG("vhost VQ %u ring restore failed: %d", idx, r);
> +}
> +}
> +
> +if (!dev->sw_lm_enabled || r < 0) {

This test should actually test for `dev->sw_lm_enabled`, not for negation.

> +/* Connection to the backend is unusable, so let's sync internal
>   * last avail idx to the device used idx.
>   */
>  virtio_queue_restore_last_avail_idx(vdev, idx);
> --
> 2.18.4
>




Re: [RFC PATCH 00/27] vDPA software assisted live migration

2020-11-20 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20201120185105.279030-1-epere...@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20201120185105.279030-1-epere...@redhat.com
Subject: [RFC PATCH 00/27] vDPA software assisted live migration

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20201117173635.29101-1-alex.ben...@linaro.org -> 
patchew/20201117173635.29101-1-alex.ben...@linaro.org
 * [new tag] patchew/20201120185105.279030-1-epere...@redhat.com -> 
patchew/20201120185105.279030-1-epere...@redhat.com
Switched to a new branch 'test'
af2fe22 vhost: forbid vhost devices logging
405925c vhost: Add vhost_hdev_can_sw_lm
7f2955b vhost: Do not commit vhost used idx on vhost_virtqueue_stop
b68d3d5 vhost: iommu changes
74f282a vhost: unmap qemu's shadow virtqueues on sw live migration
c999e86 vhost: Add vhost_virtqueue_memory_map
6e5f219 vhost: Add vhost_virtqueue_memory_unmap
d5054c8 vhost: Return used buffers
806db46 vhost: add vhost_vring_get_buf_rcu
b6b8168 vhost: add vhost_vring_poll_rcu
ca44882 vhost: add vhost_vring_set_notification_rcu
3183f62 virtio: Expose virtqueue_alloc_element
4ead0ac vhost: Do not invalidate signalled used
ceb76a4 virtio: Remove virtio_queue_get_used_notify_split
6aacdfe vhost: Send buffers to device
9fcc98d virtio: Add virtio_queue_full
41da0f8 virtio: const-ify all virtio_tswap* functions
a3c92f1 vhost: Allocate shadow vring
b40b3f7 vhost: Route host->guest notification through qemu
92ea117 vhost: Add a flag for software assisted Live Migration
ace8c10 vhost: Route guest->host notification through qemu
6be11a6 virtio: Add virtio_queue_get_used_notify_split
47d4485 vhost: Add hdev->dev.sw_lm_vq_handler
7dbc8e5 vhost: add vhost_kernel_set_vring_enable
4e51c5c vhost: Move log resize/put to vhost_dev_set_log
b964abc vhost: Add device callback in vhost_migration_log
264504e vhost: Add vhost_dev_can_log

=== OUTPUT BEGIN ===
1/27 Checking commit 264504ee0018 (vhost: Add vhost_dev_can_log)
2/27 Checking commit b964abc315bd (vhost: Add device callback in 
vhost_migration_log)
3/27 Checking commit 4e51c5cec56d (vhost: Move log resize/put to 
vhost_dev_set_log)
4/27 Checking commit 7dbc8e5c64c3 (vhost: add vhost_kernel_set_vring_enable)
5/27 Checking commit 47d4485458d1 (vhost: Add hdev->dev.sw_lm_vq_handler)
6/27 Checking commit 6be11a63e3b4 (virtio: Add 
virtio_queue_get_used_notify_split)
7/27 Checking commit ace8c1034f83 (vhost: Route guest->host notification 
through qemu)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#24: 
new file mode 100644

total: 0 errors, 1 warnings, 245 lines checked

Patch 7/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
8/27 Checking commit 92ea11700e32 (vhost: Add a flag for software assisted Live 
Migration)
WARNING: Block comments use a leading /* on a separate line
#46: FILE: hw/virtio/vhost.c:1581:
+/* We've been called after migration is completed, so no need to

WARNING: Block comments use * on subsequent lines
#47: FILE: hw/virtio/vhost.c:1582:
+/* We've been called after migration is completed, so no need to
+   disable it again

total: 0 errors, 2 warnings, 45 lines checked

Patch 8/27 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/27 Checking commit b40b3f79355c (vhost: Route host->guest notification 
through qemu)
10/27 Checking commit a3c92f15b554 (vhost: Allocate shadow vring)
11/27 Checking commit 41da0f8e02b2 (virtio: const-ify all virtio_tswap* 
functions)
12/27 Checking commit 9fcc98da9cd9 (virtio: Add virtio_queue_full)
13/27 Checking commit 6aacdfe0e0ba (vhost: Send buffers to device)
ERROR: memory barrier without comment
#50: FILE: hw/virtio/vhost-sw-lm-ring.c:45:
+smp_rmb();

WARNING: Block comments use a leading /* on a separate line
#98: FILE: hw/virtio/vhost-sw-lm-ring.c:93:
+/* virtqueue_add:

WARNING: Block comments use a leading /* on a separate line
#125: FILE: hw/virtio/vhost-sw-lm-ring.c:120:
+/* Put entry in available array (but don't update avail->idx until they

WARNING: Block comments use a trailing */ on a separate line
#126: FILE: hw/virtio/vhost-sw-lm-ring.c:121:
+ * do sync). */

ERROR: g_free(NULL) is safe this check is probably not required
#147: FILE: hw/virtio/vhost-sw-lm-ring.c:142:
+if (vq->ring_id_maps[host_head]) {
+g_free(vq->ring_id_maps[host_head]);

ERROR: braces {} are necessary for all arms of this statement
#185: 

[Bug 1346784] Re: qemu internal memory areas visible to a guest via /proc/self/maps

2020-11-20 Thread Thomas Huth
I think this had been fixed here:
https://git.qemu.org/?p=qemu.git;a=commitdiff;h=d67f4aaae8379b44b3b51ff0

** Changed in: qemu
   Status: New => Fix Released

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

Title:
  qemu internal memory areas visible to a guest via /proc/self/maps

Status in QEMU:
  Fix Released

Bug description:
  
  Qemu internal memory areas are not suppressed in the output and are  visible 
to a guest via /proc/self/maps.

  $ echo "int main() { return 0; }" > /tmp/test.c
  $ gcc -m32 -fsanitize=address -fno-common -Wall -g -fPIC -o /tmp/test 
/tmp/test.c
  $ qemu-i386-static -R 0 /tmp/test

  We use -R option because the binary can't be executed under stock
  version of Qemu with address sanitizer instrumentations (Asan).

  Qemu memory map looks the following way where GUEST valid addresses
  are marked with * and invalid with @@@:

  * 08048000-08049000 r-xp  08:01 28835889  /tmp/test
  * 08049000-0804a000 rw-p  08:01 28835889  /tmp/test
  * 1000-2400 rw-p  00:00 0 
  * 2400-2800 ---p  00:00 0 
  * 2800-4000 rw-p  00:00 0 
  * 4000-40001000 ---p  00:00 0 
  * 40001000-40801000 rw-p  00:00 0 [stack]
  * 40801000-40821000 r-xp  08:01 26738694  
/lib32/ld-2.19.so
  * 40821000-40822000 r--p 0001f000 08:01 26738694  
/lib32/ld-2.19.so
  * 40822000-40823000 rw-p 0002 08:01 26738694  
/lib32/ld-2.19.so
  * 40823000-40827000 rw-p  00:00 0 
  * 40827000-408ca000 r-xp  08:01 49424994  
/home/michail/build/lib32/libasan.so.1.0.0
  * 408ca000-408cc000 rw-p 000a3000 08:01 49424994  
/home/michail/build/lib32/libasan.so.1.0.0
  * 408cc000-40d24000 rw-p  00:00 0 
  * 40d3c000-40ee2000 r-xp  08:01 26738695  
/lib32/libc-2.19.so
  * 40ee2000-40ee4000 r--p 001a6000 08:01 26738695  
/lib32/libc-2.19.so
  * 40ee4000-40ee5000 rw-p 001a8000 08:01 26738695  
/lib32/libc-2.19.so
  * 40ee5000-40ee8000 rw-p  00:00 0 
  * 40ee8000-40f0 r-xp  08:01 26738711  
/lib32/libpthread-2.19.so
  * 40f0-40f01000 r--p 00017000 08:01 26738711  
/lib32/libpthread-2.19.so
  * 40f01000-40f02000 rw-p 00018000 08:01 26738711  
/lib32/libpthread-2.19.so
  * 40f02000-40f04000 rw-p  00:00 0 
  * 40f04000-40f07000 r-xp  08:01 26738708  
/lib32/libdl-2.19.so
  * 40f07000-40f08000 r--p 2000 08:01 26738708  
/lib32/libdl-2.19.so
  * 40f08000-40f09000 rw-p 3000 08:01 26738708  
/lib32/libdl-2.19.so
  * 40f09000-40fee000 r-xp  08:01 49424965  
/home/michail/build/lib32/libstdc++.so.6.0.20
  * 40fee000-40ff2000 r--p 000e5000 08:01 49424965  
/home/michail/build/lib32/libstdc++.so.6.0.20
  * 40ff2000-40ff3000 rw-p 000e9000 08:01 49424965  
/home/michail/build/lib32/libstdc++.so.6.0.20
  * 40ff3000-40ffa000 rw-p  00:00 0 
  * 40ffa000-4103e000 r-xp  08:01 26738698  
/lib32/libm-2.19.so
  * 4103e000-4103f000 r--p 00043000 08:01 26738698  
/lib32/libm-2.19.so
  * 4103f000-4104 rw-p 00044000 08:01 26738698  
/lib32/libm-2.19.so
  * 4104-41041000 rw-p  00:00 0 
  * 41041000-4105b000 r-xp  08:01 49424637  
/home/michail/build/lib32/libgcc_s.so.1
  * 4105b000-4105c000 rw-p 00019000 08:01 49424637  
/home/michail/build/lib32/libgcc_s.so.1
  * 4105c000-4105e000 rw-p  00:00 0 
  * 4105f000-41061000 rw-p  00:00 0 
  * 41065000-421ed000 rw-p  00:00 0 
  * 421ee000-421f1000 rw-p  00:00 0 
  * 6000-6033b000 r-xp  08:01 48760980  
/home/michail/build/bin/qemu-i386-static
  * 6053b000-60546000 rw-p 0033b000 08:01 48760980  
/home/michail/build/bin/qemu-i386-static
  * 60546000-6059a000 rw-p  00:00 0 
  * 6059a000-6259b000 rwxp  00:00 0 
  * 6259b000-625ae000 rw-p  00:00 0 
  * 62dce000-62e12000 rw-p  00:00 0  [heap]
  @@@ 7f3f5e6a9000 - 7f3f61f28000 rw-p  00:00 0 
  @@@ 7fffad13 - 7fffad132000 r-xp  00:00 0  [vdso]
  @@@ ff60 - ff601000 r-xp  00:00 0  
[vsyscall]

  qemu-i386-static and its heap are in ranges which are valid and be
  reported to guest in case of maps file reading.

  The issue is related to early reported bugs:
  http://lists.nongnu.org/archive/html/qemu-devel/2014-07/msg02793.html
  http://lists.nongnu.org/archive/html/qemu-devel/2014-07/msg03085.html

To manage notifications about this bug go to:

Re: [RFC v4 9/9] i386: split cpu accelerators from cpu.c

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 07:47:11PM +0100, Claudio Fontana wrote:
> On 11/20/20 6:44 PM, Eduardo Habkost wrote:
> > On Fri, Nov 20, 2020 at 03:49:09PM +0100, Claudio Fontana wrote:
> >> split cpu.c into:
> >>
> >> cpu.ccpuid and common x86 cpu functionality
> >> host-cpu.c   host x86 cpu functions and "host" cpu type
> >> kvm/cpu.cKVM x86 cpu type
> >> hvf/cpu.cHVF x86 cpu type
> >> tcg/cpu.cTCG x86 cpu type
> >>
> >> The link to the accel class is set in the X86CPUClass classes
> >> at MODULE_INIT_ACCEL_CPU time, when the accelerator is known.
> >>
> >> Signed-off-by: Claudio Fontana 
> > [...]
> >> +static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data)
> >> +{
> >> +X86CPUAccelClass *acc = X86_CPU_ACCEL_CLASS(oc);
> >> +
> >> +acc->cpu_realizefn = host_cpu_realizefn;
> >> +acc->cpu_common_class_init = hvf_cpu_common_class_init;
> >> +acc->cpu_instance_init = hvf_cpu_instance_init;
> >> +};
> >> +static const TypeInfo hvf_cpu_accel_type_info = {
> >> +.name = X86_CPU_ACCEL_TYPE_NAME("hvf"),
> >> +
> >> +.parent = TYPE_X86_CPU_ACCEL,
> >> +.class_init = hvf_cpu_accel_class_init,
> >> +};
> >> +static void hvf_cpu_accel_register_types(void)
> >> +{
> >> +type_register_static(_cpu_accel_type_info);
> >> +}
> >> +type_init(hvf_cpu_accel_register_types);
> >> +
> >> +static void hvf_cpu_accel_init(void)
> >> +{
> >> +if (hvf_enabled()) {
> >> +x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME("hvf"));
> >> +}
> >> +}
> >> +
> >> +accel_cpu_init(hvf_cpu_accel_init);
> > 
> > The point of my suggestion of using QOM is to not require
> > separate accel_cpu_init() functions and (hvf|tcg|kvm)_enabled()
> > checks.
> > 
> > If we still have separate accel_cpu_init() functions for calling
> > x86_cpu_accel_init() with the right argument, using a pointer to
> > static variables like _cpu_accel (like you did before) was
> > simpler and required less boilerplate code.
> 
> 
> 
> Yes I agree.
> 
> 
> 
> 
> > 
> > However, the difference is that with the X86_CPU_ACCEL_TYPE_NAME
> > macro + object_class_by_name(), you don't need the separate
> > accel_cpu_init() functions for each accelerator.
> > 
> > All you need is a single:
> > 
> >   x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME(chosen_accel_name));
> > 
> > call somewhere in the initialization path.
> 
> 
> Makes sense. The problem is just determining chosen_accel_name.

Yeah, that was a challenge.  do_configure_accelerator() knows
what's the chosen accel name, though.

We can also do it inside accel_init_machine(), if we can
determine the correct accel name from the AccelState object.

> 
> 
> > 
> > A good place for the x86_cpu_accel_init() call would be
> > do_configure_accelerator(), but the function is arch-specific.
> > That's why I suggested a cpu_accel_arch_init() function at
> > https://lore.kernel.org/qemu-devel/20201118220750.gp1509...@habkost.net
> > 
> 
> 
> Fine by me. I'd use a specific init step for this, but that also works.

A separate module init function has no easy access to the accel
name, but in this case I'd say it's on purpose: the intended use
case for module init functions is to unconditionally register
features provided by a code module.  They shouldn't look at any
runtime configuration or runtime state.

-- 
Eduardo




[Bug 1395217] Re: Networking in qemu 2.0.0 and beyond is not compatible with Open Solaris (Illumos) 5.11

2020-11-20 Thread Thomas Huth
The QEMU project is currently considering to move its bug tracking to another 
system. For this we need to know which bugs are still valid and which could be 
closed already. Thus we are setting older bugs to "Incomplete" now.
If you still think this bug report here is valid, then please switch the state 
back to "New" within the next 60 days, otherwise this report will be marked as 
"Expired". Or mark it as "Fix Released" if the problem has been solved with a 
newer version of QEMU already. Thank you and sorry for the inconvenience.

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

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

Title:
  Networking in qemu 2.0.0 and beyond is not compatible with Open
  Solaris (Illumos) 5.11

Status in QEMU:
  Incomplete

Bug description:
  The networking code in qemu in versions 2.0.0 and beyond is non-
  functional with Solaris/Illumos 5.11 images.

  Building 1.7.1, 2.0.0, 2.0.2, 2.1.2,and 2.2.0rc1with the following
  standard Slackware config:

  # From Slackware build tree . . . 
  ./configure \
--prefix=/usr \
--libdir=/usr/lib64 \
--sysconfdir=/etc \
--localstatedir=/var \
--enable-gtk \
--enable-system \
--enable-kvm \
--disable-debug-info \
--enable-virtfs \
--enable-sdl \
--audio-drv-list=alsa,oss,sdl,esd \
--enable-libusb \
--disable-vnc \
--target-list=x86_64-linux-user,i386-linux-user,x86_64-softmmu,i386-softmmu 
\
--enable-spice \
--enable-usb-redir 

  
  And attempting to run the same VM image with the following command (or via 
virt-manager):

  macaddress="DE:AD:BE:EF:3F:A4"

  qemu-system-x86_64 nex4x -cdrom /dev/cdrom -name "Nex41" -cpu Westmere
  -machine accel=kvm -smp 2 -m 4000 -net nic,macaddr=$macaddress  -net 
bridge,br=b
  r0 -net dump,file=/usr1/tmp/ -drive file=nex4x_d1 -drive 
file=nex4x_d2
   -enable-kvm

  Gives success on 1.7.1, and a deaf VM on all subsequent versions.

  Notable in validating my config, is that a Windows 7 image runs
  cleanly with networking on *all* builds, so my configuration appears
  to be good - qemu just hates Solaris at this point.

  Watching with wireshark (as well as pulling network traces from qemu
  as noted above) it appears that the notable difference in the two
  configs is that for some reason, Solaris gets stuck arping for it's
  own interface on startup, and never really comes on line on the
  network.  If other hosts attempt to ping the Solaris instance, they
  can successfully arp the bad VM, but not the other way around.

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



Re: [PATCH v1 3/6] tests/avocado: clean-up socket directory after run

2020-11-20 Thread Wainer dos Santos Moschetta



On 11/17/20 2:36 PM, Alex Bennée wrote:

Previously we were leaving temporary directories behind. While the
QEMUMachine does make efforts to clean up after itself the directory
belongs to the calling function. We use TemporaryDirectory to wrap
this although we explicitly clear the reference in tearDown() as it
doesn't get cleaned up otherwise.


This patch fixes the problem introduced on patch 02 of this series.



Signed-off-by: Alex Bennée 
---
  tests/acceptance/avocado_qemu/__init__.py | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 3033b2cabe..bf54e419da 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -171,8 +171,8 @@ class Test(avocado.Test):
  self.cancel("No QEMU binary defined or found in the build tree")
  
  def _new_vm(self, *args):

-sd = tempfile.mkdtemp(prefix="avocado_qemu_sock_")
-vm = QEMUMachine(self.qemu_bin, sock_dir=sd)
+self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")


Double-checking that you really meant "avo" or if your fingers forgot to 
type the remaining letters. :)


- Wainer


+vm = QEMUMachine(self.qemu_bin, sock_dir=self._sd.name)
  if args:
  vm.add_args(*args)
  return vm
@@ -193,6 +193,7 @@ class Test(avocado.Test):
  def tearDown(self):
  for vm in self._vms.values():
  vm.shutdown()
+self._sd = None
  
  def fetch_asset(self, name,

  asset_hash=None, algorithm=None,





[RFC PATCH 24/27] vhost: iommu changes

2020-11-20 Thread Eugenio Pérez
Since vhost is now asking for qemu's VA, iommu needs to be bypassed.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index eebfac4455..cb44b9997f 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1109,6 +1109,10 @@ static int vhost_sw_live_migration_start(struct 
vhost_dev *dev)
 
 assert(dev->vhost_ops->vhost_set_vring_enable);
 dev->vhost_ops->vhost_set_vring_enable(dev, false);
+if (vhost_dev_has_iommu(dev)) {
+r = vhost_backend_invalidate_device_iotlb(dev, 0, -1ULL);
+assert(r == 0);
+}
 
 for (idx = 0; idx < dev->nvqs; ++idx) {
 struct vhost_virtqueue *vq = >vqs[idx];
@@ -1269,6 +1273,19 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, 
uint64_t iova, int write)
 
 trace_vhost_iotlb_miss(dev, 1);
 
+if (dev->sw_lm_enabled) {
+uaddr = iova;
+len = 4096;
+ret = vhost_backend_update_device_iotlb(dev, iova, uaddr, len,
+IOMMU_RW);
+if (ret) {
+trace_vhost_iotlb_miss(dev, 2);
+error_report("Fail to update device iotlb");
+}
+
+return ret;
+}
+
 iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
   iova, write,
   MEMTXATTRS_UNSPECIFIED);
-- 
2.18.4




Re: [RFC PATCH 00/27] vDPA software assisted live migration

2020-11-20 Thread Eugenio Perez Martin
The main intention with this POC/RFC is to serve as a base to
implement SW LM in vdpa devices.

To implement in vhost-vdpa devices, the high priority is to achieve an
interface for vdpa to stop the device without losing its state, i.e.,
the avail_idx the destination device should start fetching descriptors
from. Following this POC, an implementation on vdpa_sim will be
performed.

Apart from that, there is a TODO list about this series, they will be
solved as the code is marked as valid. They don't affect the device,
just internal qemu's code, and in case of change of direction it is
easy to modify or delete. Comments about these are welcome.

- Currently, it hijacks the log mechanism to know when migration is
starting/done. Maybe it would be cleaner to forward migrate status
from virtio_vmstate_change, since there is no need for the memory
listener. However, this could make "memory backend" abstraction (also
TODO) more complicated. This would drop patches 2,3 entirely.
- There is a reverse search in a list on "vhost_dev_from_virtio" for
each notification. Not really efficient, and it leads to a race
condition at device destruction.
- Implement new capabilities (no iommu, packed vq, event_idx, ...)
- Lot of assertions need to be converted to proper error handling.

Thanks!

On Fri, Nov 20, 2020 at 8:02 PM Eugenio Pérez  wrote:
>
> This series enable vDPA software assisted live migration for vhost-net
> devices. This is a new method of vhost devices migration: Instead of
> relay on vDPA device's dirty logging capability, SW assisted LM
> intercepts dataplane, forwarding the descriptors between VM and device.
>
> In this migration mode, qemu offers a new vring to the device to
> read and write into, and disable vhost notifiers, processing guest and
> vhost notifications in qemu. On used buffer relay, qemu will mark the
> dirty memory as with plain virtio-net devices. This way, devices does
> not need to have dirty page logging capability.
>
> This series is a POC doing SW LM for vhost-net devices, which already
> have dirty page logging capabilities. None of the changes have actual
> effect with current devices until last two patches (26 and 27) are
> applied, but they can be rebased on top of any other. These checks the
> device to meet all requirements, and disable vhost-net devices logging
> so migration goes through SW LM. This last patch is not meant to be
> applied in the final revision, it is in the series just for testing
> purposes.
>
> For use SW assisted LM these vhost-net devices need to be instantiated:
> * With IOMMU (iommu_platform=on,ats=on)
> * Without event_idx (event_idx=off)
>
> Just the notification forwarding (with no descriptor relay) can be
> achieved with patches 7 and 9, and starting migration. Partial applies
> between 13 and 24 will not work while migrating on source, and patch
> 25 is needed for the destination to resume network activity.
>
> It is based on the ideas of DPDK SW assisted LM, in the series of
> DPDK's https://patchwork.dpdk.org/cover/48370/ .
>
> Comments are welcome.
>
> Thanks!
>
> Eugenio Pérez (27):
>   vhost: Add vhost_dev_can_log
>   vhost: Add device callback in vhost_migration_log
>   vhost: Move log resize/put to vhost_dev_set_log
>   vhost: add vhost_kernel_set_vring_enable
>   vhost: Add hdev->dev.sw_lm_vq_handler
>   virtio: Add virtio_queue_get_used_notify_split
>   vhost: Route guest->host notification through qemu
>   vhost: Add a flag for software assisted Live Migration
>   vhost: Route host->guest notification through qemu
>   vhost: Allocate shadow vring
>   virtio: const-ify all virtio_tswap* functions
>   virtio: Add virtio_queue_full
>   vhost: Send buffers to device
>   virtio: Remove virtio_queue_get_used_notify_split
>   vhost: Do not invalidate signalled used
>   virtio: Expose virtqueue_alloc_element
>   vhost: add vhost_vring_set_notification_rcu
>   vhost: add vhost_vring_poll_rcu
>   vhost: add vhost_vring_get_buf_rcu
>   vhost: Return used buffers
>   vhost: Add vhost_virtqueue_memory_unmap
>   vhost: Add vhost_virtqueue_memory_map
>   vhost: unmap qemu's shadow virtqueues on sw live migration
>   vhost: iommu changes
>   vhost: Do not commit vhost used idx on vhost_virtqueue_stop
>   vhost: Add vhost_hdev_can_sw_lm
>   vhost: forbid vhost devices logging
>
>  hw/virtio/vhost-sw-lm-ring.h  |  39 +++
>  include/hw/virtio/vhost.h |   5 +
>  include/hw/virtio/virtio-access.h |   8 +-
>  include/hw/virtio/virtio.h|   4 +
>  hw/net/virtio-net.c   |  39 ++-
>  hw/virtio/vhost-backend.c |  29 ++
>  hw/virtio/vhost-sw-lm-ring.c  | 268 +++
>  hw/virtio/vhost.c | 431 +-
>  hw/virtio/virtio.c|  18 +-
>  hw/virtio/meson.build |   2 +-
>  10 files changed, 758 insertions(+), 85 deletions(-)
>  create mode 100644 hw/virtio/vhost-sw-lm-ring.h
>  create mode 100644 hw/virtio/vhost-sw-lm-ring.c
>
> --
> 2.18.4
>
>




Re: [PATCH v1 2/6] tests: add prefixes to the bare mkdtemp calls

2020-11-20 Thread Wainer dos Santos Moschetta



On 11/17/20 2:36 PM, Alex Bennée wrote:

The first step to debug a thing is to know what created the thing in
the first place. Add some prefixes so random tmpdir's have something
grep in the code.



Yeah, it indeed helps.




Signed-off-by: Alex Bennée 

---
v2
   - fix long lines
---
  python/qemu/machine.py| 3 ++-
  tests/acceptance/avocado_qemu/__init__.py | 3 ++-
  2 files changed, 4 insertions(+), 2 deletions(-)



Reviewed-by: Wainer dos Santos Moschetta 




diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 6420f01bed..64d966aeeb 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -303,7 +303,8 @@ class QEMUMachine:
  return args
  
  def _pre_launch(self) -> None:

-self._temp_dir = tempfile.mkdtemp(dir=self._test_dir)
+self._temp_dir = tempfile.mkdtemp(prefix="qemu-machine-",
+  dir=self._test_dir)
  self._qemu_log_path = os.path.join(self._temp_dir, self._name + 
".log")
  self._qemu_log_file = open(self._qemu_log_path, 'wb')
  
diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py

index 4cda037187..3033b2cabe 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -171,7 +171,8 @@ class Test(avocado.Test):
  self.cancel("No QEMU binary defined or found in the build tree")
  
  def _new_vm(self, *args):

-vm = QEMUMachine(self.qemu_bin, sock_dir=tempfile.mkdtemp())
+sd = tempfile.mkdtemp(prefix="avocado_qemu_sock_")
+vm = QEMUMachine(self.qemu_bin, sock_dir=sd)
  if args:
  vm.add_args(*args)
  return vm





[RFC PATCH 23/27] vhost: unmap qemu's shadow virtqueues on sw live migration

2020-11-20 Thread Eugenio Pérez
Since vhost does not need to access it, it has no sense to keep it
mapped.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index f640d4edf0..eebfac4455 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1124,6 +1124,7 @@ static int vhost_sw_live_migration_start(struct vhost_dev 
*dev)
 
 dev->sw_lm_shadow_vq[idx] = vhost_sw_lm_shadow_vq(dev, idx);
 event_notifier_set_handler(>masked_notifier, vhost_handle_call);
+vhost_virtqueue_memory_unmap(dev, >vqs[idx], true);
 
 vhost_vring_write_addr(dev->sw_lm_shadow_vq[idx], );
 r = dev->vhost_ops->vhost_set_vring_addr(dev, );
-- 
2.18.4




[RFC PATCH 25/27] vhost: Do not commit vhost used idx on vhost_virtqueue_stop

2020-11-20 Thread Eugenio Pérez
... if sw lm is enabled

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index cb44b9997f..cf000b979f 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1424,17 +1424,22 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
 struct vhost_vring_state state = {
 .index = vhost_vq_index,
 };
-int r;
+int r = -1;
 
 if (virtio_queue_get_desc_addr(vdev, idx) == 0) {
 /* Don't stop the virtqueue which might have not been started */
 return;
 }
 
-r = dev->vhost_ops->vhost_get_vring_base(dev, );
-if (r < 0) {
-VHOST_OPS_DEBUG("vhost VQ %u ring restore failed: %d", idx, r);
-/* Connection to the backend is broken, so let's sync internal
+if (!dev->sw_lm_enabled) {
+r = dev->vhost_ops->vhost_get_vring_base(dev, );
+if (r < 0) {
+VHOST_OPS_DEBUG("vhost VQ %u ring restore failed: %d", idx, r);
+}
+}
+
+if (!dev->sw_lm_enabled || r < 0) {
+/* Connection to the backend is unusable, so let's sync internal
  * last avail idx to the device used idx.
  */
 virtio_queue_restore_last_avail_idx(vdev, idx);
-- 
2.18.4




[RFC PATCH 19/27] vhost: add vhost_vring_get_buf_rcu

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-sw-lm-ring.h |  1 +
 hw/virtio/vhost-sw-lm-ring.c | 29 +
 2 files changed, 30 insertions(+)

diff --git a/hw/virtio/vhost-sw-lm-ring.h b/hw/virtio/vhost-sw-lm-ring.h
index 03257d60c1..429a125558 100644
--- a/hw/virtio/vhost-sw-lm-ring.h
+++ b/hw/virtio/vhost-sw-lm-ring.h
@@ -19,6 +19,7 @@ typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
 
 bool vhost_vring_kick(VhostShadowVirtqueue *vq);
 int vhost_vring_add(VhostShadowVirtqueue *vq, VirtQueueElement *elem);
+VirtQueueElement *vhost_vring_get_buf_rcu(VhostShadowVirtqueue *vq, size_t sz);
 
 /* Called within rcu_read_lock().  */
 void vhost_vring_set_notification_rcu(VhostShadowVirtqueue *vq, bool enable);
diff --git a/hw/virtio/vhost-sw-lm-ring.c b/hw/virtio/vhost-sw-lm-ring.c
index 3652889d8e..4fafd1b278 100644
--- a/hw/virtio/vhost-sw-lm-ring.c
+++ b/hw/virtio/vhost-sw-lm-ring.c
@@ -187,6 +187,35 @@ int vhost_vring_add(VhostShadowVirtqueue *vq, 
VirtQueueElement *elem)
 return 0;
 }
 
+VirtQueueElement *vhost_vring_get_buf_rcu(VhostShadowVirtqueue *vq, size_t sz)
+{
+const vring_used_t *used = vq->vring.used;
+VirtQueueElement *ret;
+vring_used_elem_t used_elem;
+uint16_t last_used;
+
+if (!vhost_vring_poll_rcu(vq)) {
+return NULL;
+}
+
+last_used = vq->used_idx & (vq->vring.num - 1);
+used_elem.id = virtio_tswap32(vq->vdev, used->ring[last_used].id);
+used_elem.len = virtio_tswap32(vq->vdev, used->ring[last_used].len);
+
+if (unlikely(used_elem.id >= vq->vring.num)) {
+virtio_error(vq->vdev, "Device says index %u is available",
+ used_elem.id);
+return NULL;
+}
+
+ret = vq->ring_id_maps[used_elem.id];
+ret->len = used_elem.len;
+
+vq->used_idx++;
+
+return ret;
+}
+
 void vhost_vring_write_addr(const VhostShadowVirtqueue *vq,
 struct vhost_vring_addr *addr)
 {
-- 
2.18.4




[RFC PATCH 27/27] vhost: forbid vhost devices logging

2020-11-20 Thread Eugenio Pérez
This is NOT a commit intended for merge, but for test the patchset.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 44a51ccf5e..069e5c915d 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -79,7 +79,7 @@ static struct vhost_dev *vhost_dev_from_virtio(const 
VirtIODevice *vdev)
 
 static bool vhost_dev_can_log(const struct vhost_dev *hdev)
 {
-return hdev->features & (0x1ULL << VHOST_F_LOG_ALL);
+return false;
 }
 
 static void vhost_dev_sync_region(struct vhost_dev *dev,
-- 
2.18.4




[RFC PATCH 22/27] vhost: Add vhost_virtqueue_memory_map

2020-11-20 Thread Eugenio Pérez
To make it symmetric with _unmap.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 68 ++-
 1 file changed, 44 insertions(+), 24 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index eafbbaa751..f640d4edf0 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -827,6 +827,42 @@ static void vhost_virtqueue_memory_unmap(struct vhost_dev 
*dev,
 }
 }
 
+static int vhost_virtqueue_memory_map(struct vhost_dev *dev,
+  struct vhost_virtqueue *vq,
+  unsigned int vhost_vq_index)
+{
+int r;
+hwaddr a, l, s;
+
+a = vq->desc_phys;
+s = l = vq->desc_size;
+vq->desc = vhost_memory_map(dev, a, , false);
+if (!vq->desc || l != s) {
+return -ENOMEM;
+}
+
+a = vq->avail_phys;
+s = l = vq->avail_size;
+vq->avail = vhost_memory_map(dev, a, , false);
+if (!vq->avail || l != s) {
+return -ENOMEM;
+}
+
+a = vq->used_phys;
+s = l = vq->used_size;
+vq->used = vhost_memory_map(dev, a, , true);
+if (!vq->used || l != s) {
+return -ENOMEM;
+}
+
+r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled);
+if (r < 0) {
+return -errno;
+}
+
+return 0;
+}
+
 static int vhost_dev_set_features(struct vhost_dev *dev,
   bool enable_log)
 {
@@ -1271,7 +1307,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
 VirtioBusState *vbus = VIRTIO_BUS(qbus);
 VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
-hwaddr s, l, a;
+hwaddr a;
 int r;
 int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx);
 struct vhost_vring_file file = {
@@ -1311,31 +1347,15 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
 }
 }
 
-vq->desc_size = s = l = virtio_queue_get_desc_size(vdev, idx);
+vq->desc_size = virtio_queue_get_desc_size(vdev, idx);
 vq->desc_phys = a;
-vq->desc = vhost_memory_map(dev, a, , false);
-if (!vq->desc || l != s) {
-r = -ENOMEM;
-goto fail_alloc;
-}
-vq->avail_size = s = l = virtio_queue_get_avail_size(vdev, idx);
-vq->avail_phys = a = virtio_queue_get_avail_addr(vdev, idx);
-vq->avail = vhost_memory_map(dev, a, , false);
-if (!vq->avail || l != s) {
-r = -ENOMEM;
-goto fail_alloc;
-}
-vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx);
-vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx);
-vq->used = vhost_memory_map(dev, a, , true);
-if (!vq->used || l != s) {
-r = -ENOMEM;
-goto fail_alloc;
-}
+vq->avail_size = virtio_queue_get_avail_size(vdev, idx);
+vq->avail_phys = virtio_queue_get_avail_addr(vdev, idx);
+vq->used_size = virtio_queue_get_used_size(vdev, idx);
+vq->used_phys = virtio_queue_get_used_addr(vdev, idx);
 
-r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled);
-if (r < 0) {
-r = -errno;
+r = vhost_virtqueue_memory_map(dev, vq, vhost_vq_index);
+if (r) {
 goto fail_alloc;
 }
 
-- 
2.18.4




[RFC PATCH 16/27] virtio: Expose virtqueue_alloc_element

2020-11-20 Thread Eugenio Pérez
Specify VirtQueueElement * as return type makes no harm at this moment.

Signed-off-by: Eugenio Pérez 
---
 include/hw/virtio/virtio.h | 2 ++
 hw/virtio/virtio.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 79212141a6..ee8fe96f32 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -196,6 +196,8 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement 
*elem,
 unsigned int len, unsigned int idx);
 
 void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem);
+VirtQueueElement *virtqueue_alloc_element(size_t sz, unsigned out_num,
+  unsigned in_num);
 void *virtqueue_pop(VirtQueue *vq, size_t sz);
 unsigned int virtqueue_drop_all(VirtQueue *vq);
 void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz);
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ad9dc5dfa7..a89525f067 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1400,7 +1400,8 @@ void virtqueue_map(VirtIODevice *vdev, VirtQueueElement 
*elem)
 false);
 }
 
-static void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned 
in_num)
+VirtQueueElement *virtqueue_alloc_element(size_t sz, unsigned out_num,
+  unsigned in_num)
 {
 VirtQueueElement *elem;
 size_t in_addr_ofs = QEMU_ALIGN_UP(sz, __alignof__(elem->in_addr[0]));
-- 
2.18.4




[RFC PATCH 14/27] virtio: Remove virtio_queue_get_used_notify_split

2020-11-20 Thread Eugenio Pérez
No more uses beyond this point

Signed-off-by: Eugenio Pérez 
---
 include/hw/virtio/virtio.h |  1 -
 hw/virtio/virtio.c | 14 --
 2 files changed, 15 deletions(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 0a7f5cc63e..79212141a6 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -225,7 +225,6 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id);
 
 void virtio_notify_config(VirtIODevice *vdev);
 
-bool virtio_queue_get_used_notify_split(VirtQueue *vq);
 bool virtio_queue_get_notification(VirtQueue *vq);
 void virtio_queue_set_notification(VirtQueue *vq, int enable);
 
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 77ca5f6b6f..ad9dc5dfa7 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -377,20 +377,6 @@ static inline void vring_used_idx_set(VirtQueue *vq, 
uint16_t val)
 vq->used_idx = val;
 }
 
-bool virtio_queue_get_used_notify_split(VirtQueue *vq)
-{
-VRingMemoryRegionCaches *caches;
-hwaddr pa = offsetof(VRingUsed, flags);
-uint16_t flags;
-
-RCU_READ_LOCK_GUARD();
-
-caches = vring_get_region_caches(vq);
-assert(caches);
-flags = virtio_lduw_phys_cached(vq->vdev, >used, pa);
-return !(VRING_USED_F_NO_NOTIFY & flags);
-}
-
 /* Called within rcu_read_lock().  */
 static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
 {
-- 
2.18.4




[RFC PATCH 26/27] vhost: Add vhost_hdev_can_sw_lm

2020-11-20 Thread Eugenio Pérez
This allows a device to migrate if it meet a few requirements.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index cf000b979f..44a51ccf5e 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1529,6 +1529,37 @@ static void vhost_virtqueue_cleanup(struct 
vhost_virtqueue *vq)
 event_notifier_cleanup(>masked_notifier);
 }
 
+static bool vhost_hdev_can_sw_lm(struct vhost_dev *hdev)
+{
+const char *cause = NULL;
+
+if (hdev->features & (VIRTIO_F_IOMMU_PLATFORM)) {
+cause = "have iommu";
+} else if (hdev->features & VIRTIO_F_RING_PACKED) {
+cause = "is packed";
+} else if (hdev->features & VIRTIO_RING_F_EVENT_IDX) {
+cause = "Have event idx";
+} else if (hdev->features & VIRTIO_RING_F_INDIRECT_DESC) {
+cause = "Supports indirect descriptors";
+} else if (hdev->nvqs != 2) {
+cause = "!= 2 #vq supported";
+} else if (!hdev->vhost_ops->vhost_net_set_backend) {
+cause = "cannot pause device";
+}
+
+if (cause) {
+if (!hdev->migration_blocker) {
+error_setg(>migration_blocker,
+"Migration disabled: vhost lacks VHOST_F_LOG_ALL feature and 
%s.",
+cause);
+}
+
+return false;
+}
+
+return true;
+}
+
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
VhostBackendType backend_type, uint32_t busyloop_timeout)
 {
@@ -1604,7 +1635,8 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 };
 
 if (hdev->migration_blocker == NULL) {
-if (!vhost_dev_can_log(hdev)) {
+if (!vhost_dev_can_log(hdev) && !vhost_hdev_can_sw_lm(hdev)
+&& hdev->migration_blocker == NULL) {
 error_setg(>migration_blocker,
"Migration disabled: vhost lacks VHOST_F_LOG_ALL 
feature.");
 } else if (vhost_dev_log_is_shared(hdev) && !qemu_memfd_alloc_check()) 
{
-- 
2.18.4




[RFC PATCH 21/27] vhost: Add vhost_virtqueue_memory_unmap

2020-11-20 Thread Eugenio Pérez
This is not a huge gain but helps in later changes.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 38 --
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 9a3c580dcf..eafbbaa751 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -812,6 +812,21 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
 return 0;
 }
 
+static void vhost_virtqueue_memory_unmap(struct vhost_dev *dev,
+struct vhost_virtqueue *vq,
+bool used_is_dirty)
+{
+if (vq->used) {
+vhost_memory_unmap(dev, vq->used, vq->used_size, used_is_dirty, 0);
+}
+if (vq->avail) {
+vhost_memory_unmap(dev, vq->avail, vq->avail_size, 0, 0);
+}
+if (vq->desc) {
+vhost_memory_unmap(dev, vq->desc, vq->desc_size, 0, 0);
+}
+}
+
 static int vhost_dev_set_features(struct vhost_dev *dev,
   bool enable_log)
 {
@@ -1301,21 +1316,21 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
 vq->desc = vhost_memory_map(dev, a, , false);
 if (!vq->desc || l != s) {
 r = -ENOMEM;
-goto fail_alloc_desc;
+goto fail_alloc;
 }
 vq->avail_size = s = l = virtio_queue_get_avail_size(vdev, idx);
 vq->avail_phys = a = virtio_queue_get_avail_addr(vdev, idx);
 vq->avail = vhost_memory_map(dev, a, , false);
 if (!vq->avail || l != s) {
 r = -ENOMEM;
-goto fail_alloc_avail;
+goto fail_alloc;
 }
 vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx);
 vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx);
 vq->used = vhost_memory_map(dev, a, , true);
 if (!vq->used || l != s) {
 r = -ENOMEM;
-goto fail_alloc_used;
+goto fail_alloc;
 }
 
 r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled);
@@ -1358,15 +1373,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
 fail_vector:
 fail_kick:
 fail_alloc:
-vhost_memory_unmap(dev, vq->used, virtio_queue_get_used_size(vdev, idx),
-   0, 0);
-fail_alloc_used:
-vhost_memory_unmap(dev, vq->avail, virtio_queue_get_avail_size(vdev, idx),
-   0, 0);
-fail_alloc_avail:
-vhost_memory_unmap(dev, vq->desc, virtio_queue_get_desc_size(vdev, idx),
-   0, 0);
-fail_alloc_desc:
+vhost_virtqueue_memory_unmap(dev, vq, false);
 return r;
 }
 
@@ -1408,12 +1415,7 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
 vhost_vq_index);
 }
 
-vhost_memory_unmap(dev, vq->used, virtio_queue_get_used_size(vdev, idx),
-   1, virtio_queue_get_used_size(vdev, idx));
-vhost_memory_unmap(dev, vq->avail, virtio_queue_get_avail_size(vdev, idx),
-   0, virtio_queue_get_avail_size(vdev, idx));
-vhost_memory_unmap(dev, vq->desc, virtio_queue_get_desc_size(vdev, idx),
-   0, virtio_queue_get_desc_size(vdev, idx));
+vhost_virtqueue_memory_unmap(dev, vq, true);
 }
 
 static void vhost_eventfd_add(MemoryListener *listener,
-- 
2.18.4




[RFC PATCH 10/27] vhost: Allocate shadow vring

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-sw-lm-ring.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-sw-lm-ring.c b/hw/virtio/vhost-sw-lm-ring.c
index cbf53965cd..cd7b5ba772 100644
--- a/hw/virtio/vhost-sw-lm-ring.c
+++ b/hw/virtio/vhost-sw-lm-ring.c
@@ -16,8 +16,11 @@
 #include "qemu/event_notifier.h"
 
 typedef struct VhostShadowVirtqueue {
+struct vring vring;
 EventNotifier hdev_notifier;
 VirtQueue *vq;
+
+vring_desc_t descs[];
 } VhostShadowVirtqueue;
 
 static inline bool vhost_vring_should_kick(VhostShadowVirtqueue *vq)
@@ -37,10 +40,12 @@ VhostShadowVirtqueue *vhost_sw_lm_shadow_vq(struct 
vhost_dev *dev, int idx)
 .index = idx
 };
 VirtQueue *vq = virtio_get_queue(dev->vdev, idx);
+unsigned num = virtio_queue_get_num(dev->vdev, idx);
+size_t ring_size = vring_size(num, VRING_DESC_ALIGN_SIZE);
 VhostShadowVirtqueue *svq;
 int r;
 
-svq = g_new0(VhostShadowVirtqueue, 1);
+svq = g_malloc0(sizeof(*svq) + ring_size);
 svq->vq = vq;
 
 r = event_notifier_init(>hdev_notifier, 0);
-- 
2.18.4




[RFC PATCH 12/27] virtio: Add virtio_queue_full

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 include/hw/virtio/virtio.h |  2 ++
 hw/virtio/virtio.c | 15 +--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b9b8497ea0..0a7f5cc63e 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -233,6 +233,8 @@ int virtio_queue_ready(VirtQueue *vq);
 
 int virtio_queue_empty(VirtQueue *vq);
 
+bool virtio_queue_full(const VirtQueue *vq);
+
 /* Host binding interface.  */
 
 uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 3469946538..77ca5f6b6f 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -684,6 +684,17 @@ int virtio_queue_empty(VirtQueue *vq)
 }
 }
 
+static bool virtio_queue_full_rcu(const VirtQueue *vq)
+{
+return vq->inuse >= vq->vring.num;
+}
+
+bool virtio_queue_full(const VirtQueue *vq)
+{
+RCU_READ_LOCK_GUARD();
+return virtio_queue_full_rcu(vq);
+}
+
 static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len)
 {
@@ -1453,7 +1464,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)
 
 max = vq->vring.num;
 
-if (vq->inuse >= vq->vring.num) {
+if (unlikely(virtio_queue_full_rcu(vq))) {
 virtio_error(vdev, "Virtqueue size exceeded");
 goto done;
 }
@@ -1588,7 +1599,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t 
sz)
 
 max = vq->vring.num;
 
-if (vq->inuse >= vq->vring.num) {
+if (unlikely(virtio_queue_full_rcu(vq))) {
 virtio_error(vdev, "Virtqueue size exceeded");
 goto done;
 }
-- 
2.18.4




[RFC PATCH 20/27] vhost: Return used buffers

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-sw-lm-ring.h |  3 +++
 hw/virtio/vhost-sw-lm-ring.c | 14 +++
 hw/virtio/vhost.c| 46 +---
 3 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/hw/virtio/vhost-sw-lm-ring.h b/hw/virtio/vhost-sw-lm-ring.h
index 429a125558..0c4fa772c7 100644
--- a/hw/virtio/vhost-sw-lm-ring.h
+++ b/hw/virtio/vhost-sw-lm-ring.h
@@ -17,6 +17,9 @@
 
 typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
 
+VirtIODevice *vhost_vring_vdev(VhostShadowVirtqueue *svq);
+VirtQueue *vhost_vring_vdev_vq(VhostShadowVirtqueue *svq);
+
 bool vhost_vring_kick(VhostShadowVirtqueue *vq);
 int vhost_vring_add(VhostShadowVirtqueue *vq, VirtQueueElement *elem);
 VirtQueueElement *vhost_vring_get_buf_rcu(VhostShadowVirtqueue *vq, size_t sz);
diff --git a/hw/virtio/vhost-sw-lm-ring.c b/hw/virtio/vhost-sw-lm-ring.c
index 4fafd1b278..244c722910 100644
--- a/hw/virtio/vhost-sw-lm-ring.c
+++ b/hw/virtio/vhost-sw-lm-ring.c
@@ -46,6 +46,16 @@ typedef struct VhostShadowVirtqueue {
 vring_desc_t descs[];
 } VhostShadowVirtqueue;
 
+VirtIODevice *vhost_vring_vdev(VhostShadowVirtqueue *svq)
+{
+return svq->vdev;
+}
+
+VirtQueue *vhost_vring_vdev_vq(VhostShadowVirtqueue *svq)
+{
+return svq->vq;
+}
+
 static bool vhost_vring_should_kick_rcu(VhostShadowVirtqueue *vq)
 {
 VirtIODevice *vdev = vq->vdev;
@@ -179,10 +189,6 @@ static int vhost_vring_add_split(VhostShadowVirtqueue *vq,
 int vhost_vring_add(VhostShadowVirtqueue *vq, VirtQueueElement *elem)
 {
 int host_head = vhost_vring_add_split(vq, elem);
-if (vq->ring_id_maps[host_head]) {
-g_free(vq->ring_id_maps[host_head]);
-}
-
 vq->ring_id_maps[host_head] = elem;
 return 0;
 }
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index ac2bc14190..9a3c580dcf 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -986,17 +986,50 @@ static void handle_sw_lm_vq(VirtIODevice *vdev, VirtQueue 
*vq)
 } while(!virtio_queue_empty(vq));
 }
 
+static void handle_sw_lm_vq_call(struct vhost_dev *hdev,
+ VhostShadowVirtqueue *svq)
+{
+VirtQueueElement *elem;
+VirtIODevice *vdev = vhost_vring_vdev(svq);
+VirtQueue *vq = vhost_vring_vdev_vq(svq);
+uint16_t idx = virtio_get_queue_index(vq);
+
+RCU_READ_LOCK_GUARD();
+/*
+ * Make used all buffers as possible.
+ */
+do {
+unsigned i = 0;
+
+vhost_vring_set_notification_rcu(svq, false);
+while (true) {
+elem = vhost_vring_get_buf_rcu(svq, sizeof(*elem));
+if (!elem) {
+break;
+}
+
+assert(i < virtio_queue_get_num(vdev, idx));
+virtqueue_fill(vq, elem, elem->len, i++);
+}
+
+virtqueue_flush(vq, i);
+virtio_notify_irqfd(vdev, vq);
+
+vhost_vring_set_notification_rcu(svq, true);
+} while (vhost_vring_poll_rcu(svq));
+}
+
 static void vhost_handle_call(EventNotifier *n)
 {
 struct vhost_virtqueue *hvq = container_of(n,
   struct vhost_virtqueue,
   masked_notifier);
 struct vhost_dev *vdev = hvq->dev;
-int idx = vdev->vq_index + (hvq == >vqs[0] ? 0 : 1);
-VirtQueue *vq = virtio_get_queue(vdev->vdev, idx);
+int idx = hvq == >vqs[0] ? 0 : 1;
+VhostShadowVirtqueue *vq = vdev->sw_lm_shadow_vq[idx];
 
 if (event_notifier_test_and_clear(n)) {
-virtio_notify_irqfd(vdev->vdev, vq);
+handle_sw_lm_vq_call(vdev, vq);
 }
 }
 
@@ -1028,6 +1061,7 @@ static int vhost_sw_live_migration_start(struct vhost_dev 
*dev)
 
 for (idx = 0; idx < dev->nvqs; ++idx) {
 struct vhost_virtqueue *vq = >vqs[idx];
+unsigned num = virtio_queue_get_num(dev->vdev, idx);
 struct vhost_vring_addr addr = {
 .index = idx,
 };
@@ -1044,6 +1078,12 @@ static int vhost_sw_live_migration_start(struct 
vhost_dev *dev)
 r = dev->vhost_ops->vhost_set_vring_addr(dev, );
 assert(r == 0);
 
+r = vhost_backend_update_device_iotlb(dev, addr.used_user_addr,
+  addr.used_user_addr,
+  sizeof(vring_used_elem_t) * num,
+  IOMMU_RW);
+assert(r == 0);
+
 r = dev->vhost_ops->vhost_set_vring_base(dev, );
 assert(r == 0);
 }
-- 
2.18.4




[RFC PATCH 18/27] vhost: add vhost_vring_poll_rcu

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-sw-lm-ring.h |  2 ++
 hw/virtio/vhost-sw-lm-ring.c | 18 ++
 2 files changed, 20 insertions(+)

diff --git a/hw/virtio/vhost-sw-lm-ring.h b/hw/virtio/vhost-sw-lm-ring.h
index c537500d9e..03257d60c1 100644
--- a/hw/virtio/vhost-sw-lm-ring.h
+++ b/hw/virtio/vhost-sw-lm-ring.h
@@ -22,6 +22,8 @@ int vhost_vring_add(VhostShadowVirtqueue *vq, 
VirtQueueElement *elem);
 
 /* Called within rcu_read_lock().  */
 void vhost_vring_set_notification_rcu(VhostShadowVirtqueue *vq, bool enable);
+/* Called within rcu_read_lock().  */
+bool vhost_vring_poll_rcu(VhostShadowVirtqueue *vq);
 
 void vhost_vring_write_addr(const VhostShadowVirtqueue *vq,
struct vhost_vring_addr *addr);
diff --git a/hw/virtio/vhost-sw-lm-ring.c b/hw/virtio/vhost-sw-lm-ring.c
index c3244c550e..3652889d8e 100644
--- a/hw/virtio/vhost-sw-lm-ring.c
+++ b/hw/virtio/vhost-sw-lm-ring.c
@@ -34,6 +34,12 @@ typedef struct VhostShadowVirtqueue {
 /* Next free descriptor */
 uint16_t free_head;
 
+/* Last seen used idx */
+uint16_t shadow_used_idx;
+
+/* Next head to consume from device */
+uint16_t used_idx;
+
 /* Cache for exposed notification flag */
 bool notification;
 
@@ -83,6 +89,18 @@ void vhost_vring_set_notification_rcu(VhostShadowVirtqueue 
*vq, bool enable)
 smp_mb();
 }
 
+bool vhost_vring_poll_rcu(VhostShadowVirtqueue *vq)
+{
+if (vq->used_idx != vq->shadow_used_idx) {
+return true;
+}
+
+smp_rmb();
+vq->shadow_used_idx = virtio_tswap16(vq->vdev, vq->vring.used->idx);
+
+return vq->used_idx != vq->shadow_used_idx;
+}
+
 static void vhost_vring_write_descs(VhostShadowVirtqueue *vq,
 const struct iovec *iovec,
 size_t num, bool more_descs, bool write)
-- 
2.18.4




[RFC PATCH 09/27] vhost: Route host->guest notification through qemu

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-sw-lm-ring.c |  3 +++
 hw/virtio/vhost.c| 20 
 2 files changed, 23 insertions(+)

diff --git a/hw/virtio/vhost-sw-lm-ring.c b/hw/virtio/vhost-sw-lm-ring.c
index 0192e77831..cbf53965cd 100644
--- a/hw/virtio/vhost-sw-lm-ring.c
+++ b/hw/virtio/vhost-sw-lm-ring.c
@@ -50,6 +50,9 @@ VhostShadowVirtqueue *vhost_sw_lm_shadow_vq(struct vhost_dev 
*dev, int idx)
 r = dev->vhost_ops->vhost_set_vring_kick(dev, );
 assert(r == 0);
 
+vhost_virtqueue_mask(dev, dev->vdev, idx, true);
+vhost_virtqueue_pending(dev, idx);
+
 return svq;
 }
 
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 1d55e26d45..9352c56bfa 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -960,12 +960,29 @@ static void handle_sw_lm_vq(VirtIODevice *vdev, VirtQueue 
*vq)
 vhost_vring_kick(svq);
 }
 
+static void vhost_handle_call(EventNotifier *n)
+{
+struct vhost_virtqueue *hvq = container_of(n,
+  struct vhost_virtqueue,
+  masked_notifier);
+struct vhost_dev *vdev = hvq->dev;
+int idx = vdev->vq_index + (hvq == >vqs[0] ? 0 : 1);
+VirtQueue *vq = virtio_get_queue(vdev->vdev, idx);
+
+if (event_notifier_test_and_clear(n)) {
+virtio_queue_invalidate_signalled_used(vdev->vdev, idx);
+virtio_notify_irqfd(vdev->vdev, vq);
+}
+}
+
 static int vhost_sw_live_migration_stop(struct vhost_dev *dev)
 {
 int idx;
 
 vhost_dev_enable_notifiers(dev, dev->vdev);
 for (idx = 0; idx < dev->nvqs; ++idx) {
+vhost_virtqueue_mask(dev, dev->vdev, idx, false);
+vhost_virtqueue_pending(dev, idx);
 vhost_sw_lm_shadow_vq_free(dev->sw_lm_shadow_vq[idx]);
 }
 
@@ -977,7 +994,10 @@ static int vhost_sw_live_migration_start(struct vhost_dev 
*dev)
 int idx;
 
 for (idx = 0; idx < dev->nvqs; ++idx) {
+struct vhost_virtqueue *vq = >vqs[idx];
+
 dev->sw_lm_shadow_vq[idx] = vhost_sw_lm_shadow_vq(dev, idx);
+event_notifier_set_handler(>masked_notifier, vhost_handle_call);
 }
 
 vhost_dev_disable_notifiers(dev, dev->vdev);
-- 
2.18.4




[RFC PATCH 08/27] vhost: Add a flag for software assisted Live Migration

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 include/hw/virtio/vhost.h |  1 +
 hw/virtio/vhost.c | 17 +++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 93cc3f1ae3..ef920a8076 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -84,6 +84,7 @@ struct vhost_dev {
 uint64_t backend_cap;
 bool started;
 bool log_enabled;
+bool sw_lm_enabled;
 uint64_t log_size;
 VhostShadowVirtqueue *sw_lm_shadow_vq[2];
 VirtIOHandleOutput sw_lm_vq_handler;
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index a55b684b5f..1d55e26d45 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -988,11 +988,16 @@ static int vhost_sw_live_migration_start(struct vhost_dev 
*dev)
 static int vhost_sw_live_migration_enable(struct vhost_dev *dev,
   bool enable_lm)
 {
+int r;
+
 if (enable_lm) {
-return vhost_sw_live_migration_start(dev);
+r = vhost_sw_live_migration_start(dev);
 } else {
-return vhost_sw_live_migration_stop(dev);
+r = vhost_sw_live_migration_stop(dev);
 }
+
+dev->sw_lm_enabled = enable_lm;
+return r;
 }
 
 static void vhost_sw_lm_global_start(MemoryListener *listener)
@@ -1466,6 +1471,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 hdev->log = NULL;
 hdev->log_size = 0;
 hdev->log_enabled = false;
+hdev->sw_lm_enabled = false;
 hdev->started = false;
 memory_listener_register(>memory_listener, _space_memory);
 QLIST_INSERT_HEAD(_devices, hdev, entry);
@@ -1571,6 +1577,13 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, 
VirtIODevice *vdev)
 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
 int i, r;
 
+if (hdev->sw_lm_enabled) {
+/* We've been called after migration is completed, so no need to
+   disable it again
+*/
+return;
+}
+
 for (i = 0; i < hdev->nvqs; ++i) {
 r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i,
  false);
-- 
2.18.4




[RFC PATCH 17/27] vhost: add vhost_vring_set_notification_rcu

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-sw-lm-ring.h |  4 
 hw/virtio/vhost-sw-lm-ring.c | 23 +++
 2 files changed, 27 insertions(+)

diff --git a/hw/virtio/vhost-sw-lm-ring.h b/hw/virtio/vhost-sw-lm-ring.h
index 29d21feaf4..c537500d9e 100644
--- a/hw/virtio/vhost-sw-lm-ring.h
+++ b/hw/virtio/vhost-sw-lm-ring.h
@@ -19,6 +19,10 @@ typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
 
 bool vhost_vring_kick(VhostShadowVirtqueue *vq);
 int vhost_vring_add(VhostShadowVirtqueue *vq, VirtQueueElement *elem);
+
+/* Called within rcu_read_lock().  */
+void vhost_vring_set_notification_rcu(VhostShadowVirtqueue *vq, bool enable);
+
 void vhost_vring_write_addr(const VhostShadowVirtqueue *vq,
struct vhost_vring_addr *addr);
 
diff --git a/hw/virtio/vhost-sw-lm-ring.c b/hw/virtio/vhost-sw-lm-ring.c
index aed005c2d9..c3244c550e 100644
--- a/hw/virtio/vhost-sw-lm-ring.c
+++ b/hw/virtio/vhost-sw-lm-ring.c
@@ -34,6 +34,9 @@ typedef struct VhostShadowVirtqueue {
 /* Next free descriptor */
 uint16_t free_head;
 
+/* Cache for exposed notification flag */
+bool notification;
+
 vring_desc_t descs[];
 } VhostShadowVirtqueue;
 
@@ -60,6 +63,26 @@ bool vhost_vring_kick(VhostShadowVirtqueue *vq)
: true;
 }
 
+void vhost_vring_set_notification_rcu(VhostShadowVirtqueue *vq, bool enable)
+{
+uint16_t notification_flag;
+
+if (vq->notification == enable) {
+return;
+}
+
+notification_flag = virtio_tswap16(vq->vdev, VRING_AVAIL_F_NO_INTERRUPT);
+
+vq->notification = enable;
+if (enable) {
+vq->vring.avail->flags &= ~notification_flag;
+} else {
+vq->vring.avail->flags |= notification_flag;
+}
+
+smp_mb();
+}
+
 static void vhost_vring_write_descs(VhostShadowVirtqueue *vq,
 const struct iovec *iovec,
 size_t num, bool more_descs, bool write)
-- 
2.18.4




[RFC PATCH 15/27] vhost: Do not invalidate signalled used

2020-11-20 Thread Eugenio Pérez
Since we are in control of guest' VQ again, we can trust on it.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 304e0baa61..ac2bc14190 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -996,7 +996,6 @@ static void vhost_handle_call(EventNotifier *n)
 VirtQueue *vq = virtio_get_queue(vdev->vdev, idx);
 
 if (event_notifier_test_and_clear(n)) {
-virtio_queue_invalidate_signalled_used(vdev->vdev, idx);
 virtio_notify_irqfd(vdev->vdev, vq);
 }
 }
-- 
2.18.4




[RFC PATCH 02/27] vhost: Add device callback in vhost_migration_log

2020-11-20 Thread Eugenio Pérez
This allows code to reuse the logic to not to re-enable or re-disable
migration mechanisms. Code works the same way as before.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 2bd8cdf893..2adb2718c1 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -862,7 +862,9 @@ err_features:
 return r;
 }
 
-static int vhost_migration_log(MemoryListener *listener, bool enable)
+static int vhost_migration_log(MemoryListener *listener,
+   bool enable,
+   int (*device_cb)(struct vhost_dev *, bool))
 {
 struct vhost_dev *dev = container_of(listener, struct vhost_dev,
  memory_listener);
@@ -877,14 +879,14 @@ static int vhost_migration_log(MemoryListener *listener, 
bool enable)
 
 r = 0;
 if (!enable) {
-r = vhost_dev_set_log(dev, false);
+r = device_cb(dev, false);
 if (r < 0) {
 goto check_dev_state;
 }
 vhost_log_put(dev, false);
 } else {
 vhost_dev_log_resize(dev, vhost_get_log_size(dev));
-r = vhost_dev_set_log(dev, true);
+r = device_cb(dev, true);
 if (r < 0) {
 goto check_dev_state;
 }
@@ -916,7 +918,7 @@ static void vhost_log_global_start(MemoryListener *listener)
 {
 int r;
 
-r = vhost_migration_log(listener, true);
+r = vhost_migration_log(listener, true, vhost_dev_set_log);
 if (r < 0) {
 abort();
 }
@@ -926,7 +928,7 @@ static void vhost_log_global_stop(MemoryListener *listener)
 {
 int r;
 
-r = vhost_migration_log(listener, false);
+r = vhost_migration_log(listener, false, vhost_dev_set_log);
 if (r < 0) {
 abort();
 }
-- 
2.18.4




[Bug 824074] Re: Provide runtime option to expose the supported list of keymaps for vnc

2020-11-20 Thread Thomas Huth
The QEMU project is currently considering to move its bug tracking to another 
system. For this we need to know which bugs are still valid and which could be 
closed already. Thus we are setting older bugs to "Incomplete" now.
If you still think this bug report here is valid, then please switch the state 
back to "New" within the next 60 days, otherwise this report will be marked as 
"Expired". Or mark it as "Fix Released" if the problem has been solved with a 
newer version of QEMU already. Thank you and sorry for the inconvenience.

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

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

Title:
  Provide runtime option to expose the supported list of keymaps for vnc

Status in QEMU:
  Incomplete

Bug description:
  As discussed in the ganeti group[1], I'm opening this bug to request
  that qemu provides a runtime command or switch to list the supported
  keymaps for vnc.

   [1] -
  http://groups.google.com/group/ganeti/browse_thread/thread/dd524f5311d8d79e

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



[RFC PATCH 07/27] vhost: Route guest->host notification through qemu

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-sw-lm-ring.h |  26 +
 include/hw/virtio/vhost.h|   3 ++
 hw/virtio/vhost-sw-lm-ring.c |  60 +
 hw/virtio/vhost.c| 100 +--
 hw/virtio/meson.build|   2 +-
 5 files changed, 187 insertions(+), 4 deletions(-)
 create mode 100644 hw/virtio/vhost-sw-lm-ring.h
 create mode 100644 hw/virtio/vhost-sw-lm-ring.c

diff --git a/hw/virtio/vhost-sw-lm-ring.h b/hw/virtio/vhost-sw-lm-ring.h
new file mode 100644
index 00..86dc081b93
--- /dev/null
+++ b/hw/virtio/vhost-sw-lm-ring.h
@@ -0,0 +1,26 @@
+/*
+ * vhost software live migration ring
+ *
+ * SPDX-FileCopyrightText: Red Hat, Inc. 2020
+ * SPDX-FileContributor: Author: Eugenio Pérez 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef VHOST_SW_LM_RING_H
+#define VHOST_SW_LM_RING_H
+
+#include "qemu/osdep.h"
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+
+typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
+
+bool vhost_vring_kick(VhostShadowVirtqueue *vq);
+
+VhostShadowVirtqueue *vhost_sw_lm_shadow_vq(struct vhost_dev *dev, int idx);
+
+void vhost_sw_lm_shadow_vq_free(VhostShadowVirtqueue *vq);
+
+#endif
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index b5b7496537..93cc3f1ae3 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -54,6 +54,8 @@ struct vhost_iommu {
 QLIST_ENTRY(vhost_iommu) iommu_next;
 };
 
+typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
+
 typedef struct VhostDevConfigOps {
 /* Vhost device config space changed callback
  */
@@ -83,6 +85,7 @@ struct vhost_dev {
 bool started;
 bool log_enabled;
 uint64_t log_size;
+VhostShadowVirtqueue *sw_lm_shadow_vq[2];
 VirtIOHandleOutput sw_lm_vq_handler;
 Error *migration_blocker;
 const VhostOps *vhost_ops;
diff --git a/hw/virtio/vhost-sw-lm-ring.c b/hw/virtio/vhost-sw-lm-ring.c
new file mode 100644
index 00..0192e77831
--- /dev/null
+++ b/hw/virtio/vhost-sw-lm-ring.c
@@ -0,0 +1,60 @@
+/*
+ * vhost software live migration ring
+ *
+ * SPDX-FileCopyrightText: Red Hat, Inc. 2020
+ * SPDX-FileContributor: Author: Eugenio Pérez 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "hw/virtio/vhost-sw-lm-ring.h"
+#include "hw/virtio/vhost.h"
+
+#include "standard-headers/linux/vhost_types.h"
+#include "standard-headers/linux/virtio_ring.h"
+
+#include "qemu/event_notifier.h"
+
+typedef struct VhostShadowVirtqueue {
+EventNotifier hdev_notifier;
+VirtQueue *vq;
+} VhostShadowVirtqueue;
+
+static inline bool vhost_vring_should_kick(VhostShadowVirtqueue *vq)
+{
+return virtio_queue_get_used_notify_split(vq->vq);
+}
+
+bool vhost_vring_kick(VhostShadowVirtqueue *vq)
+{
+return vhost_vring_should_kick(vq) ? event_notifier_set(>hdev_notifier)
+   : true;
+}
+
+VhostShadowVirtqueue *vhost_sw_lm_shadow_vq(struct vhost_dev *dev, int idx)
+{
+struct vhost_vring_file file = {
+.index = idx
+};
+VirtQueue *vq = virtio_get_queue(dev->vdev, idx);
+VhostShadowVirtqueue *svq;
+int r;
+
+svq = g_new0(VhostShadowVirtqueue, 1);
+svq->vq = vq;
+
+r = event_notifier_init(>hdev_notifier, 0);
+assert(r == 0);
+
+file.fd = event_notifier_get_fd(>hdev_notifier);
+r = dev->vhost_ops->vhost_set_vring_kick(dev, );
+assert(r == 0);
+
+return svq;
+}
+
+void vhost_sw_lm_shadow_vq_free(VhostShadowVirtqueue *vq)
+{
+event_notifier_cleanup(>hdev_notifier);
+g_free(vq);
+}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 9cbd52a7f1..a55b684b5f 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -13,6 +13,8 @@
  * GNU GPL, version 2 or (at your option) any later version.
  */
 
+#include "hw/virtio/vhost-sw-lm-ring.h"
+
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/virtio/vhost.h"
@@ -61,6 +63,20 @@ bool vhost_has_free_slot(void)
 return slots_limit > used_memslots;
 }
 
+static struct vhost_dev *vhost_dev_from_virtio(const VirtIODevice *vdev)
+{
+struct vhost_dev *hdev;
+
+QLIST_FOREACH(hdev, _devices, entry) {
+if (hdev->vdev == vdev) {
+return hdev;
+}
+}
+
+assert(hdev);
+return NULL;
+}
+
 static bool vhost_dev_can_log(const struct vhost_dev *hdev)
 {
 return hdev->features & (0x1ULL << VHOST_F_LOG_ALL);
@@ -148,6 +164,12 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
 return 0;
 }
 
+static void vhost_log_sync_nop(MemoryListener *listener,
+   MemoryRegionSection *section)
+{
+return;
+}
+
 static void vhost_log_sync(MemoryListener *listener,
   MemoryRegionSection *section)
 {
@@ -928,6 +950,71 @@ static void vhost_log_global_stop(MemoryListener *listener)
 }
 }
 
+static void handle_sw_lm_vq(VirtIODevice *vdev, VirtQueue *vq)
+{
+struct vhost_dev *hdev = 

[RFC PATCH 13/27] vhost: Send buffers to device

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-sw-lm-ring.h |   3 +
 hw/virtio/vhost-sw-lm-ring.c | 134 +--
 hw/virtio/vhost.c|  59 ++-
 3 files changed, 189 insertions(+), 7 deletions(-)

diff --git a/hw/virtio/vhost-sw-lm-ring.h b/hw/virtio/vhost-sw-lm-ring.h
index 86dc081b93..29d21feaf4 100644
--- a/hw/virtio/vhost-sw-lm-ring.h
+++ b/hw/virtio/vhost-sw-lm-ring.h
@@ -18,6 +18,9 @@
 typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
 
 bool vhost_vring_kick(VhostShadowVirtqueue *vq);
+int vhost_vring_add(VhostShadowVirtqueue *vq, VirtQueueElement *elem);
+void vhost_vring_write_addr(const VhostShadowVirtqueue *vq,
+   struct vhost_vring_addr *addr);
 
 VhostShadowVirtqueue *vhost_sw_lm_shadow_vq(struct vhost_dev *dev, int idx);
 
diff --git a/hw/virtio/vhost-sw-lm-ring.c b/hw/virtio/vhost-sw-lm-ring.c
index cd7b5ba772..aed005c2d9 100644
--- a/hw/virtio/vhost-sw-lm-ring.c
+++ b/hw/virtio/vhost-sw-lm-ring.c
@@ -9,6 +9,7 @@
 
 #include "hw/virtio/vhost-sw-lm-ring.h"
 #include "hw/virtio/vhost.h"
+#include "hw/virtio/virtio-access.h"
 
 #include "standard-headers/linux/vhost_types.h"
 #include "standard-headers/linux/virtio_ring.h"
@@ -19,21 +20,140 @@ typedef struct VhostShadowVirtqueue {
 struct vring vring;
 EventNotifier hdev_notifier;
 VirtQueue *vq;
+VirtIODevice *vdev;
+
+/* Map for returning guest's descriptors */
+VirtQueueElement **ring_id_maps;
+
+/* Next head to expose to device */
+uint16_t avail_idx_shadow;
+
+/* Number of descriptors added since last notification */
+uint16_t num_added;
+
+/* Next free descriptor */
+uint16_t free_head;
 
 vring_desc_t descs[];
 } VhostShadowVirtqueue;
 
-static inline bool vhost_vring_should_kick(VhostShadowVirtqueue *vq)
+static bool vhost_vring_should_kick_rcu(VhostShadowVirtqueue *vq)
 {
-return virtio_queue_get_used_notify_split(vq->vq);
+VirtIODevice *vdev = vq->vdev;
+vq->num_added = 0;
+
+smp_rmb();
+return !(vq->vring.used->flags
+ & virtio_tswap16(vdev, VRING_USED_F_NO_NOTIFY));
 }
 
+static bool vhost_vring_should_kick(VhostShadowVirtqueue *vq)
+{
+RCU_READ_LOCK_GUARD();
+return vhost_vring_should_kick_rcu(vq);
+}
+
+
 bool vhost_vring_kick(VhostShadowVirtqueue *vq)
 {
 return vhost_vring_should_kick(vq) ? event_notifier_set(>hdev_notifier)
: true;
 }
 
+static void vhost_vring_write_descs(VhostShadowVirtqueue *vq,
+const struct iovec *iovec,
+size_t num, bool more_descs, bool write)
+{
+uint16_t i = vq->free_head, last = vq->free_head;
+unsigned n;
+const VirtIODevice *vdev = vq->vdev;
+uint16_t flags = write ? virtio_tswap16(vdev, VRING_DESC_F_WRITE) : 0;
+vring_desc_t *descs = vq->vring.desc;
+
+if (num == 0) {
+return;
+}
+
+for (n = 0; n < num; n++) {
+if (more_descs || (n + 1 < num)) {
+descs[i].flags = flags | virtio_tswap16(vdev, VRING_DESC_F_NEXT);
+} else {
+descs[i].flags = flags;
+}
+descs[i].addr = virtio_tswap64(vdev, (hwaddr)iovec[n].iov_base);
+descs[i].len = virtio_tswap32(vdev, iovec[n].iov_len);
+
+last = i;
+i = virtio_tswap16(vdev, descs[i].next);
+}
+
+vq->free_head = virtio_tswap16(vdev, descs[last].next);
+}
+
+/* virtqueue_add:
+ * @vq: The #VirtQueue
+ * @elem: The #VirtQueueElement
+ *
+ * Add an avail element to a virtqueue.
+ */
+static int vhost_vring_add_split(VhostShadowVirtqueue *vq,
+ const VirtQueueElement *elem)
+{
+int head;
+unsigned avail_idx;
+const VirtIODevice *vdev;
+vring_avail_t *avail;
+
+RCU_READ_LOCK_GUARD();
+vdev = vq->vdev;
+avail = vq->vring.avail;
+
+head = vq->free_head;
+
+/* We need some descriptors here */
+assert(elem->out_num || elem->in_num);
+
+vhost_vring_write_descs(vq, elem->out_sg, elem->out_num,
+   elem->in_num > 0, false);
+vhost_vring_write_descs(vq, elem->in_sg, elem->in_num, false, true);
+
+/* Put entry in available array (but don't update avail->idx until they
+ * do sync). */
+avail_idx = vq->avail_idx_shadow & (vq->vring.num - 1);
+avail->ring[avail_idx] = virtio_tswap16(vdev, head);
+vq->avail_idx_shadow++;
+
+/* Expose descriptors to device */
+smp_wmb();
+avail->idx = virtio_tswap16(vdev, vq->avail_idx_shadow);
+
+/* threoretically possible. Kick just in case */
+if (unlikely(vq->num_added++ == (uint16_t)-1)) {
+vhost_vring_kick(vq);
+}
+
+return head;
+}
+
+int vhost_vring_add(VhostShadowVirtqueue *vq, VirtQueueElement *elem)
+{
+int host_head = vhost_vring_add_split(vq, elem);
+if (vq->ring_id_maps[host_head]) {
+g_free(vq->ring_id_maps[host_head]);
+}
+
+

[RFC PATCH 00/27] vDPA software assisted live migration

2020-11-20 Thread Eugenio Pérez
This series enable vDPA software assisted live migration for vhost-net
devices. This is a new method of vhost devices migration: Instead of
relay on vDPA device's dirty logging capability, SW assisted LM
intercepts dataplane, forwarding the descriptors between VM and device.

In this migration mode, qemu offers a new vring to the device to
read and write into, and disable vhost notifiers, processing guest and
vhost notifications in qemu. On used buffer relay, qemu will mark the
dirty memory as with plain virtio-net devices. This way, devices does
not need to have dirty page logging capability.

This series is a POC doing SW LM for vhost-net devices, which already
have dirty page logging capabilities. None of the changes have actual
effect with current devices until last two patches (26 and 27) are
applied, but they can be rebased on top of any other. These checks the
device to meet all requirements, and disable vhost-net devices logging
so migration goes through SW LM. This last patch is not meant to be
applied in the final revision, it is in the series just for testing
purposes.

For use SW assisted LM these vhost-net devices need to be instantiated:
* With IOMMU (iommu_platform=on,ats=on)
* Without event_idx (event_idx=off)

Just the notification forwarding (with no descriptor relay) can be
achieved with patches 7 and 9, and starting migration. Partial applies
between 13 and 24 will not work while migrating on source, and patch
25 is needed for the destination to resume network activity.

It is based on the ideas of DPDK SW assisted LM, in the series of
DPDK's https://patchwork.dpdk.org/cover/48370/ .

Comments are welcome.

Thanks!

Eugenio Pérez (27):
  vhost: Add vhost_dev_can_log
  vhost: Add device callback in vhost_migration_log
  vhost: Move log resize/put to vhost_dev_set_log
  vhost: add vhost_kernel_set_vring_enable
  vhost: Add hdev->dev.sw_lm_vq_handler
  virtio: Add virtio_queue_get_used_notify_split
  vhost: Route guest->host notification through qemu
  vhost: Add a flag for software assisted Live Migration
  vhost: Route host->guest notification through qemu
  vhost: Allocate shadow vring
  virtio: const-ify all virtio_tswap* functions
  virtio: Add virtio_queue_full
  vhost: Send buffers to device
  virtio: Remove virtio_queue_get_used_notify_split
  vhost: Do not invalidate signalled used
  virtio: Expose virtqueue_alloc_element
  vhost: add vhost_vring_set_notification_rcu
  vhost: add vhost_vring_poll_rcu
  vhost: add vhost_vring_get_buf_rcu
  vhost: Return used buffers
  vhost: Add vhost_virtqueue_memory_unmap
  vhost: Add vhost_virtqueue_memory_map
  vhost: unmap qemu's shadow virtqueues on sw live migration
  vhost: iommu changes
  vhost: Do not commit vhost used idx on vhost_virtqueue_stop
  vhost: Add vhost_hdev_can_sw_lm
  vhost: forbid vhost devices logging

 hw/virtio/vhost-sw-lm-ring.h  |  39 +++
 include/hw/virtio/vhost.h |   5 +
 include/hw/virtio/virtio-access.h |   8 +-
 include/hw/virtio/virtio.h|   4 +
 hw/net/virtio-net.c   |  39 ++-
 hw/virtio/vhost-backend.c |  29 ++
 hw/virtio/vhost-sw-lm-ring.c  | 268 +++
 hw/virtio/vhost.c | 431 +-
 hw/virtio/virtio.c|  18 +-
 hw/virtio/meson.build |   2 +-
 10 files changed, 758 insertions(+), 85 deletions(-)
 create mode 100644 hw/virtio/vhost-sw-lm-ring.h
 create mode 100644 hw/virtio/vhost-sw-lm-ring.c

-- 
2.18.4




[RFC PATCH 06/27] virtio: Add virtio_queue_get_used_notify_split

2020-11-20 Thread Eugenio Pérez
This function is just used for a few commits, so SW LM is developed
incrementally, and it is deleted after it is useful.

For a few commits, only the events (irqfd, eventfd) are forwarded.
This series adds descriptors forwarding on top of that.

Signed-off-by: Eugenio Pérez 
---
 include/hw/virtio/virtio.h |  1 +
 hw/virtio/virtio.c | 14 ++
 2 files changed, 15 insertions(+)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b7ece7a6a8..b9b8497ea0 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -225,6 +225,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id);
 
 void virtio_notify_config(VirtIODevice *vdev);
 
+bool virtio_queue_get_used_notify_split(VirtQueue *vq);
 bool virtio_queue_get_notification(VirtQueue *vq);
 void virtio_queue_set_notification(VirtQueue *vq, int enable);
 
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ceb58fda6c..3469946538 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -377,6 +377,20 @@ static inline void vring_used_idx_set(VirtQueue *vq, 
uint16_t val)
 vq->used_idx = val;
 }
 
+bool virtio_queue_get_used_notify_split(VirtQueue *vq)
+{
+VRingMemoryRegionCaches *caches;
+hwaddr pa = offsetof(VRingUsed, flags);
+uint16_t flags;
+
+RCU_READ_LOCK_GUARD();
+
+caches = vring_get_region_caches(vq);
+assert(caches);
+flags = virtio_lduw_phys_cached(vq->vdev, >used, pa);
+return !(VRING_USED_F_NO_NOTIFY & flags);
+}
+
 /* Called within rcu_read_lock().  */
 static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
 {
-- 
2.18.4




[RFC PATCH 11/27] virtio: const-ify all virtio_tswap* functions

2020-11-20 Thread Eugenio Pérez
They do not modify vdev, so these should be const as qemu coding style
guideline.

Signed-off-by: Eugenio Pérez 
---
 include/hw/virtio/virtio-access.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/hw/virtio/virtio-access.h 
b/include/hw/virtio/virtio-access.h
index 6818a23a2d..7474f89b5f 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -24,7 +24,7 @@
 #define LEGACY_VIRTIO_IS_BIENDIAN 1
 #endif
 
-static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
+static inline bool virtio_access_is_big_endian(const VirtIODevice *vdev)
 {
 #if defined(LEGACY_VIRTIO_IS_BIENDIAN)
 return virtio_is_big_endian(vdev);
@@ -147,7 +147,7 @@ static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, 
const void *ptr)
 }
 }
 
-static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s)
+static inline uint16_t virtio_tswap16(const VirtIODevice *vdev, uint16_t s)
 {
 #ifdef HOST_WORDS_BIGENDIAN
 return virtio_access_is_big_endian(vdev) ? s : bswap16(s);
@@ -213,7 +213,7 @@ static inline void virtio_tswap16s(VirtIODevice *vdev, 
uint16_t *s)
 *s = virtio_tswap16(vdev, *s);
 }
 
-static inline uint32_t virtio_tswap32(VirtIODevice *vdev, uint32_t s)
+static inline uint32_t virtio_tswap32(const VirtIODevice *vdev, uint32_t s)
 {
 #ifdef HOST_WORDS_BIGENDIAN
 return virtio_access_is_big_endian(vdev) ? s : bswap32(s);
@@ -227,7 +227,7 @@ static inline void virtio_tswap32s(VirtIODevice *vdev, 
uint32_t *s)
 *s = virtio_tswap32(vdev, *s);
 }
 
-static inline uint64_t virtio_tswap64(VirtIODevice *vdev, uint64_t s)
+static inline uint64_t virtio_tswap64(const VirtIODevice *vdev, uint64_t s)
 {
 #ifdef HOST_WORDS_BIGENDIAN
 return virtio_access_is_big_endian(vdev) ? s : bswap64(s);
-- 
2.18.4




[RFC PATCH 04/27] vhost: add vhost_kernel_set_vring_enable

2020-11-20 Thread Eugenio Pérez
Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost-backend.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 222bbcc62d..317f1f96fa 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -201,6 +201,34 @@ static int vhost_kernel_get_vq_index(struct vhost_dev 
*dev, int idx)
 return idx - dev->vq_index;
 }
 
+static int vhost_kernel_set_vq_enable(struct vhost_dev *dev, unsigned idx,
+  bool enable)
+{
+struct vhost_vring_file file = {
+.index = idx,
+};
+
+if (!enable) {
+file.fd = -1; /* Pass -1 to unbind from file. */
+} else {
+struct vhost_net *vn_dev = container_of(dev, struct vhost_net, dev);
+file.fd = vn_dev->backend;
+}
+
+return vhost_kernel_net_set_backend(dev, );
+}
+
+static int vhost_kernel_set_vring_enable(struct vhost_dev *dev, int enable)
+{
+int i;
+
+for (i = 0; i < dev->nvqs; ++i) {
+vhost_kernel_set_vq_enable(dev, i, enable);
+}
+
+return 0;
+}
+
 #ifdef CONFIG_VHOST_VSOCK
 static int vhost_kernel_vsock_set_guest_cid(struct vhost_dev *dev,
 uint64_t guest_cid)
@@ -317,6 +345,7 @@ static const VhostOps kernel_ops = {
 .vhost_set_owner = vhost_kernel_set_owner,
 .vhost_reset_device = vhost_kernel_reset_device,
 .vhost_get_vq_index = vhost_kernel_get_vq_index,
+.vhost_set_vring_enable = vhost_kernel_set_vring_enable,
 #ifdef CONFIG_VHOST_VSOCK
 .vhost_vsock_set_guest_cid = vhost_kernel_vsock_set_guest_cid,
 .vhost_vsock_set_running = vhost_kernel_vsock_set_running,
-- 
2.18.4




[RFC PATCH 05/27] vhost: Add hdev->dev.sw_lm_vq_handler

2020-11-20 Thread Eugenio Pérez
Only virtio-net honors it.

Signed-off-by: Eugenio Pérez 
---
 include/hw/virtio/vhost.h |  1 +
 hw/net/virtio-net.c   | 39 ---
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 4a8bc75415..b5b7496537 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -83,6 +83,7 @@ struct vhost_dev {
 bool started;
 bool log_enabled;
 uint64_t log_size;
+VirtIOHandleOutput sw_lm_vq_handler;
 Error *migration_blocker;
 const VhostOps *vhost_ops;
 void *opaque;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9179013ac4..9a69ae3598 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2628,24 +2628,32 @@ static void virtio_net_tx_bh(void *opaque)
 }
 }
 
-static void virtio_net_add_queue(VirtIONet *n, int index)
+static void virtio_net_add_queue(VirtIONet *n, int index,
+ VirtIOHandleOutput custom_handler)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(n);
+VirtIOHandleOutput rx_vq_handler = virtio_net_handle_rx;
+VirtIOHandleOutput tx_vq_handler;
+bool tx_timer = n->net_conf.tx && !strcmp(n->net_conf.tx, "timer");
+
+if (custom_handler) {
+rx_vq_handler = tx_vq_handler = custom_handler;
+} else if (tx_timer) {
+tx_vq_handler = virtio_net_handle_tx_timer;
+} else {
+tx_vq_handler = virtio_net_handle_tx_bh;
+}
 
 n->vqs[index].rx_vq = virtio_add_queue(vdev, n->net_conf.rx_queue_size,
-   virtio_net_handle_rx);
+   rx_vq_handler);
+n->vqs[index].tx_vq = virtio_add_queue(vdev, n->net_conf.tx_queue_size,
+   tx_vq_handler);
 
-if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
-n->vqs[index].tx_vq =
-virtio_add_queue(vdev, n->net_conf.tx_queue_size,
- virtio_net_handle_tx_timer);
+if (tx_timer) {
 n->vqs[index].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
   virtio_net_tx_timer,
   >vqs[index]);
 } else {
-n->vqs[index].tx_vq =
-virtio_add_queue(vdev, n->net_conf.tx_queue_size,
- virtio_net_handle_tx_bh);
 n->vqs[index].tx_bh = qemu_bh_new(virtio_net_tx_bh, >vqs[index]);
 }
 
@@ -2677,6 +2685,10 @@ static void virtio_net_del_queue(VirtIONet *n, int index)
 static void virtio_net_change_num_queues(VirtIONet *n, int new_max_queues)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(n);
+NetClientState *nc = n->nic->conf->peers.ncs[0];
+struct vhost_net *hdev = get_vhost_net(nc);
+VirtIOHandleOutput custom_handler = hdev ? hdev->dev.sw_lm_vq_handler
+ : NULL;
 int old_num_queues = virtio_get_num_queues(vdev);
 int new_num_queues = new_max_queues * 2 + 1;
 int i;
@@ -2702,7 +2714,7 @@ static void virtio_net_change_num_queues(VirtIONet *n, 
int new_max_queues)
 
 for (i = old_num_queues - 1; i < new_num_queues - 1; i += 2) {
 /* new_num_queues > old_num_queues */
-virtio_net_add_queue(n, i / 2);
+virtio_net_add_queue(n, i / 2, custom_handler);
 }
 
 /* add ctrl_vq last */
@@ -3256,6 +3268,8 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
 VirtIONet *n = VIRTIO_NET(dev);
 NetClientState *nc;
+struct vhost_net *hdev;
+VirtIOHandleOutput custom_handler;
 int i;
 
 if (n->net_conf.mtu) {
@@ -3347,8 +3361,11 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 n->net_conf.tx_queue_size = MIN(virtio_net_max_tx_queue_size(n),
 n->net_conf.tx_queue_size);
 
+nc = n->nic_conf.peers.ncs[0];
+hdev = get_vhost_net(nc);
+custom_handler = hdev ? hdev->dev.sw_lm_vq_handler : NULL;
 for (i = 0; i < n->max_queues; i++) {
-virtio_net_add_queue(n, i);
+virtio_net_add_queue(n, i, custom_handler);
 }
 
 n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
-- 
2.18.4




[PATCH] virtio: reset device on bad guest index in virtio_load()

2020-11-20 Thread John Levon


If we find a queue with an inconsistent guest index value, explicitly mark the
device as needing a reset - and broken - via virtio_error().

There's at least one driver implementation - the virtio-win NetKVM driver - that
is able to handle a VIRTIO_CONFIG_S_NEEDS_RESET notification and successfully
restore the device to a working state. Other implementations do not correctly
handle this, but as the VQ is not in a functional state anyway, this is still
worth doing.

Signed-off-by: John Levon 
---
 hw/virtio/virtio.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ceb58fda6c..eff35fab7c 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3161,12 +3161,15 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
 nheads = vring_avail_idx(>vq[i]) - 
vdev->vq[i].last_avail_idx;
 /* Check it isn't doing strange things with descriptor numbers. */
 if (nheads > vdev->vq[i].vring.num) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "VQ %d size 0x%x Guest index 0x%x "
-  "inconsistent with Host index 0x%x: delta 0x%x",
-  i, vdev->vq[i].vring.num,
-  vring_avail_idx(>vq[i]),
-  vdev->vq[i].last_avail_idx, nheads);
+virtio_error(vdev, "VQ %d size 0x%x Guest index 0x%x "
+ "inconsistent with Host index 0x%x: delta 0x%x",
+ i, vdev->vq[i].vring.num,
+ vring_avail_idx(>vq[i]),
+ vdev->vq[i].last_avail_idx, nheads);
+vdev->vq[i].used_idx = 0;
+vdev->vq[i].shadow_avail_idx = 0;
+vdev->vq[i].inuse = 0;
+continue;
 }
 vdev->vq[i].used_idx = vring_used_idx(>vq[i]);
 vdev->vq[i].shadow_avail_idx = vring_avail_idx(>vq[i]);
-- 
2.22.3



[Bug 1214884] Re: Support VDI (Virtualbox) snapshots

2020-11-20 Thread Thomas Huth
The QEMU project is currently considering to move its bug tracking to another 
system. For this we need to know which bugs are still valid and which could be 
closed already. Thus we are setting older bugs to "Incomplete" now.
If you still think this bug report here is valid, then please switch the state 
back to "New" within the next 60 days, otherwise this report will be marked as 
"Expired". Or mark it as "Fix Released" if the problem has been solved with a 
newer version of QEMU already. Thank you and sorry for the inconvenience.

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

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

Title:
  Support VDI (Virtualbox) snapshots

Status in QEMU:
  Incomplete

Bug description:
  Please support Snapshots in VDI images.

  It seems that VirtualBox uses a snapshot for any changes to the main
  system disc. Even when the user does not create a snapshot.

  So if I want to mount a VDI disc with the recent system changes, I
  have to mount the Snapshot.

  Thanks

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



[RFC PATCH 01/27] vhost: Add vhost_dev_can_log

2020-11-20 Thread Eugenio Pérez
Just syntactic sugar.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 614ccc2bcb..2bd8cdf893 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -61,6 +61,11 @@ bool vhost_has_free_slot(void)
 return slots_limit > used_memslots;
 }
 
+static bool vhost_dev_can_log(const struct vhost_dev *hdev)
+{
+return hdev->features & (0x1ULL << VHOST_F_LOG_ALL);
+}
+
 static void vhost_dev_sync_region(struct vhost_dev *dev,
   MemoryRegionSection *section,
   uint64_t mfirst, uint64_t mlast,
@@ -1347,7 +1352,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 };
 
 if (hdev->migration_blocker == NULL) {
-if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
+if (!vhost_dev_can_log(hdev)) {
 error_setg(>migration_blocker,
"Migration disabled: vhost lacks VHOST_F_LOG_ALL 
feature.");
 } else if (vhost_dev_log_is_shared(hdev) && !qemu_memfd_alloc_check()) 
{
-- 
2.18.4




[RFC PATCH 03/27] vhost: Move log resize/put to vhost_dev_set_log

2020-11-20 Thread Eugenio Pérez
Software assisted live migration does not allocate vhost log.

Signed-off-by: Eugenio Pérez 
---
 hw/virtio/vhost.c | 24 +---
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 2adb2718c1..9cbd52a7f1 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -828,6 +828,10 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool 
enable_log)
 int r, i, idx;
 hwaddr addr;
 
+if (enable_log) {
+vhost_dev_log_resize(dev, vhost_get_log_size(dev));
+}
+
 r = vhost_dev_set_features(dev, enable_log);
 if (r < 0) {
 goto err_features;
@@ -850,6 +854,10 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool 
enable_log)
 goto err_vq;
 }
 }
+
+if (!enable_log) {
+vhost_log_put(dev, false);
+}
 return 0;
 err_vq:
 for (; i >= 0; --i) {
@@ -877,22 +885,8 @@ static int vhost_migration_log(MemoryListener *listener,
 return 0;
 }
 
-r = 0;
-if (!enable) {
-r = device_cb(dev, false);
-if (r < 0) {
-goto check_dev_state;
-}
-vhost_log_put(dev, false);
-} else {
-vhost_dev_log_resize(dev, vhost_get_log_size(dev));
-r = device_cb(dev, true);
-if (r < 0) {
-goto check_dev_state;
-}
-}
+r = device_cb(dev, enable);
 
-check_dev_state:
 dev->log_enabled = enable;
 /*
  * vhost-user-* devices could change their state during log
-- 
2.18.4




[Bug 1284090] Re: RFE: QMP: report error reason in BLOCK_IO_ERROR message

2020-11-20 Thread Thomas Huth
The QEMU project is currently considering to move its bug tracking to another 
system. For this we need to know which bugs are still valid and which could be 
closed already. Thus we are setting older bugs to "Incomplete" now.
If you still think this bug report here is valid, then please switch the state 
back to "New" within the next 60 days, otherwise this report will be marked as 
"Expired". Or mark it as "Fix Released" if the problem has been solved with a 
newer version of QEMU already. Thank you and sorry for the inconvenience.

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

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

Title:
  RFE: QMP: report error reason in BLOCK_IO_ERROR message

Status in QEMU:
  Incomplete

Bug description:
  when a disk drive is configured with the error policy enospc for write 
errors, the monitoring client needs a way to distinguish
  betwwen generic I/O error and the I/O error for space exausted.

  The JSON QMP protocol lacks this information: the BLOCK_IO_ERROR
  message does not provide a reason or code for the error verified, so
  the monitoring client cannot distinguish the source of the errors.

  verified against git 105a060188dc6fdd4551571a966514d1a5f6815a

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



Re: [RFC v4 9/9] i386: split cpu accelerators from cpu.c

2020-11-20 Thread Claudio Fontana
On 11/20/20 6:44 PM, Eduardo Habkost wrote:
> On Fri, Nov 20, 2020 at 03:49:09PM +0100, Claudio Fontana wrote:
>> split cpu.c into:
>>
>> cpu.ccpuid and common x86 cpu functionality
>> host-cpu.c   host x86 cpu functions and "host" cpu type
>> kvm/cpu.cKVM x86 cpu type
>> hvf/cpu.cHVF x86 cpu type
>> tcg/cpu.cTCG x86 cpu type
>>
>> The link to the accel class is set in the X86CPUClass classes
>> at MODULE_INIT_ACCEL_CPU time, when the accelerator is known.
>>
>> Signed-off-by: Claudio Fontana 
> [...]
>> +static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data)
>> +{
>> +X86CPUAccelClass *acc = X86_CPU_ACCEL_CLASS(oc);
>> +
>> +acc->cpu_realizefn = host_cpu_realizefn;
>> +acc->cpu_common_class_init = hvf_cpu_common_class_init;
>> +acc->cpu_instance_init = hvf_cpu_instance_init;
>> +};
>> +static const TypeInfo hvf_cpu_accel_type_info = {
>> +.name = X86_CPU_ACCEL_TYPE_NAME("hvf"),
>> +
>> +.parent = TYPE_X86_CPU_ACCEL,
>> +.class_init = hvf_cpu_accel_class_init,
>> +};
>> +static void hvf_cpu_accel_register_types(void)
>> +{
>> +type_register_static(_cpu_accel_type_info);
>> +}
>> +type_init(hvf_cpu_accel_register_types);
>> +
>> +static void hvf_cpu_accel_init(void)
>> +{
>> +if (hvf_enabled()) {
>> +x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME("hvf"));
>> +}
>> +}
>> +
>> +accel_cpu_init(hvf_cpu_accel_init);
> 
> The point of my suggestion of using QOM is to not require
> separate accel_cpu_init() functions and (hvf|tcg|kvm)_enabled()
> checks.
> 
> If we still have separate accel_cpu_init() functions for calling
> x86_cpu_accel_init() with the right argument, using a pointer to
> static variables like _cpu_accel (like you did before) was
> simpler and required less boilerplate code.



Yes I agree.




> 
> However, the difference is that with the X86_CPU_ACCEL_TYPE_NAME
> macro + object_class_by_name(), you don't need the separate
> accel_cpu_init() functions for each accelerator.
> 
> All you need is a single:
> 
>   x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME(chosen_accel_name));
> 
> call somewhere in the initialization path.


Makes sense. The problem is just determining chosen_accel_name.


> 
> A good place for the x86_cpu_accel_init() call would be
> do_configure_accelerator(), but the function is arch-specific.
> That's why I suggested a cpu_accel_arch_init() function at
> https://lore.kernel.org/qemu-devel/20201118220750.gp1509...@habkost.net
> 


Fine by me. I'd use a specific init step for this, but that also works.

Ciao,

Clauidio




[PATCH] virtio: reset device on bad guest index in virtio_load()

2020-11-20 Thread John Levon


If we find a queue with an inconsistent guest index value, explicitly mark the
device as needing a reset - and broken - via virtio_error().

There's at least one driver implementation - the virtio-win NetKVM driver - that
is able to handle a VIRTIO_CONFIG_S_NEEDS_RESET notification and successfully
restore the device to a working state. Other implementations do not correctly
handle this, but as the VQ is not in a functional state anyway, this is still
worth doing.

Signed-off-by: John Levon 
---
 hw/virtio/virtio.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ceb58fda6c..eff35fab7c 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3161,12 +3161,15 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
 nheads = vring_avail_idx(>vq[i]) - 
vdev->vq[i].last_avail_idx;
 /* Check it isn't doing strange things with descriptor numbers. */
 if (nheads > vdev->vq[i].vring.num) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "VQ %d size 0x%x Guest index 0x%x "
-  "inconsistent with Host index 0x%x: delta 0x%x",
-  i, vdev->vq[i].vring.num,
-  vring_avail_idx(>vq[i]),
-  vdev->vq[i].last_avail_idx, nheads);
+virtio_error(vdev, "VQ %d size 0x%x Guest index 0x%x "
+ "inconsistent with Host index 0x%x: delta 0x%x",
+ i, vdev->vq[i].vring.num,
+ vring_avail_idx(>vq[i]),
+ vdev->vq[i].last_avail_idx, nheads);
+vdev->vq[i].used_idx = 0;
+vdev->vq[i].shadow_avail_idx = 0;
+vdev->vq[i].inuse = 0;
+continue;
 }
 vdev->vq[i].used_idx = vring_used_idx(>vq[i]);
 vdev->vq[i].shadow_avail_idx = vring_avail_idx(>vq[i]);
-- 
2.22.3



Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 06:29:16AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > On Thu, Nov 19, 2020 at 11:24:52AM +0100, Markus Armbruster wrote:
> >> Marc-André Lureau  writes:
> >> 
> >> > On Tue, Nov 17, 2020 at 6:42 PM Eduardo Habkost  
> >> > wrote:
> >> >
> >> >> On Tue, Nov 17, 2020 at 12:37:56PM +0400, Marc-André Lureau wrote:
> >> >> > On Tue, Nov 17, 2020 at 2:43 AM Eduardo Habkost 
> >> >> wrote:
> >> >> >
> >> >> > > Provide a separate QNumValue type that can be used for QNum value
> >> >> > > literals without the referencing counting and memory allocation
> >> >> > > features provided by QObject.
> >> >> > >
> >> >> > > Signed-off-by: Eduardo Habkost 
> >> >> > > ---
> >> >> > > Changes v1 -> v2:
> >> >> > > * Fix "make check" failure, by updating check-qnum unit test to
> >> >> > >   use the new struct fields
> >> >> > > ---
> >> >> > >  include/qapi/qmp/qnum.h | 40 +++--
> >> >> > >  qobject/qnum.c  | 78 
> >> >> > > -
> >> >> > >  tests/check-qnum.c  | 14 
> >> >> > >  3 files changed, 84 insertions(+), 48 deletions(-)
> >> >> > >
> >> >> > > diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
> >> >> > > index 55c27b1c24..62fbdfda68 100644
> >> >> > > --- a/include/qapi/qmp/qnum.h
> >> >> > > +++ b/include/qapi/qmp/qnum.h
> >> >> > > @@ -46,20 +46,56 @@ typedef enum {
> >> >> > >   * in range: qnum_get_try_int() / qnum_get_try_uint() check range 
> >> >> > > and
> >> >> > >   * convert under the hood.
> >> >> > >   */
> >> >> > > -struct QNum {
> >> >> > > -struct QObjectBase_ base;
> >> >> > > +
> >> >> > > +/**
> >> >> > > + * struct QNumValue: the value of a QNum
> >> >> > > + *
> >> >> > > + * QNumValue literals can be constructed using the `QNUM_VAL_INT`,
> >> >> > > + * `QNUM_VAL_UINT`, and `QNUM_VAL_DOUBLE` macros.
> >> >> > > + */
> >> >> > > +typedef struct QNumValue {
> >> >> > > +/* private: */
> >> 
> >> Do we care?
> >
> > Are you asking if we want to make them private, or if we want to
> > document them as private (assuming they are).
> >
> > The answer to the latter is yes ("private:" is an indication to
> > kernel-doc).  The answer to the former seems to be "no", based on
> > your other comments.
> >
> > Or maybe `kind` should be public and `u` should be private?
> 
> You're factoring out a part of struct QNum into new struct QNumValue.
> struct QNum is not private before the patch.  I see no need to start
> making it or parts of it private now.

I don't want to change the rules, just to document the existing
implicit rules.  If you say QNum.u was never private, I won't
argue.

> 
> When the structure of a data type is to be kept away from its users, I
> prefer to keep it out of the public header, so the compiler enforces the
> encapsulation.

I prefer that too, except that it is impossible when users of the
API need the compiler to know the struct size.

-- 
Eduardo




Re: [PATCH v2 4/8] qnum: qnum_value_is_equal() function

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 07:52:31AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > On Thu, Nov 19, 2020 at 11:27:40AM +0100, Markus Armbruster wrote:
> > [...]
> >> > +bool qnum_is_equal(const QObject *x, const QObject *y)
> >> > +{
> >> > +const QNum *qnum_x = qobject_to(QNum, x);
> >> > +const QNum *qnum_y = qobject_to(QNum, y);
> >> 
> >> Humor me: blank line between declarations and statements, please.
> >
> > I can do it.  But why do you prefer it that way?
> 
> Habit borne out of C lacking other visual cues to distinguish
> declarations and statements.

Why is the distinction important, when many variable declarations
also include initializer expressions that can be as complex as
other statements?

(The qobject_to() calls above are an example).

> 
> Declaration or statement?  Tell me quick, don't analyze!
> 
> mumble(*mutter)();
> 
> This "obviously" declares @mutter as pointer to function returning
> mumble.
> 
> Except when @mumble isn't a typedef name, but a function taking one
> argument and returning a function that takes no argument.  Then it
> passes *mutter to mumble(), and calls its return value.
> 
> The whole point of coding style is to help readers along.  Two stylistic
> conventions that can help here:
> 
> 1. In a function call, no space between the expression denoting the
>called function and the (parenthesized) argument list.  Elsewhere,
>space.
> 
>So, when the example above is indeed a declaration, write it as
> 
> mumble (*mutter)();
> 
>If it's function calls, write it as
> 
> mumble(*mutter)();

This makes lots of sense.  Starting with a word followed by space
is what makes declarations visually distinguishable.

> 
> 2. Separate declarations from statements with a blank line.  Do not mix
>them.

I'm not sure about this one, and I'm actually glad it is not part
of CODING_STYLE.  :)

(I'll still follow your advice as maintainer of that piece of
code, of course)

-- 
Eduardo




Re: [PATCH RFC 0/5] Fix accidental crash in iotest 30

2020-11-20 Thread Vladimir Sementsov-Ogievskiy

20.11.2020 20:22, Kevin Wolf wrote:

Am 20.11.2020 um 17:43 hat Vladimir Sementsov-Ogievskiy geschrieben:

20.11.2020 19:36, Kevin Wolf wrote:

Am 20.11.2020 um 17:16 hat Vladimir Sementsov-Ogievskiy geschrieben:

Hi all!

As Peter recently noted, iotest 30 accidentally fails.

I found that Qemu crashes due to interleaving of graph-update
operations of parallel mirror and stream block-jobs.


I haven't found the time yet to properly look into this or your other
thread where you had a similar question, but there is one thing I'm
wondering: Why can the nested job even make progress and run its
completion handler?

When we modify the graph, we should have drained the subtree in
question, so in theory while one job finishes and modifies the graph,
there should be no way for the other job to make progress and get
interleaved - it shouldn't be able to start I/O requests and much less
to run its completion handler and modify the graph.

Are we missing drained sections somewhere or do they fail to achieve
what I think they should achieve?



It all looks like both jobs are reached their finish simultaneously.
So, all progress is done in both jobs. And they go concurrently to
completion procedures which interleaves. So, there no more io through
blk, which is restricted by drained sections.


They can't be truly simultaneous because they run in the same thread.
During job completion, this is the main thread.


No, they not truly simultaneous, but completions may interleave through nested 
aio_poll loops.



However as soon as job_is_completed() returns true, it seems we're not
pausing the job any more when one of its nodes gets drained.

Possibly also relevant: The job->busy = false in job_exit(). The comment
there says it's a lie, but we might deadlock otherwise.

This problem will probably affect other callers, too, which drain a
subtree and then resonably expect that nobody will modify the graph
until they end the drained section. So I think the problem that we need
to address is that jobs run their completion handlers even though they
are supposed to be paused by a drain.


Hmm. I always thought about drained section as about thing that stops IO 
requests, not other operations.. And we do graph modifications in drained 
section to avoid in-flight IO requests during graph modification.



I'm not saying that your graph modification locks are a bad idea, but
they are probably not a complete solution.



Hmm. What do you mean? It's of course not complete, as I didn't protect every 
graph modification procedure.. But if we do protect all such things and do 
graph modifications always under this mutex, it should work I think.

--
Best regards,
Vladimir



[PATCH v2 1/2] Update linux headers

2020-11-20 Thread Eric Farman
This is a placeholder for a proper run of scripts/update-linux-headers.sh

Signed-off-by: Eric Farman 
---
 linux-headers/linux/vfio.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index b92dcc4daf..609099e455 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -820,6 +820,7 @@ enum {
 enum {
VFIO_CCW_IO_IRQ_INDEX,
VFIO_CCW_CRW_IRQ_INDEX,
+   VFIO_CCW_REQ_IRQ_INDEX,
VFIO_CCW_NUM_IRQS
 };
 
-- 
2.17.1




[PATCH v2 0/2] vfio-ccw: Implement request notifier

2020-11-20 Thread Eric Farman
Updated QEMU code for the request notifier, to match version 2
of the kernel code [1]. No changes since the v1/RFC [2],
other than including Conny's r-b on patch 2 (Thank you!).

This registers the QEMU vfio-ccw code's ability to respond to
a request from the kernel to release the device, because of a
(probably fatal) device error that has removed it from the host
configuration, and thus its ability to be used by the guest.

[1] https://lore.kernel.org/kvm/20201120180740.87837-1-far...@linux.ibm.com/
[2] 
https://lore.kernel.org/qemu-devel/20201117032605.56831-1-far...@linux.ibm.com/

Eric Farman (2):
  Update linux headers
  vfio-ccw: Connect the device request notifier

 hw/vfio/ccw.c  | 40 ++
 linux-headers/linux/vfio.h |  1 +
 2 files changed, 37 insertions(+), 4 deletions(-)

-- 
2.17.1




[PATCH v2 2/2] vfio-ccw: Connect the device request notifier

2020-11-20 Thread Eric Farman
Now that the vfio-ccw code has a notifier interface to request that
a device be unplugged, let's wire that together.

Signed-off-by: Eric Farman 
Reviewed-by: Cornelia Huck 
---
 hw/vfio/ccw.c | 40 
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index d2755d7fc5..bc78a0ad76 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -49,6 +49,7 @@ struct VFIOCCWDevice {
 struct ccw_crw_region *crw_region;
 EventNotifier io_notifier;
 EventNotifier crw_notifier;
+EventNotifier req_notifier;
 bool force_orb_pfch;
 bool warned_orb_pfch;
 };
@@ -287,6 +288,21 @@ static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev)
 } while (1);
 }
 
+static void vfio_ccw_req_notifier_handler(void *opaque)
+{
+VFIOCCWDevice *vcdev = opaque;
+Error *err = NULL;
+
+if (!event_notifier_test_and_clear(>req_notifier)) {
+return;
+}
+
+qdev_unplug(DEVICE(vcdev), );
+if (err) {
+warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
+}
+}
+
 static void vfio_ccw_crw_notifier_handler(void *opaque)
 {
 VFIOCCWDevice *vcdev = opaque;
@@ -386,6 +402,10 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 notifier = >crw_notifier;
 fd_read = vfio_ccw_crw_notifier_handler;
 break;
+case VFIO_CCW_REQ_IRQ_INDEX:
+notifier = >req_notifier;
+fd_read = vfio_ccw_req_notifier_handler;
+break;
 default:
 error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
 return;
@@ -440,6 +460,9 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice 
*vcdev,
 case VFIO_CCW_CRW_IRQ_INDEX:
 notifier = >crw_notifier;
 break;
+case VFIO_CCW_REQ_IRQ_INDEX:
+notifier = >req_notifier;
+break;
 default:
 error_report("vfio: Unsupported device irq(%d)", irq);
 return;
@@ -661,20 +684,28 @@ static void vfio_ccw_realize(DeviceState *dev, Error 
**errp)
 
 vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, );
 if (err) {
-goto out_notifier_err;
+goto out_io_notifier_err;
 }
 
 if (vcdev->crw_region) {
 vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, );
 if (err) {
-vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
-goto out_notifier_err;
+goto out_crw_notifier_err;
 }
 }
 
+vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, );
+if (err) {
+goto out_req_notifier_err;
+}
+
 return;
 
-out_notifier_err:
+out_req_notifier_err:
+vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
+out_crw_notifier_err:
+vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
+out_io_notifier_err:
 vfio_ccw_put_region(vcdev);
 out_region_err:
 vfio_ccw_put_device(vcdev);
@@ -696,6 +727,7 @@ static void vfio_ccw_unrealize(DeviceState *dev)
 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
 VFIOGroup *group = vcdev->vdev.group;
 
+vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
 vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
 vfio_ccw_put_region(vcdev);
-- 
2.17.1




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 06:41:35PM +0100, Claudio Fontana wrote:
> On 11/20/20 6:19 PM, Eduardo Habkost wrote:
> > On Fri, Nov 20, 2020 at 01:13:33PM +0100, Claudio Fontana wrote:
> >> On 11/18/20 11:07 PM, Eduardo Habkost wrote:
> >>> On Wed, Nov 18, 2020 at 08:13:18PM +0100, Paolo Bonzini wrote:
>  On 18/11/20 18:30, Eduardo Habkost wrote:
> >> Adding a layer of indirect calls is not very different from monkey 
> >> patching
> >> though.
> >
> > I'm a little bothered by monkey patching, but I'm more
> > bothered by having to:
> >
> > (1) register (module_init()) a function (kvm_cpu_accel_register()) that
> >(2) register (accel_register_call()) a function 
> > (kvm_cpu_accel_init()) that
> >  (3) register (x86_cpu_accel_init()) a data structure (X86CPUAccel 
> > kvm_cpu_accel) that
> >(4) will be saved in multiple QOM classes, so that
> >  (5) we will call the right X86CPUClass.accel method at the 
> > right moment
> >  (common_class_init(), instance_init(), realizefn()),
> > where:
> >step 4 must be done before any CPU object is created
> >  (otherwise X86CPUAccel.instance_init & X86CPUAccel.realizefn
> >   will be silently ignored), and
> >step 3 must be done after all QOM types were registered.
> >
> >> You also have to consider that accel currently does not exist in 
> >> usermode
> >> emulators, so that's an issue too. I would rather get a simple change 
> >> in
> >> quickly, instead of designing the perfect class hierarchy.
> >
> > It doesn't have to be perfect.  I agree that simple is better.
> >
> > To me, registering a QOM type and looking it up when necessary is
> > simpler than the above.  Even if it's a weird class having no
> > object instances.  It probably could be an interface type.
> 
>  Registering a QOM type still has quite some boilerplate.  [...]
> >>>
> >>> We're working on that.  :)
> >>>
> [...]  Also 
>  registering a
>  QOM type has a public side effect (shows up in qom-list-types).  In 
>  general
>  I don't look at QOM unless I want its property mechanism, but maybe 
>  that's
>  just me.
> >>>
> >>> We have lots of internal-use-only types returned by
> >>> qom-list-types, I don't think it's a big deal.
> >>>
> 
> >> Perhaps another idea would be to allow adding interfaces to classes
> >> *separately from the registration of the types*. Then we can use it to 
> >> add
> >> SOFTMMU_ACCEL and I386_ACCEL interfaces to a bare bones accel class, 
> >> and
> >> add the accel object to usermode emulators.
> >
> > I'm not sure I follow.  What do you mean by bare bones accel
> > class, and when exactly would you add the new interfaces to the
> > classes?
> 
>  A bare bones accel class would not have init_machine and setup_post 
>  methods;
>  those would be in a TYPE_SOFTMMU_ACCEL interface.  It would still have
>  properties (such as tb-size for TCG) and would be able to register compat
>  properties.
> > 
> > [1]
> > 
> >>>
> >>> Oh, I think I see.  This could save us having a lot of parallel type
> >>> hierarchies.
> >>>
> 
>  Where would I add it, I don't know.  It could be a simple public wrapper
>  around type_initialize_interface() if we add a new MODULE_INIT_* phase 
>  after
>  QOM.
> 
>  Or without adding a new phase, it could be a class_type->array of
>  (interface_type, init_fn) hash table.  type_initialize would look up the
>  class_type by name, add the interfaces would to the class with
>  type_initialize_interface, and then call the init_fn to fill in the 
>  vtable.
> >>>
> >>> That sounds nice.  I don't think Claudio's cleanup should be
> >>> blocked until this new mechanism is ready, though.
> >>>
> >>> We don't really need the type representing X86CPUAccel to be a
> >>> subtype of TYPE_ACCEL or an interface implemented by
> >>> current_machine->accelerator, in the first version.  We just need
> >>> a simple way for the CPU initialization code to find the correct
> >>> X86CPUAccel struct.
> >>>
> >>> While we don't have the new mechanism, it can be just a:
> >>>   object_class_by_name("%s-x86-cpu-accel" % (accel->name))
> >>> call.
> >>>
> >>> Below is a rough draft of what I mean.  There's still lots of
> >>> room for cleaning it up (especially getting rid of the
> >>> X86CPUClass.common_class_init and X86CPUClass.accel fields).
> >>>
> >>> git tree at 
> >>> https://gitlab.com/ehabkost/qemu/-/commits/work/qom-based-x86-cpu-accel
> >>>
> >>> Signed-off-by: Eduardo Habkost 
> > [...]
> >>>  /**
> >>> - * X86CPUAccel:
> >>> - * @name: string name of the X86 CPU Accelerator
> >>> - *
> >>> + * X86CPUAccelInterface:
> >>>   * @common_class_init: initializer for the common cpu
> >>>   * 

Re: [PATCH-for-5.2 v2] hw/intc: fix heap-buffer-overflow in rxicu_realize()

2020-11-20 Thread Philippe Mathieu-Daudé
Hi Peter,

On 11/20/20 5:41 PM, Peter Maydell wrote:
> On Fri, 20 Nov 2020 at 13:44, Peter Maydell  wrote:
>>
>> On Wed, 11 Nov 2020 at 14:18, Chen Qun  wrote:
>>>
>>> When 'j = icu->nr_sense – 1', the 'j < icu->nr_sense' condition is true,
>>> then 'j = icu->nr_sense', the'icu->init_sense[j]' has out-of-bounds access.
> 
>>> Suggested-by: Peter Maydell 
>>> Reported-by: Euler Robot 
>>> Signed-off-by: Chen Qun 
>>
>>
>> Reviewed-by: Peter Maydell 
> 
> I'll take this via target-arm.next, I guess.

Sorry I missed this patch while preparing the latest Renesas
pull request. I filter for hw/rx/ and didn't notice this
(also I was not Cc'ed in v1).

BTW to make things clear, I'm not maintaining this subsystem,
I simply try to cover for Yoshinori who is not very active.

As there are no other patch, I appreciate you taking this via
your ARM queue.

Thanks,

Phil.



[PATCH for-6.0 7/8] spapr: Drop "nr_servers" argument of the sPAPR IC activate() operation

2020-11-20 Thread Greg Kurz
This argument isn't used by the backends anymore.

Signed-off-by: Greg Kurz 
---
 include/hw/ppc/spapr_irq.h | 3 +--
 hw/intc/spapr_xive.c   | 3 +--
 hw/intc/xics_spapr.c   | 3 +--
 hw/ppc/spapr_irq.c | 3 +--
 4 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index c22a72c9e270..3e1c619d4c06 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -43,8 +43,7 @@ DECLARE_CLASS_CHECKERS(SpaprInterruptControllerClass, 
SPAPR_INTC,
 struct SpaprInterruptControllerClass {
 InterfaceClass parent;
 
-int (*activate)(SpaprInterruptController *intc, uint32_t nr_servers,
-Error **errp);
+int (*activate)(SpaprInterruptController *intc, Error **errp);
 void (*deactivate)(SpaprInterruptController *intc);
 
 /*
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index d13a2955ce9b..8331026fdb12 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -754,8 +754,7 @@ static void spapr_xive_dt(SpaprInterruptController *intc, 
uint32_t nr_servers,
  plat_res_int_priorities, 
sizeof(plat_res_int_priorities)));
 }
 
-static int spapr_xive_activate(SpaprInterruptController *intc,
-   uint32_t nr_servers, Error **errp)
+static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
 {
 SpaprXive *xive = SPAPR_XIVE(intc);
 
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index ce147e8980ed..8810bd93c856 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -426,8 +426,7 @@ static int xics_spapr_post_load(SpaprInterruptController 
*intc, int version_id)
 return 0;
 }
 
-static int xics_spapr_activate(SpaprInterruptController *intc,
-   uint32_t nr_servers, Error **errp)
+static int xics_spapr_activate(SpaprInterruptController *intc, Error **errp)
 {
 if (kvm_enabled()) {
 return spapr_irq_init_kvm(xics_kvm_connect, intc,
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index be6f4041e433..f2897fbc942a 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -480,7 +480,6 @@ static void set_active_intc(SpaprMachineState *spapr,
 SpaprInterruptController *new_intc)
 {
 SpaprInterruptControllerClass *sicc;
-uint32_t nr_servers = spapr_max_server_number(spapr);
 
 assert(new_intc);
 
@@ -498,7 +497,7 @@ static void set_active_intc(SpaprMachineState *spapr,
 
 sicc = SPAPR_INTC_GET_CLASS(new_intc);
 if (sicc->activate) {
-sicc->activate(new_intc, nr_servers, _fatal);
+sicc->activate(new_intc, _fatal);
 }
 
 spapr->active_intc = new_intc;
-- 
2.26.2




[PATCH for-6.0 8/8] spapr: Drop "nr_servers" argument of the sPAPR IC dt() operation

2020-11-20 Thread Greg Kurz
This argument isn't used by the backends anymore.

Signed-off-by: Greg Kurz 
---
 include/hw/ppc/spapr_irq.h | 6 ++
 hw/intc/spapr_xive.c   | 4 ++--
 hw/intc/xics_spapr.c   | 4 ++--
 hw/ppc/spapr.c | 2 +-
 hw/ppc/spapr_irq.c | 5 ++---
 5 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 3e1c619d4c06..e2519e4bc596 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -61,8 +61,7 @@ struct SpaprInterruptControllerClass {
 /* These methods should only be called on the active intc */
 void (*set_irq)(SpaprInterruptController *intc, int irq, int val);
 void (*print_info)(SpaprInterruptController *intc, Monitor *mon);
-void (*dt)(SpaprInterruptController *intc, uint32_t nr_servers,
-   void *fdt, uint32_t phandle);
+void (*dt)(SpaprInterruptController *intc, void *fdt, uint32_t phandle);
 int (*post_load)(SpaprInterruptController *intc, int version_id);
 };
 
@@ -73,8 +72,7 @@ int spapr_irq_cpu_intc_create(struct SpaprMachineState *spapr,
 void spapr_irq_cpu_intc_reset(struct SpaprMachineState *spapr, PowerPCCPU 
*cpu);
 void spapr_irq_cpu_intc_destroy(struct SpaprMachineState *spapr, PowerPCCPU 
*cpu);
 void spapr_irq_print_info(struct SpaprMachineState *spapr, Monitor *mon);
-void spapr_irq_dt(struct SpaprMachineState *spapr, uint32_t nr_servers,
-  void *fdt, uint32_t phandle);
+void spapr_irq_dt(struct SpaprMachineState *spapr, void *fdt, uint32_t 
phandle);
 
 uint32_t spapr_irq_nr_msis(struct SpaprMachineState *spapr);
 int spapr_irq_msi_alloc(struct SpaprMachineState *spapr, uint32_t num, bool 
align,
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 8331026fdb12..749cff9bf2b9 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -691,8 +691,8 @@ static void spapr_xive_print_info(SpaprInterruptController 
*intc, Monitor *mon)
 spapr_xive_pic_print_info(xive, mon);
 }
 
-static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
-  void *fdt, uint32_t phandle)
+static void spapr_xive_dt(SpaprInterruptController *intc, void *fdt,
+  uint32_t phandle)
 {
 SpaprXive *xive = SPAPR_XIVE(intc);
 int node;
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 8810bd93c856..a790b59f1bbc 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -312,8 +312,8 @@ static void ics_spapr_realize(DeviceState *dev, Error 
**errp)
 spapr_register_hypercall(H_IPOLL, h_ipoll);
 }
 
-static void xics_spapr_dt(SpaprInterruptController *intc, uint32_t nr_servers,
-  void *fdt, uint32_t phandle)
+static void xics_spapr_dt(SpaprInterruptController *intc, void *fdt,
+  uint32_t phandle)
 {
 uint32_t interrupt_server_ranges_prop[] = {
 0, cpu_to_be32(ICS_SPAPR(intc)->nr_servers),
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 21de0456446b..595dd1b81ce1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1164,7 +1164,7 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool 
reset, size_t space)
 _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
 
 /* /interrupt controller */
-spapr_irq_dt(spapr, spapr_max_server_number(spapr), fdt, PHANDLE_INTC);
+spapr_irq_dt(spapr, fdt, PHANDLE_INTC);
 
 ret = spapr_dt_memory(spapr, fdt);
 if (ret < 0) {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index f2897fbc942a..f93476d00a59 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -271,13 +271,12 @@ void spapr_irq_print_info(SpaprMachineState *spapr, 
Monitor *mon)
 sicc->print_info(spapr->active_intc, mon);
 }
 
-void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
-  void *fdt, uint32_t phandle)
+void spapr_irq_dt(SpaprMachineState *spapr, void *fdt, uint32_t phandle)
 {
 SpaprInterruptControllerClass *sicc
 = SPAPR_INTC_GET_CLASS(spapr->active_intc);
 
-sicc->dt(spapr->active_intc, nr_servers, fdt, phandle);
+sicc->dt(spapr->active_intc, fdt, phandle);
 }
 
 uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
-- 
2.26.2




[PATCH for-6.0 2/8] spapr/xive: Introduce spapr_xive_nr_ends()

2020-11-20 Thread Greg Kurz
We're going to kill the "nr_ends" field in a subsequent patch.
Prepare ground by using an helper instead of peeking into
the sPAPR XIVE structure directly.

Signed-off-by: Greg Kurz 
---
 include/hw/ppc/spapr_xive.h |  1 +
 hw/intc/spapr_xive.c| 23 ++-
 hw/intc/spapr_xive_kvm.c|  4 ++--
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index 26c8d90d7196..4b967f13c030 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -75,6 +75,7 @@ void spapr_xive_map_mmio(SpaprXive *xive);
 
 int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
  uint32_t *out_server, uint8_t *out_prio);
+uint32_t spapr_xive_nr_ends(const SpaprXive *xive);
 
 /*
  * KVM XIVE device helpers
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 60e0d5769dcc..f473ad9cba47 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -192,7 +192,7 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor 
*mon)
 uint32_t end_idx = xive_get_field64(EAS_END_INDEX, eas->w);
 XiveEND *end;
 
-assert(end_idx < xive->nr_ends);
+assert(end_idx < spapr_xive_nr_ends(xive));
 end = >endt[end_idx];
 
 if (xive_end_is_valid(end)) {
@@ -270,7 +270,7 @@ static void spapr_xive_reset(void *dev)
 }
 
 /* Clear all ENDs */
-for (i = 0; i < xive->nr_ends; i++) {
+for (i = 0; i < spapr_xive_nr_ends(xive); i++) {
 spapr_xive_end_reset(>endt[i]);
 }
 }
@@ -288,6 +288,11 @@ static void spapr_xive_instance_init(Object *obj)
 xive->fd = -1;
 }
 
+uint32_t spapr_xive_nr_ends(const SpaprXive *xive)
+{
+return xive->nr_ends;
+}
+
 static void spapr_xive_realize(DeviceState *dev, Error **errp)
 {
 SpaprXive *xive = SPAPR_XIVE(dev);
@@ -336,7 +341,7 @@ static void spapr_xive_realize(DeviceState *dev, Error 
**errp)
  * Allocate the routing tables
  */
 xive->eat = g_new0(XiveEAS, xive->nr_irqs);
-xive->endt = g_new0(XiveEND, xive->nr_ends);
+xive->endt = g_new0(XiveEND, spapr_xive_nr_ends(xive));
 
 xive->nodename = g_strdup_printf("interrupt-controller@%" PRIx64,
xive->tm_base + XIVE_TM_USER_PAGE * (1 << 
TM_SHIFT));
@@ -375,7 +380,7 @@ static int spapr_xive_get_end(XiveRouter *xrtr,
 {
 SpaprXive *xive = SPAPR_XIVE(xrtr);
 
-if (end_idx >= xive->nr_ends) {
+if (end_idx >= spapr_xive_nr_ends(xive)) {
 return -1;
 }
 
@@ -389,7 +394,7 @@ static int spapr_xive_write_end(XiveRouter *xrtr, uint8_t 
end_blk,
 {
 SpaprXive *xive = SPAPR_XIVE(xrtr);
 
-if (end_idx >= xive->nr_ends) {
+if (end_idx >= spapr_xive_nr_ends(xive)) {
 return -1;
 }
 
@@ -1138,7 +1143,7 @@ static target_ulong h_int_get_source_config(PowerPCCPU 
*cpu,
 /* EAS_END_BLOCK is unused on sPAPR */
 end_idx = xive_get_field64(EAS_END_INDEX, eas.w);
 
-assert(end_idx < xive->nr_ends);
+assert(end_idx < spapr_xive_nr_ends(xive));
 end = >endt[end_idx];
 
 nvt_blk = xive_get_field32(END_W6_NVT_BLOCK, end->w6);
@@ -1216,7 +1221,7 @@ static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
 return H_P2;
 }
 
-assert(end_idx < xive->nr_ends);
+assert(end_idx < spapr_xive_nr_ends(xive));
 end = >endt[end_idx];
 
 args[0] = xive->end_base + (1ull << (end_xsrc->esb_shift + 1)) * end_idx;
@@ -1304,7 +1309,7 @@ static target_ulong h_int_set_queue_config(PowerPCCPU 
*cpu,
 return H_P2;
 }
 
-assert(end_idx < xive->nr_ends);
+assert(end_idx < spapr_xive_nr_ends(xive));
 memcpy(, >endt[end_idx], sizeof(XiveEND));
 
 switch (qsize) {
@@ -1470,7 +1475,7 @@ static target_ulong h_int_get_queue_config(PowerPCCPU 
*cpu,
 return H_P2;
 }
 
-assert(end_idx < xive->nr_ends);
+assert(end_idx < spapr_xive_nr_ends(xive));
 end = >endt[end_idx];
 
 args[0] = 0;
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 66bf4c06fe55..1566016f0e28 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -531,7 +531,7 @@ static int kvmppc_xive_get_queues(SpaprXive *xive, Error 
**errp)
 int i;
 int ret;
 
-for (i = 0; i < xive->nr_ends; i++) {
+for (i = 0; i < spapr_xive_nr_ends(xive); i++) {
 if (!xive_end_is_valid(>endt[i])) {
 continue;
 }
@@ -701,7 +701,7 @@ int kvmppc_xive_post_load(SpaprXive *xive, int version_id)
 assert(xive->fd != -1);
 
 /* Restore the ENDT first. The targetting depends on it. */
-for (i = 0; i < xive->nr_ends; i++) {
+for (i = 0; i < spapr_xive_nr_ends(xive); i++) {
 if (!xive_end_is_valid(>endt[i])) {
 continue;
 }
-- 
2.26.2




[PATCH for-6.0 6/8] spapr/xics: Add "nr-servers" property

2020-11-20 Thread Greg Kurz
The sPAPR ICS device exposes the range of vCPU ids it can handle in
the "ibm,interrupt-server-ranges" FDT property. The highest vCPU
id, ie. spapr_max_server_number(), is obtained from the machine
through the "nr_servers" argument of the generic spapr_irq_dt() call.

We want to drop the "nr_servers" argument from the API because it
doesn't make sense for the sPAPR XIVE device actually.

On POWER9, we also pass the highest vCPU id to the KVM XICS-on-XIVE
device, in order to optimize resource allocation in the HW.

This is enough motivation to introduce an "nr-servers" property
and to use it for both purposes.

Signed-off-by: Greg Kurz 
---
 include/hw/ppc/spapr.h  |  4 ++--
 include/hw/ppc/xics_spapr.h | 21 +---
 hw/intc/xics_kvm.c  |  2 +-
 hw/intc/xics_spapr.c| 38 -
 hw/ppc/spapr.c  |  5 +++--
 hw/ppc/spapr_irq.c  |  7 +--
 6 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 2e89e36cfbdc..b76c84a2f884 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -10,7 +10,7 @@
 #include "hw/ppc/spapr_irq.h"
 #include "qom/object.h"
 #include "hw/ppc/spapr_xive.h"  /* For SpaprXive */
-#include "hw/ppc/xics.h"/* For ICSState */
+#include "hw/ppc/xics_spapr.h"  /* For IcsSpaprState */
 #include "hw/ppc/spapr_tpm_proxy.h"
 
 struct SpaprVioBus;
@@ -230,7 +230,7 @@ struct SpaprMachineState {
 SpaprIrq *irq;
 qemu_irq *qirqs;
 SpaprInterruptController *active_intc;
-ICSState *ics;
+IcsSpaprState *ics;
 SpaprXive *xive;
 
 bool cmd_line_caps[SPAPR_CAP_NUM];
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index de752c0d2c7e..1a483a873b62 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -28,12 +28,27 @@
 #define XICS_SPAPR_H
 
 #include "hw/ppc/spapr.h"
+#include "hw/ppc/xics.h"
 #include "qom/object.h"
 
+typedef struct IcsSpaprState {
+/*< private >*/
+ICPState parent_obj;
+
+/*
+ * The ICS needs to know the upper limit to vCPU ids it
+ * might be exposed to in order to size the vCPU id range
+ * in "ibm,interrupt-server-ranges" and to optimize HW
+ * resource allocation when using the XICS-on-XIVE KVM
+ * device. It is the purpose of the "nr-servers" property
+ * which *must* be set to a non-null value before realizing
+ * the ICS.
+ */
+uint32_t nr_servers;
+} IcsSpaprState;
+
 #define TYPE_ICS_SPAPR "ics-spapr"
-/* This is reusing the ICSState typedef from TYPE_ICS */
-DECLARE_INSTANCE_CHECKER(ICSState, ICS_SPAPR,
- TYPE_ICS_SPAPR)
+DECLARE_INSTANCE_CHECKER(IcsSpaprState, ICS_SPAPR, TYPE_ICS_SPAPR)
 
 int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
  Error **errp);
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 570d635bcc08..ecbbda0e249b 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -350,7 +350,7 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
 int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
  Error **errp)
 {
-ICSState *ics = ICS_SPAPR(intc);
+ICSState *ics = ICS(intc);
 int rc;
 CPUState *cs;
 Error *local_err = NULL;
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 8ae4f41459c3..ce147e8980ed 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -34,6 +34,7 @@
 #include "hw/ppc/xics.h"
 #include "hw/ppc/xics_spapr.h"
 #include "hw/ppc/fdt.h"
+#include "hw/qdev-properties.h"
 #include "qapi/visitor.h"
 
 /*
@@ -154,7 +155,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
   uint32_t nargs, target_ulong args,
   uint32_t nret, target_ulong rets)
 {
-ICSState *ics = spapr->ics;
+ICSState *ics = ICS(spapr->ics);
 uint32_t nr, srcno, server, priority;
 
 CHECK_EMULATED_XICS_RTAS(spapr, rets);
@@ -189,7 +190,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
   uint32_t nargs, target_ulong args,
   uint32_t nret, target_ulong rets)
 {
-ICSState *ics = spapr->ics;
+ICSState *ics = ICS(spapr->ics);
 uint32_t nr, srcno;
 
 CHECK_EMULATED_XICS_RTAS(spapr, rets);
@@ -221,7 +222,7 @@ static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
  uint32_t nargs, target_ulong args,
  uint32_t nret, target_ulong rets)
 {
-ICSState *ics = spapr->ics;
+ICSState *ics = ICS(spapr->ics);
 uint32_t nr, srcno;
 
 CHECK_EMULATED_XICS_RTAS(spapr, rets);
@@ -254,7 +255,7 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 uint32_t nargs, target_ulong args,
 uint32_t nret, target_ulong rets)
 {
-ICSState *ics = spapr->ics;

[PATCH for-6.0 0/8] spapr: Address the confusion between IPI numbers and vCPU ids

2020-11-20 Thread Greg Kurz
A regression was recently fixed in the sPAPR XIVE code for QEMU 5.2
RC3 [1]. It boiled down to a confusion between IPI numbers and vCPU
ids, which happen to be numerically equal in general, but are really
different entities that can diverge in some setups. When this happens,
we end up misconfiguring XIVE in a way that is almost fatal for the
guest.

The confusion comes from XICS which has historically assumed equality
between interrupt server numbers and vCPU ids, as mentionned in a
comment back from 2011 in the linux kernel icp_native_init_one_node()
function:

/* This code does the theorically broken assumption that the interrupt
 * server numbers are the same as the hard CPU numbers.
 * This happens to be the case so far but we are playing with fire...
 * should be fixed one of these days. -BenH.
 */

This assumption crept into QEMU through the "ibm,interrupt-server-ranges"
property of the "interrupt-controller" node in the DT. This property
contains ranges of consecutive vCPU ids defined as (first id, # of ids).
In the case of QEMU, we define a single range starting from 0 up to the
highest vCPU id, as returned by spapr_max_server_number(). This has
always been associated to the "nr_servers" wording when naming variables
or function arguments. When XIVE got added, we introduced an sPAPR IRQ
abstraction to be able to control several interrupt controller backends.
The sPAPR IRQ base class provides a dt() handler used to populate the
"interrupt-controller" node in the DT. This handler takes an "nr_server"
argument inherited from XICS and we ended up using it to populate the
"ibm,xive-lisn-ranges" property used with XIVE, which has completely
different semantics. It contain ranges of interrupt numbers that the
guest can use for any purpose. Since one obvious purpose is IPI, its
first range should just be able to accomodate all possible vCPUs.
In the case of QEMU, we define a single range starting from 0 up
to "nr_server" but we should rather size it to the number of vCPUs
actually (ie. smp.max_cpus).

This series aims at getting rid of the "nr_server" argument in the
sPAPR IC handlers. Since both the highest possible vCPU id and the
maximum number of vCPUs are invariants for XICS and XIVE respectively,
let's make them device properties to be configured by the machine when
it creates the interrupt controllers and use them where needed.

This doesn't cause any visible change to setups using the default
VSMT machine settings. This changes "ibm,xive-lisn-ranges" for
setups that mess with VSMT, but this is acceptable since linux
only allocates one interrupt per vCPU and the higher part of the
range was never used.

[1] 
https://git.qemu.org/?p=qemu.git;a=commit;h=6d24795ee7e3199d199d3c415312c93382ad1807

Greg Kurz (8):
  spapr/xive: Turn some sanity checks into assertions
  spapr/xive: Introduce spapr_xive_nr_ends()
  spapr/xive: Add "nr-servers" property
  spapr/xive: Add "nr-ipis" property
  spapr/xics: Drop unused argument to xics_kvm_has_broken_disconnect()
  spapr/xics: Add "nr-servers" property
  spapr: Drop "nr_servers" argument of the sPAPR IC activate() operation
  spapr: Drop "nr_servers" argument of the sPAPR IC dt() operation

 include/hw/ppc/spapr.h  |  4 +--
 include/hw/ppc/spapr_irq.h  |  9 ++---
 include/hw/ppc/spapr_xive.h | 25 -
 include/hw/ppc/xics_spapr.h | 23 +---
 hw/intc/spapr_xive.c| 72 ++---
 hw/intc/spapr_xive_kvm.c|  4 +--
 hw/intc/xics_kvm.c  |  4 +--
 hw/intc/xics_spapr.c| 45 ++-
 hw/ppc/spapr.c  |  7 ++--
 hw/ppc/spapr_irq.c  | 27 +++---
 10 files changed, 141 insertions(+), 79 deletions(-)

-- 
2.26.2





Re: [PATCH v1 4/6] gitlab: move remaining x86 check-tcg targets to gitlab

2020-11-20 Thread Wainer dos Santos Moschetta



On 11/17/20 2:36 PM, Alex Bennée wrote:

The GCC check-tcg (user) test in particular was very prone to timing
out on Travis. We only actually need to move the some-softmmu builds
across as we already have coverage for linux-user.

As --enable-debug-tcg does increase the run time somewhat as more
debug is put in let's restrict that to just the plugins build. It's
unlikely that a plugins enabled build is going to hide a sanity
failure in core TCG code so let the plugin builds do the heavy lifting
on checking TCG sanity so the non-plugin builds can run swiftly.

Now the only remaining check-tcg builds on Travis are for the various
non-x86 arches.

Signed-off-by: Alex Bennée 
Message-Id: <20201110192316.26397-10-alex.ben...@linaro.org>
---
  .gitlab-ci.yml | 17 +
  .travis.yml| 26 --
  2 files changed, 17 insertions(+), 26 deletions(-)



Reviewed-by: Wainer dos Santos Moschetta 




diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9a8b375188..b406027a55 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -247,6 +247,15 @@ build-user:
  CONFIGURE_ARGS: --disable-tools --disable-system
  MAKE_CHECK_ARGS: check-tcg
  
+# Only build the softmmu targets we have check-tcg tests for

+build-some-softmmu:
+  <<: *native_build_job_definition
+  variables:
+IMAGE: debian-all-test-cross
+CONFIGURE_ARGS: --disable-tools --enable-debug-tcg
+TARGETS: xtensa-softmmu arm-softmmu aarch64-softmmu alpha-softmmu
+MAKE_CHECK_ARGS: check-tcg
+
  # Run check-tcg against linux-user (with plugins)
  # we skip sparc64-linux-user until it has been fixed somewhat
  # we skip cris-linux-user as it doesn't use the common run loop
@@ -258,6 +267,14 @@ build-user-plugins:
  MAKE_CHECK_ARGS: check-tcg
timeout: 1h 30m
  
+build-some-softmmu-plugins:

+  <<: *native_build_job_definition
+  variables:
+IMAGE: debian-all-test-cross
+CONFIGURE_ARGS: --disable-tools --disable-user --enable-plugins 
--enable-debug-tcg
+TARGETS: xtensa-softmmu arm-softmmu aarch64-softmmu alpha-softmmu
+MAKE_CHECK_ARGS: check-tcg
+
  build-clang:
<<: *native_build_job_definition
variables:
diff --git a/.travis.yml b/.travis.yml
index a3d78171ca..bac085f800 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -301,32 +301,6 @@ jobs:
  - ${SRC_DIR}/configure ${CONFIG} --extra-cflags="-g3 -O0 -fsanitize=thread" 
|| { cat config.log meson-logs/meson-log.txt && exit 1; }
  
  
-# Run check-tcg against linux-user

-- name: "GCC check-tcg (user)"
-  env:
-- CONFIG="--disable-system --enable-debug-tcg"
-- TEST_BUILD_CMD="make build-tcg"
-- TEST_CMD="make check-tcg"
-- CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug-tcg"
-
-
-# Run check-tcg against softmmu targets
-- name: "GCC check-tcg (some-softmmu)"
-  env:
-- CONFIG="--enable-debug-tcg 
--target-list=xtensa-softmmu,arm-softmmu,aarch64-softmmu,alpha-softmmu"
-- TEST_BUILD_CMD="make build-tcg"
-- TEST_CMD="make check-tcg"
-- CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug-tcg"
-
-
-# Run check-tcg against softmmu targets (with plugins)
-- name: "GCC plugins check-tcg (some-softmmu)"
-  env:
-- CONFIG="--enable-plugins --enable-debug-tcg 
--target-list=xtensa-softmmu,arm-softmmu,aarch64-softmmu,alpha-softmmu"
-- TEST_BUILD_CMD="make build-tcg"
-- TEST_CMD="make check-tcg"
-- CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug-tcg"
-
  - name: "[aarch64] GCC check-tcg"
arch: arm64
dist: focal





[PATCH for-6.0 1/8] spapr/xive: Turn some sanity checks into assertions

2020-11-20 Thread Greg Kurz
The sPAPR XIVE device is created by the machine in spapr_irq_init().
The latter overrides any value provided by the user with -global for
the "nr-irqs" and "nr-ends" properties with strictly positive values.

It seems reasonable to assume these properties should never be 0,
which wouldn't make much sense by the way.

Signed-off-by: Greg Kurz 
---
 hw/intc/spapr_xive.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 1fa09f287ac0..60e0d5769dcc 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -296,22 +296,16 @@ static void spapr_xive_realize(DeviceState *dev, Error 
**errp)
 XiveENDSource *end_xsrc = >end_source;
 Error *local_err = NULL;
 
+/* Set by spapr_irq_init() */
+g_assert(xive->nr_irqs);
+g_assert(xive->nr_ends);
+
 sxc->parent_realize(dev, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
 
-if (!xive->nr_irqs) {
-error_setg(errp, "Number of interrupt needs to be greater 0");
-return;
-}
-
-if (!xive->nr_ends) {
-error_setg(errp, "Number of interrupt needs to be greater 0");
-return;
-}
-
 /*
  * Initialize the internal sources, for IPIs and virtual devices.
  */
-- 
2.26.2




  1   2   3   >