[PATCH RFC 16/16] hw/arm: Introduce the microvm machine type

2020-02-16 Thread Xu Yandong
It's a minimalist machine type without PCI nor ACPI support, designed
for short-lived guests. microvm also establishes a baseline for
benchmarking and optimizing both QEMU and guest operating systems,
since it is optimized for both boot time and footprint.

Signed-off-by: Xu Yandong 
---
 default-configs/aarch64-softmmu.mak |   2 +
 hw/arm/Kconfig  |   7 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/arm.c|   8 +
 hw/arm/microvm.c| 303 
 hw/arm/virt.c   |  17 +-
 include/hw/arm/arm.h|   2 +
 include/hw/arm/microvm.h|  40 
 include/hw/arm/virt.h   |   1 -
 9 files changed, 372 insertions(+), 9 deletions(-)
 create mode 100644 hw/arm/microvm.c
 create mode 100644 include/hw/arm/microvm.h

diff --git a/default-configs/aarch64-softmmu.mak 
b/default-configs/aarch64-softmmu.mak
index 958b1e08e4..e9e994801c 100644
--- a/default-configs/aarch64-softmmu.mak
+++ b/default-configs/aarch64-softmmu.mak
@@ -6,3 +6,5 @@ include arm-softmmu.mak
 CONFIG_XLNX_ZYNQMP_ARM=y
 CONFIG_XLNX_VERSAL=y
 CONFIG_SBSA_REF=y
+
+CONFIG_ARM_MICROVM=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 3d86691ae0..153ffbabac 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -25,6 +25,13 @@ config ARM_VIRT
 select ACPI_MEMORY_HOTPLUG
 select ACPI_HW_REDUCED
 
+config ARM_MICROVM
+bool
+select A15MPCORE
+select PL011 # UART
+select PL031 # RTC
+select VIRTIO_MMIO
+
 config CHEETAH
 bool
 select OMAP
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 51fcee2ac8..2a2f643774 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,6 +1,7 @@
 obj-y += boot.o
 obj-$(CONFIG_PLATFORM_BUS) += sysbus-fdt.o
 obj-$(CONFIG_ARM_VIRT) += arm.o virt.o
+obj-$(CONFIG_ARM_MICROVM) += arm.o microvm.o
 obj-$(CONFIG_ACPI) += virt-acpi-build.o
 obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-$(CONFIG_EXYNOS4) += exynos4_boards.o
diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index 8bb5d92d2e..0c5bf1a2f8 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -306,6 +306,14 @@ void qdev_create_gic(ArmMachineState *ams)
  */
 qdev_prop_set_uint32(ams->gic, "num-irq", NUM_IRQS + 32);
 
+if (!kvm_irqchip_in_kernel()) {
+qdev_prop_set_bit(ams->gic, "has-security-extensions", false);
+if (type != 3) {
+qdev_prop_set_bit(ams->gic, "has-virtualization-extensions",
+  false);
+}
+}
+
 if (type == 3) {
 uint32_t redist0_capacity =
 ams->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
diff --git a/hw/arm/microvm.c b/hw/arm/microvm.c
new file mode 100644
index 00..04f98d63cb
--- /dev/null
+++ b/hw/arm/microvm.c
@@ -0,0 +1,303 @@
+/*
+ * ARM mach-virt emulation
+ *
+ * Copyright (c) 2013 Linaro Limited
+ * Copyright (c) 2020 Huawei.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "hw/arm/arm.h"
+#include "hw/arm/microvm.h"
+#include "sysemu/device_tree.h"
+#include "sysemu/numa.h"
+#include "sysemu/sysemu.h"
+#include "hw/loader.h"
+#include "hw/qdev-properties.h"
+#include "hw/arm/fdt.h"
+#include "kvm_arm.h"
+
+/* Number of external interrupt lines to configure the GIC with */
+#define NUM_IRQS 256
+
+#define PLATFORM_BUS_NUM_IRQS 64
+
+/* Legacy RAM limit in GB (< version 4.0) */
+#define LEGACY_RAMLIMIT_GB 255
+#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
+
+/* Addresses and sizes of our components.
+ * 0..128MB is space for a flash device so we can run bootrom code such as 
UEFI.
+ * 128MB..256MB is used for miscellaneous device I/O.
+ * 256MB..1GB is reserved for possible future PCI support (ie where the
+ * PCI memory window will go if we add a PCI host controller).
+ * 1GB and up is RAM (which may happily spill over into the
+ * high memory region beyond 4GB).
+ * This represents a compromise between how much RAM can be given to
+ * a 32 bit VM and leaving space for expansion and in particular for PCI.
+ * Note that devices should generally be placed at multiples of 0x1,
+ * to accommodate guests using 64K pages.
+ */
+static MemMapEntry base_memmap[] = {
+/* Space up to 0x800 is reserved for a boot ROM */
+[VIRT_CPUPERIPHS] = { 0x0800, 0x0002 },
+/* 

[PATCH RFC 02/16] hw/arm: move shared fdt member to ArmMachine

2020-02-16 Thread Xu Yandong
Move fdt and fdt_size member from VirtMachineState to ArmMachineState.

Signed-off-by: Xu Yandong 
---
 hw/arm/virt.c | 303 ++
 include/hw/arm/arm.h  |   2 +
 include/hw/arm/virt.h |   2 -
 3 files changed, 163 insertions(+), 144 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 355007fd32..41b2076ce1 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -211,15 +211,16 @@ static bool cpu_type_valid(const char *cpu)
 static void create_fdt(VirtMachineState *vms)
 {
 MachineState *ms = MACHINE(vms);
+ArmMachineState *ams = ARM_MACHINE(vms);
 int nb_numa_nodes = ms->numa_state->num_nodes;
-void *fdt = create_device_tree(>fdt_size);
+void *fdt = create_device_tree(>fdt_size);
 
 if (!fdt) {
 error_report("create_device_tree() failed");
 exit(1);
 }
 
-vms->fdt = fdt;
+ams->fdt = fdt;
 
 /* Header */
 qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
@@ -288,6 +289,7 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
  * the correct information.
  */
 ARMCPU *armcpu;
+ArmMachineState *ams = ARM_MACHINE(vms);
 VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
 uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
 
@@ -301,19 +303,19 @@ static void fdt_add_timer_nodes(const VirtMachineState 
*vms)
  (1 << vms->smp_cpus) - 1);
 }
 
-qemu_fdt_add_subnode(vms->fdt, "/timer");
+qemu_fdt_add_subnode(ams->fdt, "/timer");
 
 armcpu = ARM_CPU(qemu_get_cpu(0));
 if (arm_feature(>env, ARM_FEATURE_V8)) {
 const char compat[] = "arm,armv8-timer\0arm,armv7-timer";
-qemu_fdt_setprop(vms->fdt, "/timer", "compatible",
+qemu_fdt_setprop(ams->fdt, "/timer", "compatible",
  compat, sizeof(compat));
 } else {
-qemu_fdt_setprop_string(vms->fdt, "/timer", "compatible",
+qemu_fdt_setprop_string(ams->fdt, "/timer", "compatible",
 "arm,armv7-timer");
 }
-qemu_fdt_setprop(vms->fdt, "/timer", "always-on", NULL, 0);
-qemu_fdt_setprop_cells(vms->fdt, "/timer", "interrupts",
+qemu_fdt_setprop(ams->fdt, "/timer", "always-on", NULL, 0);
+qemu_fdt_setprop_cells(ams->fdt, "/timer", "interrupts",
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
@@ -325,6 +327,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
 int cpu;
 int addr_cells = 1;
 const MachineState *ms = MACHINE(vms);
+const ArmMachineState *ams = ARM_MACHINE(vms);
 
 /*
  * From Documentation/devicetree/bindings/arm/cpus.txt
@@ -348,36 +351,36 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
 }
 }
 
-qemu_fdt_add_subnode(vms->fdt, "/cpus");
-qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#address-cells", addr_cells);
-qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#size-cells", 0x0);
+qemu_fdt_add_subnode(ams->fdt, "/cpus");
+qemu_fdt_setprop_cell(ams->fdt, "/cpus", "#address-cells", addr_cells);
+qemu_fdt_setprop_cell(ams->fdt, "/cpus", "#size-cells", 0x0);
 
 for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) {
 char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
 CPUState *cs = CPU(armcpu);
 
-qemu_fdt_add_subnode(vms->fdt, nodename);
-qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "cpu");
-qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
+qemu_fdt_add_subnode(ams->fdt, nodename);
+qemu_fdt_setprop_string(ams->fdt, nodename, "device_type", "cpu");
+qemu_fdt_setprop_string(ams->fdt, nodename, "compatible",
 armcpu->dtb_compatible);
 
 if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED
 && vms->smp_cpus > 1) {
-qemu_fdt_setprop_string(vms->fdt, nodename,
+qemu_fdt_setprop_string(ams->fdt, nodename,
 "enable-method", "psci");
 }
 
 if (addr_cells == 2) {
-qemu_fdt_setprop_u64(vms->fdt, nodename, "reg",
+qemu_fdt_setprop_u64(ams->fdt, nodename, "reg",
  armcpu->mp_affinity);
 } else {
-qemu_fdt_setprop_cell(vms->fdt, nodename, "reg",
+qemu_fdt_setprop_cell(ams->fdt, nodename, "reg",
   armcpu->mp_affinity);
 }
 
 if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
-qemu_fdt_setprop_cell(vms->fdt, nodename, "numa-node-id",
+qemu_fdt_setprop_cell(ams->fdt, nodename, "numa-node-id",
 ms->possible_cpus->cpus[cs->cpu_index].props.node_id);

[PATCH RFC 01/16] hw/arm/arm: Introduce ArmMachineState and ArmMachineClass

2020-02-16 Thread Xu Yandong
In the following patches, VirtMachineState and VirtMachineClass will
splited to and deriving ArmMachineState and ArmMachineClass.
This allows sharing code with other arm machine types.

Signed-off-by: Xu Yandong 
---
 hw/arm/Makefile.objs  |   2 +-
 hw/arm/arm.c  |  77 
 hw/arm/virt.c |  11 +
 include/hw/arm/arm.h  | 100 ++
 include/hw/arm/virt.h |  61 ++
 5 files changed, 183 insertions(+), 68 deletions(-)
 create mode 100644 hw/arm/arm.c
 create mode 100644 include/hw/arm/arm.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 336f6dd374..51fcee2ac8 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,6 +1,6 @@
 obj-y += boot.o
 obj-$(CONFIG_PLATFORM_BUS) += sysbus-fdt.o
-obj-$(CONFIG_ARM_VIRT) += virt.o
+obj-$(CONFIG_ARM_VIRT) += arm.o virt.o
 obj-$(CONFIG_ACPI) += virt-acpi-build.o
 obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-$(CONFIG_EXYNOS4) += exynos4_boards.o
diff --git a/hw/arm/arm.c b/hw/arm/arm.c
new file mode 100644
index 00..4261d56832
--- /dev/null
+++ b/hw/arm/arm.c
@@ -0,0 +1,77 @@
+/*
+ * ARM mach-virt emulation
+ * Copyright (c) 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ *
+ * Emulate a virtual board which works by passing Linux all the information
+ * it needs about what devices are present via the device tree.
+ * There are some restrictions about what we can do here:
+ *  + we can only present devices whose Linux drivers will work based
+ *purely on the device tree with no platform data at all
+ * This is essentially the same approach kvmtool uses.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/arm/arm.h"
+#include "sysemu/device_tree.h"
+#include "sysemu/numa.h"
+#include "hw/loader.h"
+#include "exec/address-spaces.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+#include "qemu/module.h"
+#include "hw/arm/sysbus-fdt.h"
+#include "hw/platform-bus.h"
+#include "hw/qdev-properties.h"
+#include "hw/arm/fdt.h"
+#include "hw/intc/arm_gic.h"
+#include "kvm_arm.h"
+
+static void arm_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+mc->block_default_type = IF_VIRTIO;
+mc->no_cdrom = 1;
+mc->pci_allow_0_address = true;
+/* We know we will never create a pre-ARMv7 CPU which needs 1K pages */
+mc->minimum_page_bits = 12;
+mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
+mc->numa_mem_supported = true;
+mc->auto_enable_numa_with_memhp = true;
+}
+
+static void arm_instance_init(Object *obj)
+{
+}
+
+static const TypeInfo arm_machine_info = {
+.name  = TYPE_ARM_MACHINE,
+.parent= TYPE_MACHINE,
+.abstract  = true,
+.instance_size = sizeof(ArmMachineState),
+.class_size= sizeof(ArmMachineClass),
+.class_init= arm_machine_class_init,
+.instance_init = arm_instance_init,
+.interfaces = (InterfaceInfo[]) {
+ { }
+},
+};
+
+static void macharm_machine_init(void)
+{
+type_register_static(_machine_info);
+}
+type_init(macharm_machine_init);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f788fe27d6..355007fd32 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -37,6 +37,7 @@
 #include "hw/boards.h"
 #include "hw/arm/boot.h"
 #include "hw/arm/primecell.h"
+#include "hw/arm/arm.h"
 #include "hw/arm/virt.h"
 #include "hw/block/flash.h"
 #include "hw/vfio/vfio-calxeda-xgmac.h"
@@ -2041,14 +2042,8 @@ static void virt_machine_class_init(ObjectClass *oc, 
void *data)
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
-mc->block_default_type = IF_VIRTIO;
-mc->no_cdrom = 1;
-mc->pci_allow_0_address = true;
-/* We know we will never create a pre-ARMv7 CPU which needs 1K pages */
-mc->minimum_page_bits = 12;
 mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
 mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
-mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
 mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
 mc->kvm_type = virt_kvm_type;
 assert(!mc->get_hotplug_handler);
@@ -2056,8 +2051,6 @@ static void virt_machine_class_init(ObjectClass *oc, void 

[PATCH RFC 03/16] hw/arm: move shared memmap member to ArmMachine

2020-02-16 Thread Xu Yandong
Move memmap member from VirtMachineState to ArmMachineState.

Cc: Michael S. Tsirkin 
Cc: Igor Mammedov 
Cc: Shannon Zhao 
Signed-off-by: Xu Yandong 
---
 hw/arm/virt-acpi-build.c |  21 +++--
 hw/arm/virt.c| 178 ---
 include/hw/arm/arm.h |   1 +
 include/hw/arm/virt.h|   4 +-
 4 files changed, 110 insertions(+), 94 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index bd5f771e9b..ef61a651c1 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -43,6 +43,7 @@
 #include "hw/acpi/generic_event_device.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/pci/pci.h"
+#include "hw/arm/arm.h"
 #include "hw/arm/virt.h"
 #include "sysemu/numa.h"
 #include "sysemu/reset.h"
@@ -383,6 +384,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 AcpiIortSmmu3 *smmu;
 size_t node_size, iort_node_offset, iort_length, smmu_offset = 0;
 AcpiIortRC *rc;
+ArmMachineState *ams = ARM_MACHINE(vms);
 
 iort = acpi_data_push(table_data, sizeof(*iort));
 
@@ -424,7 +426,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 smmu->length = cpu_to_le16(node_size);
 smmu->mapping_count = cpu_to_le32(1);
 smmu->mapping_offset = cpu_to_le32(sizeof(*smmu));
-smmu->base_address = cpu_to_le64(vms->memmap[VIRT_SMMU].base);
+smmu->base_address = cpu_to_le64(ams->memmap[VIRT_SMMU].base);
 smmu->flags = cpu_to_le32(ACPI_IORT_SMMU_V3_COHACC_OVERRIDE);
 smmu->event_gsiv = cpu_to_le32(irq);
 smmu->pri_gsiv = cpu_to_le32(irq + 1);
@@ -484,7 +486,8 @@ static void
 build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
 AcpiSerialPortConsoleRedirection *spcr;
-const MemMapEntry *uart_memmap = >memmap[VIRT_UART];
+ArmMachineState *ams = ARM_MACHINE(vms);
+const MemMapEntry *uart_memmap = >memmap[VIRT_UART];
 int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
 int spcr_start = table_data->len;
 
@@ -524,6 +527,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 uint64_t mem_base;
 MachineClass *mc = MACHINE_GET_CLASS(vms);
 MachineState *ms = MACHINE(vms);
+ArmMachineState *ams = ARM_MACHINE(vms);
 const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(ms);
 
 srat_start = table_data->len;
@@ -539,7 +543,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 core->flags = cpu_to_le32(1);
 }
 
-mem_base = vms->memmap[VIRT_MEM].base;
+mem_base = ams->memmap[VIRT_MEM].base;
 for (i = 0; i < ms->numa_state->num_nodes; ++i) {
 if (ms->numa_state->nodes[i].node_mem > 0) {
 numamem = acpi_data_push(table_data, sizeof(*numamem));
@@ -602,8 +606,9 @@ static void
 build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
 VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+ArmMachineState *ams = ARM_MACHINE(vms);
 int madt_start = table_data->len;
-const MemMapEntry *memmap = vms->memmap;
+const MemMapEntry *memmap = ams->memmap;
 const int *irqmap = vms->irqmap;
 AcpiMultipleApicTable *madt;
 AcpiMadtGenericDistributor *gicd;
@@ -723,7 +728,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 {
 Aml *scope, *dsdt;
 MachineState *ms = MACHINE(vms);
-const MemMapEntry *memmap = vms->memmap;
+ArmMachineState *ams = ARM_MACHINE(vms);
+const MemMapEntry *memmap = ams->memmap;
 const int *irqmap = vms->irqmap;
 
 dsdt = init_aml_allocator();
@@ -796,6 +802,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables 
*tables)
 unsigned dsdt, xsdt;
 GArray *tables_blob = tables->table_data;
 MachineState *ms = MACHINE(vms);
+ArmMachineState *ams = ARM_MACHINE(vms);
 
 table_offsets = g_array_new(false, true /* clear */,
 sizeof(uint32_t));
@@ -821,8 +828,8 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables 
*tables)
 acpi_add_table(table_offsets, tables_blob);
 {
 AcpiMcfgInfo mcfg = {
-   .base = vms->memmap[VIRT_ECAM_ID(vms->highmem_ecam)].base,
-   .size = vms->memmap[VIRT_ECAM_ID(vms->highmem_ecam)].size,
+   .base = ams->memmap[VIRT_ECAM_ID(vms->highmem_ecam)].base,
+   .size = ams->memmap[VIRT_ECAM_ID(vms->highmem_ecam)].size,
 };
 build_mcfg(tables_blob, tables->linker, );
 }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 41b2076ce1..1dea640719 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -395,14 +395,14 @@ static void fdt_add_its_gic_node(VirtMachineState *vms)
 
 vms->msi_phandle = qemu_fdt_alloc_phandle(ams->fdt);
 nodename = g_strdup_printf("/intc/its@%" PRIx64,
-   vms->memmap[VIRT_GIC_ITS].base);
+   ams->memmap[VIRT_GIC_ITS].base);
 

[PATCH RFC 13/16] hw/arm: move shared fdt related functions to arm.c and export them

2020-02-16 Thread Xu Yandong
Move fdt related functions that will be shared between VIRT and
non-VIRT machine types to arm.c.

Signed-off-by: Xu Yandong 
---
 hw/arm/arm.c | 226 
 hw/arm/virt.c| 238 +--
 include/hw/arm/arm.h |   8 ++
 3 files changed, 238 insertions(+), 234 deletions(-)

diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index 6751c6a624..4bffee0f37 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -39,6 +39,232 @@
 #include "hw/intc/arm_gic.h"
 #include "kvm_arm.h"
 
+void create_fdt(ArmMachineState *ams)
+{
+MachineState *ms = MACHINE(ams);
+int nb_numa_nodes = ms->numa_state->num_nodes;
+void *fdt = create_device_tree(>fdt_size);
+
+if (!fdt) {
+error_report("create_device_tree() failed");
+exit(1);
+}
+
+ams->fdt = fdt;
+
+/* Header */
+qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
+qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
+qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
+
+/* /chosen must exist for load_dtb to fill in necessary properties later */
+qemu_fdt_add_subnode(fdt, "/chosen");
+
+/* Clock node, for the benefit of the UART. The kernel device tree
+ * binding documentation claims the PL011 node clock properties are
+ * optional but in practice if you omit them the kernel refuses to
+ * probe for the device.
+ */
+ams->clock_phandle = qemu_fdt_alloc_phandle(fdt);
+qemu_fdt_add_subnode(fdt, "/apb-pclk");
+qemu_fdt_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
+qemu_fdt_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
+qemu_fdt_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 2400);
+qemu_fdt_setprop_string(fdt, "/apb-pclk", "clock-output-names",
+"clk24mhz");
+qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", ams->clock_phandle);
+
+if (nb_numa_nodes > 0 && ms->numa_state->have_numa_distance) {
+int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
+uint32_t *matrix = g_malloc0(size);
+int idx, i, j;
+
+for (i = 0; i < nb_numa_nodes; i++) {
+for (j = 0; j < nb_numa_nodes; j++) {
+idx = (i * nb_numa_nodes + j) * 3;
+matrix[idx + 0] = cpu_to_be32(i);
+matrix[idx + 1] = cpu_to_be32(j);
+matrix[idx + 2] =
+cpu_to_be32(ms->numa_state->nodes[i].distance[j]);
+}
+}
+
+qemu_fdt_add_subnode(fdt, "/distance-map");
+qemu_fdt_setprop_string(fdt, "/distance-map", "compatible",
+"numa-distance-map-v1");
+qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
+ matrix, size);
+g_free(matrix);
+}
+}
+
+void fdt_add_timer_nodes(const ArmMachineState *ams)
+{
+/* On real hardware these interrupts are level-triggered.
+ * On KVM they were edge-triggered before host kernel version 4.4,
+ * and level-triggered afterwards.
+ * On emulated QEMU they are level-triggered.
+ *
+ * Getting the DTB info about them wrong is awkward for some
+ * guest kernels:
+ *  pre-4.8 ignore the DT and leave the interrupt configured
+ *   with whatever the GIC reset value (or the bootloader) left it at
+ *  4.8 before rc6 honour the incorrect data by programming it back
+ *   into the GIC, causing problems
+ *  4.8rc6 and later ignore the DT and always write "level triggered"
+ *   into the GIC
+ *
+ * For backwards-compatibility, virt-2.8 and earlier will continue
+ * to say these are edge-triggered, but later machines will report
+ * the correct information.
+ */
+ARMCPU *armcpu;
+ArmMachineClass *amc = ARM_MACHINE_GET_CLASS(ams);
+uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
+
+if (amc->claim_edge_triggered_timers) {
+irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
+}
+
+if (ams->gic_version == 2) {
+irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
+ GIC_FDT_IRQ_PPI_CPU_WIDTH,
+ (1 << ams->smp_cpus) - 1);
+}
+
+qemu_fdt_add_subnode(ams->fdt, "/timer");
+
+armcpu = ARM_CPU(qemu_get_cpu(0));
+if (arm_feature(>env, ARM_FEATURE_V8)) {
+const char compat[] = "arm,armv8-timer\0arm,armv7-timer";
+qemu_fdt_setprop(ams->fdt, "/timer", "compatible",
+ compat, sizeof(compat));
+} else {
+qemu_fdt_setprop_string(ams->fdt, "/timer", "compatible",
+"arm,armv7-timer");
+}
+qemu_fdt_setprop(ams->fdt, "/timer", "always-on", NULL, 0);
+qemu_fdt_setprop_cells(ams->fdt, "/timer", "interrupts",
+   GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
+   GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, 

[PATCH RFC 09/16] hw/arm: move shared gic member to ArmMachine

2020-02-16 Thread Xu Yandong
Move gic member from VirtMachineState to ArmMachineState.

Cc: Michael S. Tsirkin 
Cc: Igor Mammedov 
Cc: Shannon Zhao 
Signed-off-by: Xu Yandong 
---
 hw/arm/arm.c |  35 ++
 hw/arm/virt-acpi-build.c |   8 +--
 hw/arm/virt.c| 139 +++
 include/hw/arm/arm.h |  17 +
 include/hw/arm/virt.h|  15 -
 5 files changed, 110 insertions(+), 104 deletions(-)

diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index 4261d56832..ecb99611ed 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -39,6 +39,32 @@
 #include "hw/intc/arm_gic.h"
 #include "kvm_arm.h"
 
+static char *virt_get_gic_version(Object *obj, Error **errp)
+{
+ArmMachineState *ams = ARM_MACHINE(obj);
+const char *val = ams->gic_version == 3 ? "3" : "2";
+
+return g_strdup(val);
+}
+
+static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
+{
+ArmMachineState *ams = ARM_MACHINE(obj);
+
+if (!strcmp(value, "3")) {
+ams->gic_version = 3;
+} else if (!strcmp(value, "2")) {
+ams->gic_version = 2;
+} else if (!strcmp(value, "host")) {
+ams->gic_version = 0; /* Will probe later */
+} else if (!strcmp(value, "max")) {
+ams->gic_version = -1; /* Will probe later */
+} else {
+error_setg(errp, "Invalid gic-version value");
+error_append_hint(errp, "Valid values are 3, 2, host, max.\n");
+}
+}
+
 static void arm_machine_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -55,6 +81,15 @@ static void arm_machine_class_init(ObjectClass *oc, void 
*data)
 
 static void arm_instance_init(Object *obj)
 {
+ArmMachineState *ams = ARM_MACHINE(obj);
+/* Default GIC type is v2 */
+ams->gic_version = 2;
+object_property_add_str(obj, "gic-version", virt_get_gic_version,
+virt_set_gic_version, NULL);
+object_property_set_description(obj, "gic-version",
+"Set GIC version. "
+"Valid values are 2, 3 and host", NULL);
+
 }
 
 static const TypeInfo arm_machine_info = {
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index ef2761ef77..770c53f5d0 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -621,7 +621,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
 gicd->length = sizeof(*gicd);
 gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
-gicd->version = vms->gic_version;
+gicd->version = ams->gic_version;
 
 for (i = 0; i < ams->smp_cpus; i++) {
 AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
@@ -630,7 +630,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 
 gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
 gicc->length = sizeof(*gicc);
-if (vms->gic_version == 2) {
+if (ams->gic_version == 2) {
 gicc->base_address = cpu_to_le64(memmap[VIRT_GIC_CPU].base);
 gicc->gich_base_address = cpu_to_le64(memmap[VIRT_GIC_HYP].base);
 gicc->gicv_base_address = cpu_to_le64(memmap[VIRT_GIC_VCPU].base);
@@ -648,9 +648,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 }
 }
 
-if (vms->gic_version == 3) {
+if (ams->gic_version == 3) {
 AcpiMadtGenericTranslator *gic_its;
-int nb_redist_regions = virt_gicv3_redist_region_count(vms);
+int nb_redist_regions = virt_gicv3_redist_region_count(ams);
 AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
  sizeof *gicr);
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 087616190e..b9689b0f0c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -100,10 +100,6 @@
 #define DEFINE_VIRT_MACHINE(major, minor) \
 DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
 
-
-/* Number of external interrupt lines to configure the GIC with */
-#define NUM_IRQS 256
-
 #define PLATFORM_BUS_NUM_IRQS 64
 
 /* Legacy RAM limit in GB (< version 4.0) */
@@ -297,7 +293,7 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
 irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
 }
 
-if (vms->gic_version == 2) {
+if (ams->gic_version == 2) {
 irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
  GIC_FDT_IRQ_PPI_CPU_WIDTH,
  (1 << ams->smp_cpus) - 1);
@@ -435,7 +431,7 @@ static void fdt_gic_set_virt_extension(VirtMachineState 
*vms)
ams->memmap[VIRT_GIC_DIST].base);
 
 
-if (vms->gic_version == 3) {
+if (ams->gic_version == 3) {
 if (vms->virt) {
 qemu_fdt_setprop_cells(ams->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
@@ -470,8 +466,8 @@ 

[PATCH RFC 12/16] hw/arm: move shared devices related functions to arm.c and export them

2020-02-16 Thread Xu Yandong
Move device related functions to arm.c, include RTC(pl031), UART(pl011),
virtio devices.

Signed-off-by: Xu Yandong 
---
 hw/arm/arm.c  | 137 +
 hw/arm/virt.c | 156 +++---
 include/hw/arm/arm.h  |   8 +++
 include/hw/arm/virt.h |   1 -
 4 files changed, 153 insertions(+), 149 deletions(-)

diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index c51bf513d2..6751c6a624 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -145,6 +145,143 @@ void init_gic_sysbus(ArmMachineState *ams)
 }
 }
 
+void create_uart(const ArmMachineState *ams, int uart,
+MemoryRegion *mem, Chardev *chr)
+{
+char *nodename;
+hwaddr base = ams->memmap[uart].base;
+hwaddr size = ams->memmap[uart].size;
+int irq = ams->irqmap[uart];
+const char compat[] = "arm,pl011\0arm,primecell";
+const char clocknames[] = "uartclk\0apb_pclk";
+DeviceState *dev = qdev_create(NULL, "pl011");
+SysBusDevice *s = SYS_BUS_DEVICE(dev);
+
+qdev_prop_set_chr(dev, "chardev", chr);
+qdev_init_nofail(dev);
+memory_region_add_subregion(mem, base,
+sysbus_mmio_get_region(s, 0));
+sysbus_connect_irq(s, 0, qdev_get_gpio_in(ams->gic, irq));
+
+nodename = g_strdup_printf("/pl011@%" PRIx64, base);
+qemu_fdt_add_subnode(ams->fdt, nodename);
+/* Note that we can't use setprop_string because of the embedded NUL */
+qemu_fdt_setprop(ams->fdt, nodename, "compatible",
+ compat, sizeof(compat));
+qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
+ 2, base, 2, size);
+qemu_fdt_setprop_cells(ams->fdt, nodename, "interrupts",
+   GIC_FDT_IRQ_TYPE_SPI, irq,
+   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+qemu_fdt_setprop_cells(ams->fdt, nodename, "clocks",
+   ams->clock_phandle, ams->clock_phandle);
+qemu_fdt_setprop(ams->fdt, nodename, "clock-names",
+ clocknames, sizeof(clocknames));
+
+if (uart == VIRT_UART) {
+qemu_fdt_setprop_string(ams->fdt, "/chosen", "stdout-path", nodename);
+} else {
+/* Mark as not usable by the normal world */
+qemu_fdt_setprop_string(ams->fdt, nodename, "status", "disabled");
+qemu_fdt_setprop_string(ams->fdt, nodename, "secure-status", "okay");
+
+qemu_fdt_add_subnode(ams->fdt, "/secure-chosen");
+qemu_fdt_setprop_string(ams->fdt, "/secure-chosen", "stdout-path",
+nodename);
+}
+
+g_free(nodename);
+}
+
+void create_rtc(const ArmMachineState *ams)
+{
+char *nodename;
+hwaddr base = ams->memmap[VIRT_RTC].base;
+hwaddr size = ams->memmap[VIRT_RTC].size;
+int irq = ams->irqmap[VIRT_RTC];
+const char compat[] = "arm,pl031\0arm,primecell";
+
+sysbus_create_simple("pl031", base, qdev_get_gpio_in(ams->gic, irq));
+
+nodename = g_strdup_printf("/pl031@%" PRIx64, base);
+qemu_fdt_add_subnode(ams->fdt, nodename);
+qemu_fdt_setprop(ams->fdt, nodename, "compatible", compat, sizeof(compat));
+qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
+ 2, base, 2, size);
+qemu_fdt_setprop_cells(ams->fdt, nodename, "interrupts",
+   GIC_FDT_IRQ_TYPE_SPI, irq,
+   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+qemu_fdt_setprop_cell(ams->fdt, nodename, "clocks", ams->clock_phandle);
+qemu_fdt_setprop_string(ams->fdt, nodename, "clock-names", "apb_pclk");
+g_free(nodename);
+}
+
+void create_virtio_devices(const ArmMachineState *ams)
+{
+int i;
+hwaddr size = ams->memmap[VIRT_MMIO].size;
+
+/* We create the transports in forwards order. Since qbus_realize()
+ * prepends (not appends) new child buses, the incrementing loop below will
+ * create a list of virtio-mmio buses with decreasing base addresses.
+ *
+ * When a -device option is processed from the command line,
+ * qbus_find_recursive() picks the next free virtio-mmio bus in forwards
+ * order. The upshot is that -device options in increasing command line
+ * order are mapped to virtio-mmio buses with decreasing base addresses.
+ *
+ * When this code was originally written, that arrangement ensured that the
+ * guest Linux kernel would give the lowest "name" (/dev/vda, eth0, etc) to
+ * the first -device on the command line. (The end-to-end order is a
+ * function of this loop, qbus_realize(), qbus_find_recursive(), and the
+ * guest kernel's name-to-address assignment strategy.)
+ *
+ * Meanwhile, the kernel's traversal seems to have been reversed; see eg.
+ * the message, if not necessarily the code, of commit 70161ff336.
+ * Therefore the loop now establishes the inverse of the original intent.
+ *
+ * Unfortunately, we can't counteract the 

[PATCH RFC 14/16] hw/arm: move shared bootinfo member to ArmMachine

2020-02-16 Thread Xu Yandong
Move bootinfo member from VirtMachineState to ArmMachineState.

Signed-off-by: Xu Yandong 
---
 hw/arm/arm.c  |  9 +
 hw/arm/virt.c | 28 +---
 include/hw/arm/arm.h  |  3 +++
 include/hw/arm/virt.h |  1 -
 4 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index 4bffee0f37..7d880dd8e7 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -508,6 +508,15 @@ void create_virtio_devices(const ArmMachineState *ams)
 }
 }
 
+void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
+{
+const ArmMachineState *board = container_of(binfo, ArmMachineState,
+ bootinfo);
+
+*fdt_size = board->fdt_size;
+return board->fdt;
+}
+
 static char *virt_get_gic_version(Object *obj, Error **errp)
 {
 ArmMachineState *ams = ARM_MACHINE(obj);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 11e753906b..2f498ea687 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -971,16 +971,6 @@ static void create_secure_ram(VirtMachineState *vms,
 g_free(nodename);
 }
 
-static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
-{
-const VirtMachineState *vms = container_of(binfo, VirtMachineState,
- bootinfo);
-
-ArmMachineState *board = ARM_MACHINE(vms);
-*fdt_size = board->fdt_size;
-return board->fdt;
-}
-
 static void virt_build_smbios(VirtMachineState *vms)
 {
 MachineClass *mc = MACHINE_GET_CLASS(vms);
@@ -1016,7 +1006,7 @@ void virt_machine_done(Notifier *notifier, void *data)
 MachineState *ms = MACHINE(vms);
 ArmMachineState *ams = ARM_MACHINE(vms);
 ARMCPU *cpu = ARM_CPU(first_cpu);
-struct arm_boot_info *info = >bootinfo;
+struct arm_boot_info *info = >bootinfo;
 AddressSpace *as = arm_boot_address_space(cpu, info);
 
 /*
@@ -1373,14 +1363,14 @@ static void machvirt_init(MachineState *machine)
 
 create_platform_bus(vms);
 
-vms->bootinfo.ram_size = machine->ram_size;
-vms->bootinfo.nb_cpus = smp_cpus;
-vms->bootinfo.board_id = -1;
-vms->bootinfo.loader_start = ams->memmap[VIRT_MEM].base;
-vms->bootinfo.get_dtb = machvirt_dtb;
-vms->bootinfo.skip_dtb_autoload = true;
-vms->bootinfo.firmware_loaded = firmware_loaded;
-arm_load_kernel(ARM_CPU(first_cpu), machine, >bootinfo);
+ams->bootinfo.ram_size = machine->ram_size;
+ams->bootinfo.nb_cpus = smp_cpus;
+ams->bootinfo.board_id = -1;
+ams->bootinfo.loader_start = ams->memmap[VIRT_MEM].base;
+ams->bootinfo.get_dtb = machvirt_dtb;
+ams->bootinfo.skip_dtb_autoload = true;
+ams->bootinfo.firmware_loaded = firmware_loaded;
+arm_load_kernel(ARM_CPU(first_cpu), machine, >bootinfo);
 
 vms->machine_done.notify = virt_machine_done;
 qemu_add_machine_init_done_notifier(>machine_done);
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 743a90ba36..372f4dea28 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -92,6 +92,7 @@ typedef struct {
 typedef struct {
 MachineState parent;
 int32_t gic_version;
+struct arm_boot_info bootinfo;
 MemMapEntry *memmap;
 const int *irqmap;
 int smp_cpus;
@@ -130,6 +131,8 @@ void create_rtc(const ArmMachineState *ams);
 
 void create_virtio_devices(const ArmMachineState *ams);
 
+void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size);
+
 /* Return the number of used redistributor regions  */
 static inline int virt_gicv3_redist_region_count(ArmMachineState *ams)
 {
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 086a27682f..8276e2c02c 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -68,7 +68,6 @@ typedef struct {
 bool its;
 bool virt;
 VirtIOMMUType iommu;
-struct arm_boot_info bootinfo;
 uint32_t msi_phandle;
 uint32_t iommu_phandle;
 hwaddr highest_gpa;
-- 
2.18.1




[PATCH RFC 15/16] hw/arm: move shared cpu related functions to arm.c and export them

2020-02-16 Thread Xu Yandong
Move cpu related functions that will be shared between VIRT and
non-VIRT machine types to arm.c.

Signed-off-by: Xu Yandong 
---
 hw/arm/arm.c  | 89 ++
 hw/arm/virt.c | 91 +--
 include/hw/arm/arm.h  |  3 ++
 include/hw/arm/virt.h |  1 -
 4 files changed, 94 insertions(+), 90 deletions(-)

diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index 7d880dd8e7..8bb5d92d2e 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -39,6 +39,28 @@
 #include "hw/intc/arm_gic.h"
 #include "kvm_arm.h"
 
+static const char *valid_cpus[] = {
+ARM_CPU_TYPE_NAME("cortex-a7"),
+ARM_CPU_TYPE_NAME("cortex-a15"),
+ARM_CPU_TYPE_NAME("cortex-a53"),
+ARM_CPU_TYPE_NAME("cortex-a57"),
+ARM_CPU_TYPE_NAME("cortex-a72"),
+ARM_CPU_TYPE_NAME("host"),
+ARM_CPU_TYPE_NAME("max"),
+};
+
+bool cpu_type_valid(const char *cpu)
+{
+int i;
+
+for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) {
+if (strcmp(cpu, valid_cpus[i]) == 0) {
+return true;
+}
+}
+return false;
+}
+
 void create_fdt(ArmMachineState *ams)
 {
 MachineState *ms = MACHINE(ams);
@@ -543,6 +565,70 @@ static void virt_set_gic_version(Object *obj, const char 
*value, Error **errp)
 }
 }
 
+static uint64_t virt_cpu_mp_affinity(ArmMachineState *ams, int idx)
+{
+uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
+ArmMachineClass *amc = ARM_MACHINE_GET_CLASS(ams);
+
+if (!amc->disallow_affinity_adjustment) {
+/* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
+ * GIC's target-list limitations. 32-bit KVM hosts currently
+ * always create clusters of 4 CPUs, but that is expected to
+ * change when they gain support for gicv3. When KVM is enabled
+ * it will override the changes we make here, therefore our
+ * purposes are to make TCG consistent (with 64-bit KVM hosts)
+ * and to improve SGI efficiency.
+ */
+if (ams->gic_version == 3) {
+clustersz = GICV3_TARGETLIST_BITS;
+} else {
+clustersz = GIC_TARGETLIST_BITS;
+}
+}
+return arm_cpu_mp_affinity(idx, clustersz);
+}
+
+
+static CpuInstanceProperties
+virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
+{
+MachineClass *mc = MACHINE_GET_CLASS(ms);
+const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
+
+assert(cpu_index < possible_cpus->len);
+return possible_cpus->cpus[cpu_index].props;
+}
+
+
+static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
+{
+return idx % ms->numa_state->num_nodes;
+}
+
+static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
+{
+int n;
+unsigned int max_cpus = ms->smp.max_cpus;
+ArmMachineState *ams = ARM_MACHINE(ms);
+
+if (ms->possible_cpus) {
+assert(ms->possible_cpus->len == max_cpus);
+return ms->possible_cpus;
+}
+
+ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
+  sizeof(CPUArchId) * max_cpus);
+ms->possible_cpus->len = max_cpus;
+for (n = 0; n < ms->possible_cpus->len; n++) {
+ms->possible_cpus->cpus[n].type = ms->cpu_type;
+ms->possible_cpus->cpus[n].arch_id =
+virt_cpu_mp_affinity(ams, n);
+ms->possible_cpus->cpus[n].props.has_thread_id = true;
+ms->possible_cpus->cpus[n].props.thread_id = n;
+}
+return ms->possible_cpus;
+}
+
 static void arm_machine_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -555,6 +641,9 @@ static void arm_machine_class_init(ObjectClass *oc, void 
*data)
 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
 mc->numa_mem_supported = true;
 mc->auto_enable_numa_with_memhp = true;
+mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
+mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
+mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
 }
 
 static void arm_instance_init(Object *obj)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 2f498ea687..14d20d5c46 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -182,28 +182,6 @@ static const int a15irqmap[] = {
 [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
 };
 
-static const char *valid_cpus[] = {
-ARM_CPU_TYPE_NAME("cortex-a7"),
-ARM_CPU_TYPE_NAME("cortex-a15"),
-ARM_CPU_TYPE_NAME("cortex-a53"),
-ARM_CPU_TYPE_NAME("cortex-a57"),
-ARM_CPU_TYPE_NAME("cortex-a72"),
-ARM_CPU_TYPE_NAME("host"),
-ARM_CPU_TYPE_NAME("max"),
-};
-
-static bool cpu_type_valid(const char *cpu)
-{
-int i;
-
-for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) {
-if (strcmp(cpu, valid_cpus[i]) == 0) {
-return true;
-}
-}
-return false;
-}
-
 static void fdt_add_its_gic_node(VirtMachineState *vms)
 {
 char *nodename;
@@ -1030,30 +1008,6 @@ void 

[PATCH RFC 04/16] hw/arm: move shared irqmap member to ArmMachine

2020-02-16 Thread Xu Yandong
Move irqmap member from VirtMachineState to ArmMachineState.

Cc: Michael S. Tsirkin 
Cc: Igor Mammedov 
Cc: Shannon Zhao 
Signed-off-by: Xu Yandong 
---
 hw/arm/virt-acpi-build.c |  8 
 hw/arm/virt.c| 25 +
 include/hw/arm/arm.h |  1 +
 include/hw/arm/virt.h|  1 -
 4 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index ef61a651c1..27e6c95eca 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -414,7 +414,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 its->identifiers[0] = 0; /* MADT translation_id */
 
 if (vms->iommu == VIRT_IOMMU_SMMUV3) {
-int irq =  vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE;
+int irq =  ams->irqmap[VIRT_SMMU] + ARM_SPI_BASE;
 
 /* SMMUv3 node */
 smmu_offset = iort_node_offset + node_size;
@@ -488,7 +488,7 @@ build_spcr(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 AcpiSerialPortConsoleRedirection *spcr;
 ArmMachineState *ams = ARM_MACHINE(vms);
 const MemMapEntry *uart_memmap = >memmap[VIRT_UART];
-int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
+int irq = ams->irqmap[VIRT_UART] + ARM_SPI_BASE;
 int spcr_start = table_data->len;
 
 spcr = acpi_data_push(table_data, sizeof(*spcr));
@@ -609,7 +609,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 ArmMachineState *ams = ARM_MACHINE(vms);
 int madt_start = table_data->len;
 const MemMapEntry *memmap = ams->memmap;
-const int *irqmap = vms->irqmap;
+const int *irqmap = ams->irqmap;
 AcpiMultipleApicTable *madt;
 AcpiMadtGenericDistributor *gicd;
 AcpiMadtGenericMsiFrame *gic_msi;
@@ -730,7 +730,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 MachineState *ms = MACHINE(vms);
 ArmMachineState *ams = ARM_MACHINE(vms);
 const MemMapEntry *memmap = ams->memmap;
-const int *irqmap = vms->irqmap;
+const int *irqmap = ams->irqmap;
 
 dsdt = init_aml_allocator();
 /* Reserve space for header */
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1dea640719..e7eee13385 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -544,7 +544,7 @@ static inline DeviceState *create_acpi_ged(VirtMachineState 
*vms)
 DeviceState *dev;
 MachineState *ms = MACHINE(vms);
 ArmMachineState *ams = ARM_MACHINE(vms);
-int irq = vms->irqmap[VIRT_ACPI_GED];
+int irq = ams->irqmap[VIRT_ACPI_GED];
 uint32_t event = ACPI_GED_PWR_DOWN_EVT;
 
 if (ms->ram_slots) {
@@ -588,7 +588,7 @@ static void create_v2m(VirtMachineState *vms)
 {
 int i;
 ArmMachineState *ams = ARM_MACHINE(vms);
-int irq = vms->irqmap[VIRT_GIC_V2M];
+int irq = ams->irqmap[VIRT_GIC_V2M];
 DeviceState *dev;
 
 dev = qdev_create(NULL, "arm-gicv2m");
@@ -734,7 +734,7 @@ static void create_uart(const VirtMachineState *vms, int 
uart,
 const ArmMachineState *ams = ARM_MACHINE(vms);
 hwaddr base = ams->memmap[uart].base;
 hwaddr size = ams->memmap[uart].size;
-int irq = vms->irqmap[uart];
+int irq = ams->irqmap[uart];
 const char compat[] = "arm,pl011\0arm,primecell";
 const char clocknames[] = "uartclk\0apb_pclk";
 DeviceState *dev = qdev_create(NULL, "pl011");
@@ -782,7 +782,7 @@ static void create_rtc(const VirtMachineState *vms)
 const ArmMachineState *ams = ARM_MACHINE(vms);
 hwaddr base = ams->memmap[VIRT_RTC].base;
 hwaddr size = ams->memmap[VIRT_RTC].size;
-int irq = vms->irqmap[VIRT_RTC];
+int irq = ams->irqmap[VIRT_RTC];
 const char compat[] = "arm,pl031\0arm,primecell";
 
 sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
@@ -820,7 +820,7 @@ static void create_gpio(const VirtMachineState *vms)
 const ArmMachineState *ams = ARM_MACHINE(vms);
 hwaddr base = ams->memmap[VIRT_GPIO].base;
 hwaddr size = ams->memmap[VIRT_GPIO].size;
-int irq = vms->irqmap[VIRT_GPIO];
+int irq = ams->irqmap[VIRT_GPIO];
 const char compat[] = "arm,pl061\0arm,primecell";
 
 pl061_dev = sysbus_create_simple("pl061", base,
@@ -892,7 +892,7 @@ static void create_virtio_devices(const VirtMachineState 
*vms)
  * of disks users must use UUIDs or similar mechanisms.
  */
 for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) {
-int irq = vms->irqmap[VIRT_MMIO] + i;
+int irq = ams->irqmap[VIRT_MMIO] + i;
 hwaddr base = ams->memmap[VIRT_MMIO].base + i * size;
 
 sysbus_create_simple("virtio-mmio", base,
@@ -908,7 +908,7 @@ static void create_virtio_devices(const VirtMachineState 
*vms)
  */
 for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) {
 char *nodename;
-int irq = vms->irqmap[VIRT_MMIO] + i;
+int irq = ams->irqmap[VIRT_MMIO] + i;
 hwaddr base = ams->memmap[VIRT_MMIO].base + i * size;
 
 nodename = 

[PATCH RFC 00/16] Implement Microvm for aarch64 architecture

2020-02-16 Thread Xu Yandong
Implement Microvm for aarch64 architecture

This series attempts to implement microvm for aarch64
architecture.

Just like how Sergio Lopez does for implementing microvm
for x86 architecture. We remove parts of emulate devices which
are not needed in microvm, compared with normal VM,
We only keep PL011 (UART), PL031 (RTC) and virtio-mmio
devices for microvm of aarch64.

We compared the boot time between virt VM and microvm With the
follow command lines:
For microvm:
qemu-system-aarch64 \
-cpu host \
-smp 1,sockets=1,cores=1,threads=1 \
-m 1024M \
-machine microvm,accel=kvm,gic-version=3 \
-kernel vmlinux.bin \
-drive id=test,file=ubuntu-rootfs.img,format=raw,if=none \
-device virtio-blk-device,drive=test \
-netdev tap,id=tap0,script=no,downscript=no \
-device virtio-net-device,netdev=tap0 \
-append "root=/dev/vda rw printk.time=y" \
-nographic
Normal VM???Only changed the machine type to 'virt'
qemu-system-aarch64 \
-cpu host \
-smp 1,sockets=1,cores=1,threads=1 \
-m 1024M \
-machine virt,accel=kvm,gic-version=3 \
-kernel vmlinux.bin \
-drive id=test,file=ubuntu-rootfs.img,format=raw,if=none \
-device virtio-blk-device,drive=test \
-netdev tap,id=tap0,script=no,downscript=no \
-device virtio-net-device,netdev=tap0 \
-append "root=/dev/vda rw printk.time=y" \
-nographic

This is the test results:
1. Boot time
1) boot time after dropped caches(echo 3 > /proc/sys/vm/drop_caches)
normal virt Machine: 204 ms
microvm Machine: 132 ms

2) boot time with caches
normal virt Machine: 168 ms
microvm Machine: 71 ms

2. MMIO regions
normal virt Machine:
address-space: memory
  - (prio 0, i/o): system
-03ff (prio 0, romd): virt.flash0
0400-07ff (prio 0, romd): virt.flash1
0800-0800 (prio 0, i/o): gicv3_dist
0808-0809 (prio 0, i/o): gicv3_its
  0808-0808 (prio 0, i/o): control
  0809-0809 (prio 0, i/o): translation
080a-080b (prio 0, i/o): gicv3_redist_region[0]
0900-09000fff (prio 0, i/o): pl011
0901-09010fff (prio 0, i/o): pl031
0902-09020007 (prio 0, i/o): fwcfg.data
09020008-09020009 (prio 0, i/o): fwcfg.ctl
09020010-09020017 (prio 0, i/o): fwcfg.dma
0903-09030fff (prio 0, i/o): pl061
0a00-0a0001ff (prio 0, i/o): virtio-mmio
... skipped 30 virtio-mmio region
0a003e00-0a003fff (prio 0, i/o): virtio-mmio
0c00-0dff (prio 0, i/o): platform bus
1000-3efe (prio 0, i/o): alias pcie-mmio @gpex_mmio 
1000-3efe
3eff-3eff (prio 0, i/o): gpex_ioport
  3eff1000-3eff101f (prio 1, i/o): virtio-pci
4000-7fff (prio 0, ram): mach-virt.ram
00401000-00401fff (prio 0, i/o): alias pcie-ecam 
@pcie-mmcfg-mmio -0fff
0080-00ff (prio 0, i/o): alias pcie-mmio-high 
@gpex_mmio 0080-00ff

microvm Machine:
address-space: memory
  - (prio 0, i/o): system
  0800-0800 (prio 0, i/o): gicv3_dist
080a-080b (prio 0, i/o): gicv3_redist_region[0]
0900-09000fff (prio 0, i/o): pl011
0901-09010fff (prio 0, i/o): pl031
0a00-0a0001ff (prio 0, i/o): virtio-mmio
... skipped 30 virtio-mmio region
0a003e00-0a003fff (prio 0, i/o): virtio-mmio
4000-7fff (prio 0, ram): mach-virt.ram

Please review this series.

Thinks,
Xu Yandong.

Xu Yandong (16):
  hw/arm/arm: Introduce ArmMachineState and ArmMachineClass
  hw/arm: move shared fdt member to ArmMachine
  hw/arm: move shared memmap member to ArmMachine
  hw/arm: move shared irqmap member to ArmMachine
  hw/arm: move shared smp_cpus member to ArmMachine
  hw/arm/virt: split MSI related codes from create_gic
  hw/arm/virt: split virt extension related codes from create_gic
  hw/arm/virt: split secure extension related codes from create_gic
  hw/arm: move shared gic member to ArmMachine
  hw/arm: split create_gic function
  hw/arm: move shared psci_enable and claim_edge_triggered_timers member
to ArmMachine
  hw/arm: move shared devices related functions to arm.c and export them
  hw/arm: move shared fdt related functions to arm.c and export them
  hw/arm: move shared bootinfo member to ArmMachine
  hw/arm: move shared cpu related functions to arm.c and export them
  hw/arm: Introduce the microvm machine type

 default-configs/aarch64-softmmu.mak |2 +
 

[PATCH RFC 11/16] hw/arm: move shared psci_enable and claim_edge_triggered_timers member to ArmMachine

2020-02-16 Thread Xu Yandong
Move psci_enable member from VirtMachineState to ArmMachineState.
Move claim_edge_triggered_timers member from VirtMachineClass to
ArmMachineClass.

Cc: Michael S. Tsirkin 
Cc: Igor Mammedov 
Cc: Shannon Zhao 
Signed-off-by: Xu Yandong 
---
 hw/arm/virt-acpi-build.c |  7 ---
 hw/arm/virt.c| 14 +++---
 include/hw/arm/arm.h |  2 ++
 include/hw/arm/virt.h|  2 --
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 770c53f5d0..f2de897694 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -570,12 +570,12 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 static void
 build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
-VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+ArmMachineClass *amc = ARM_MACHINE_GET_CLASS(ARM_MACHINE(vms));
 int gtdt_start = table_data->len;
 AcpiGenericTimerTable *gtdt;
 uint32_t irqflags;
 
-if (vmc->claim_edge_triggered_timers) {
+if (amc->claim_edge_triggered_timers) {
 irqflags = ACPI_GTDT_INTERRUPT_MODE_EDGE;
 } else {
 irqflags = ACPI_GTDT_INTERRUPT_MODE_LEVEL;
@@ -696,6 +696,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 static void build_fadt_rev5(GArray *table_data, BIOSLinker *linker,
 VirtMachineState *vms, unsigned dsdt_tbl_offset)
 {
+ArmMachineState *ams = ARM_MACHINE(vms);
 /* ACPI v5.1 */
 AcpiFadtData fadt = {
 .rev = 5,
@@ -704,7 +705,7 @@ static void build_fadt_rev5(GArray *table_data, BIOSLinker 
*linker,
 .xdsdt_tbl_offset = _tbl_offset,
 };
 
-switch (vms->psci_conduit) {
+switch (ams->psci_conduit) {
 case QEMU_PSCI_CONDUIT_DISABLED:
 fadt.arm_boot_arch = 0;
 break;
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f971f49bcf..2c0dfb2695 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1576,11 +1576,11 @@ static void machvirt_init(MachineState *machine)
  * because if we're using KVM then we must use HVC).
  */
 if (vms->secure && firmware_loaded) {
-vms->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
+ams->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
 } else if (vms->virt) {
-vms->psci_conduit = QEMU_PSCI_CONDUIT_SMC;
+ams->psci_conduit = QEMU_PSCI_CONDUIT_SMC;
 } else {
-vms->psci_conduit = QEMU_PSCI_CONDUIT_HVC;
+ams->psci_conduit = QEMU_PSCI_CONDUIT_HVC;
 }
 
 /* The maximum number of CPUs depends on the GIC version, or on how
@@ -1641,8 +1641,8 @@ static void machvirt_init(MachineState *machine)
 object_property_set_bool(cpuobj, false, "has_el2", NULL);
 }
 
-if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) {
-object_property_set_int(cpuobj, vms->psci_conduit,
+if (ams->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) {
+object_property_set_int(cpuobj, ams->psci_conduit,
 "psci-conduit", NULL);
 
 /* Secondary CPUs start in PSCI powered-down state */
@@ -2186,14 +2186,14 @@ DEFINE_VIRT_MACHINE(2, 9)
 
 static void virt_machine_2_8_options(MachineClass *mc)
 {
-VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+ArmMachineClass *amc = ARM_MACHINE_CLASS(OBJECT_CLASS(mc));
 
 virt_machine_2_9_options(mc);
 compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
 /* For 2.8 and earlier we falsely claimed in the DT that
  * our timers were edge-triggered, not level-triggered.
  */
-vmc->claim_edge_triggered_timers = true;
+amc->claim_edge_triggered_timers = true;
 }
 DEFINE_VIRT_MACHINE(2, 8)
 
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 9ba51c4882..bb3680e583 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -86,6 +86,7 @@ typedef struct MemMapEntry {
 
 typedef struct {
 MachineClass parent;
+bool claim_edge_triggered_timers;
 } ArmMachineClass;
 
 typedef struct {
@@ -97,6 +98,7 @@ typedef struct {
 void *fdt;
 int fdt_size;
 uint32_t gic_phandle;
+int psci_conduit;
 DeviceState *gic;
 } ArmMachineState;
 
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 393afb7faf..ad94634038 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -50,7 +50,6 @@ typedef struct {
 bool disallow_affinity_adjustment;
 bool no_its;
 bool no_pmu;
-bool claim_edge_triggered_timers;
 bool smbios_old_sys_ver;
 bool no_highmem_ecam;
 bool no_ged;   /* Machines < 4.2 has no support for ACPI GED device */
@@ -73,7 +72,6 @@ typedef struct {
 uint32_t clock_phandle;
 uint32_t msi_phandle;
 uint32_t iommu_phandle;
-int psci_conduit;
 hwaddr highest_gpa;
 DeviceState *acpi_dev;
 Notifier powerdown_notifier;
-- 
2.18.1




[PATCH RFC 10/16] hw/arm: split create_gic function

2020-02-16 Thread Xu Yandong
Split sharable GIC qdev create and sysbus initiatea codes as independent 
function.

Signed-off-by: Xu Yandong 
---
 hw/arm/arm.c | 106 +++
 hw/arm/virt.c|  93 +
 include/hw/arm/arm.h |   4 ++
 3 files changed, 112 insertions(+), 91 deletions(-)

diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index ecb99611ed..c51bf513d2 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -39,6 +39,112 @@
 #include "hw/intc/arm_gic.h"
 #include "kvm_arm.h"
 
+void qdev_create_gic(ArmMachineState *ams)
+{
+MachineState *ms = MACHINE(ams);
+/* We create a standalone GIC */
+const char *gictype;
+int type = ams->gic_version;
+unsigned int smp_cpus = ms->smp.cpus;
+uint32_t nb_redist_regions = 0;
+
+gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
+
+ams->gic = qdev_create(NULL, gictype);
+qdev_prop_set_uint32(ams->gic, "revision", type);
+qdev_prop_set_uint32(ams->gic, "num-cpu", smp_cpus);
+/* Note that the num-irq property counts both internal and external
+ * interrupts; there are always 32 of the former (mandated by GIC spec).
+ */
+qdev_prop_set_uint32(ams->gic, "num-irq", NUM_IRQS + 32);
+
+if (type == 3) {
+uint32_t redist0_capacity =
+ams->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
+uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
+
+nb_redist_regions = virt_gicv3_redist_region_count(ams);
+
+qdev_prop_set_uint32(ams->gic, "len-redist-region-count",
+ nb_redist_regions);
+qdev_prop_set_uint32(ams->gic, "redist-region-count[0]", 
redist0_count);
+
+if (nb_redist_regions == 2) {
+uint32_t redist1_capacity =
+ams->memmap[VIRT_HIGH_GIC_REDIST2].size / 
GICV3_REDIST_SIZE;
+
+qdev_prop_set_uint32(ams->gic, "redist-region-count[1]",
+MIN(smp_cpus - redist0_count, redist1_capacity));
+}
+}
+}
+
+void init_gic_sysbus(ArmMachineState *ams)
+{
+MachineState *ms = MACHINE(ams);
+/* We create a standalone GIC */
+SysBusDevice *gicbusdev;
+int type = ams->gic_version, i;
+unsigned int smp_cpus = ms->smp.cpus;
+uint32_t nb_redist_regions = 0;
+
+gicbusdev = SYS_BUS_DEVICE(ams->gic);
+sysbus_mmio_map(gicbusdev, 0, ams->memmap[VIRT_GIC_DIST].base);
+if (type == 3) {
+sysbus_mmio_map(gicbusdev, 1, ams->memmap[VIRT_GIC_REDIST].base);
+if (nb_redist_regions == 2) {
+sysbus_mmio_map(gicbusdev, 2,
+ams->memmap[VIRT_HIGH_GIC_REDIST2].base);
+}
+} else {
+sysbus_mmio_map(gicbusdev, 1, ams->memmap[VIRT_GIC_CPU].base);
+}
+
+/* Wire the outputs from each CPU's generic timer and the GICv3
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
+ */
+for (i = 0; i < smp_cpus; i++) {
+DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
+int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
+int irq;
+/* Mapping from the output timer irq lines from the CPU to the
+ * GIC PPI inputs we use for the virt board.
+ */
+const int timer_irq[] = {
+[GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
+[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
+[GTIMER_HYP]  = ARCH_TIMER_NS_EL2_IRQ,
+[GTIMER_SEC]  = ARCH_TIMER_S_EL1_IRQ,
+};
+
+for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
+qdev_connect_gpio_out(cpudev, irq,
+  qdev_get_gpio_in(ams->gic,
+   ppibase + timer_irq[irq]));
+}
+
+if (type == 3) {
+qemu_irq irq = qdev_get_gpio_in(ams->gic,
+ppibase + ARCH_GIC_MAINT_IRQ);
+qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
+0, irq);
+}
+
+qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
+qdev_get_gpio_in(ams->gic, ppibase
+ + VIRTUAL_PMU_IRQ));
+
+sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, 
ARM_CPU_IRQ));
+sysbus_connect_irq(gicbusdev, i + smp_cpus,
+   qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
+   qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
+sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
+   qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
+}
+}
+
 static char *virt_get_gic_version(Object *obj, Error **errp)
 {
 ArmMachineState *ams = ARM_MACHINE(obj);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 

[PATCH RFC 06/16] hw/arm/virt: split MSI related codes from create_gic

2020-02-16 Thread Xu Yandong
GICv2m and GICits is not always needed.

Signed-off-by: Xu Yandong 
---
 hw/arm/virt.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 9031fd6757..32c3977e32 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -605,6 +605,15 @@ static void create_v2m(VirtMachineState *vms)
 fdt_add_v2m_gic_node(vms);
 }
 
+static void gic_set_msi_interrupt(VirtMachineState *vms)
+{
+if (vms->gic_version == 3 && vms->its) {
+create_its(vms);
+} else if (vms->gic_version == 2) {
+create_v2m(vms);
+}
+}
+
 static void create_gic(VirtMachineState *vms)
 {
 MachineState *ms = MACHINE(vms);
@@ -719,12 +728,7 @@ static void create_gic(VirtMachineState *vms)
 }
 
 fdt_add_gic_node(vms);
-
-if (type == 3 && vms->its) {
-create_its(vms);
-} else if (type == 2) {
-create_v2m(vms);
-}
+gic_set_msi_interrupt(vms);
 }
 
 static void create_uart(const VirtMachineState *vms, int uart,
-- 
2.18.1




[PATCH RFC 07/16] hw/arm/virt: split virt extension related codes from create_gic

2020-02-16 Thread Xu Yandong
EL2 extension is not always needed.

Signed-off-by: Xu Yandong 
---
 hw/arm/virt.c | 116 +-
 1 file changed, 77 insertions(+), 39 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 32c3977e32..afaf143888 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -426,6 +426,45 @@ static void fdt_add_v2m_gic_node(VirtMachineState *vms)
 g_free(nodename);
 }
 
+static void fdt_gic_set_virt_extension(VirtMachineState *vms)
+{
+char *nodename;
+ArmMachineState *ams = ARM_MACHINE(vms);
+
+nodename = g_strdup_printf("/intc@%" PRIx64,
+   ams->memmap[VIRT_GIC_DIST].base);
+
+
+if (vms->gic_version == 3) {
+if (vms->virt) {
+qemu_fdt_setprop_cells(ams->fdt, nodename, "interrupts",
+   GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
+   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+}
+} else {
+if (!vms->virt) {
+qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
+ 2, ams->memmap[VIRT_GIC_DIST].base,
+ 2, ams->memmap[VIRT_GIC_DIST].size,
+ 2, ams->memmap[VIRT_GIC_CPU].base,
+ 2, ams->memmap[VIRT_GIC_CPU].size);
+} else {
+qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
+ 2, ams->memmap[VIRT_GIC_DIST].base,
+ 2, ams->memmap[VIRT_GIC_DIST].size,
+ 2, ams->memmap[VIRT_GIC_CPU].base,
+ 2, ams->memmap[VIRT_GIC_CPU].size,
+ 2, ams->memmap[VIRT_GIC_HYP].base,
+ 2, ams->memmap[VIRT_GIC_HYP].size,
+ 2, ams->memmap[VIRT_GIC_VCPU].base,
+ 2, ams->memmap[VIRT_GIC_VCPU].size);
+qemu_fdt_setprop_cells(ams->fdt, nodename, "interrupts",
+   GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
+   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+}
+}
+}
+
 static void fdt_add_gic_node(VirtMachineState *vms)
 {
 char *nodename;
@@ -466,36 +505,10 @@ static void fdt_add_gic_node(VirtMachineState *vms)
  2, ams->memmap[VIRT_HIGH_GIC_REDIST2].base,
  2, ams->memmap[VIRT_HIGH_GIC_REDIST2].size);
 }
-
-if (vms->virt) {
-qemu_fdt_setprop_cells(ams->fdt, nodename, "interrupts",
-   GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
-   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
-}
 } else {
 /* 'cortex-a15-gic' means 'GIC v2' */
 qemu_fdt_setprop_string(ams->fdt, nodename, "compatible",
 "arm,cortex-a15-gic");
-if (!vms->virt) {
-qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
- 2, ams->memmap[VIRT_GIC_DIST].base,
- 2, ams->memmap[VIRT_GIC_DIST].size,
- 2, ams->memmap[VIRT_GIC_CPU].base,
- 2, ams->memmap[VIRT_GIC_CPU].size);
-} else {
-qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
- 2, ams->memmap[VIRT_GIC_DIST].base,
- 2, ams->memmap[VIRT_GIC_DIST].size,
- 2, ams->memmap[VIRT_GIC_CPU].base,
- 2, ams->memmap[VIRT_GIC_CPU].size,
- 2, ams->memmap[VIRT_GIC_HYP].base,
- 2, ams->memmap[VIRT_GIC_HYP].size,
- 2, ams->memmap[VIRT_GIC_VCPU].base,
- 2, ams->memmap[VIRT_GIC_VCPU].size);
-qemu_fdt_setprop_cells(ams->fdt, nodename, "interrupts",
-   GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
-   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
-}
 }
 
 qemu_fdt_setprop_cell(ams->fdt, nodename, "phandle", vms->gic_phandle);
@@ -614,6 +627,40 @@ static void gic_set_msi_interrupt(VirtMachineState *vms)
 }
 }
 
+static void qdev_gic_set_virt_bit(VirtMachineState *vms)
+{
+if (vms->gic_version != 3 && !kvm_irqchip_in_kernel()) {
+qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
+  vms->virt);
+}
+}
+
+static void set_gic_virt_sysbus(VirtMachineState *vms)
+{
+MachineState *ms = MACHINE(vms);
+ArmMachineState *ams = ARM_MACHINE(vms);
+SysBusDevice 

[PATCH RFC 08/16] hw/arm/virt: split secure extension related codes from create_gic

2020-02-16 Thread Xu Yandong
EL3 extension is not always needed.

Signed-off-by: Xu Yandong 
---
 hw/arm/virt.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index afaf143888..087616190e 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -627,6 +627,14 @@ static void gic_set_msi_interrupt(VirtMachineState *vms)
 }
 }
 
+static void qdev_gic_set_secure_bit(VirtMachineState *vms)
+{
+if (!kvm_irqchip_in_kernel()) {
+qdev_prop_set_bit(vms->gic, "has-security-extensions",
+  vms->secure);
+}
+}
+
 static void qdev_gic_set_virt_bit(VirtMachineState *vms)
 {
 if (vms->gic_version != 3 && !kvm_irqchip_in_kernel()) {
@@ -681,9 +689,6 @@ static void create_gic(VirtMachineState *vms)
  * interrupts; there are always 32 of the former (mandated by GIC spec).
  */
 qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
-if (!kvm_irqchip_in_kernel()) {
-qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure);
-}
 
 if (type == 3) {
 uint32_t redist0_capacity =
@@ -704,6 +709,7 @@ static void create_gic(VirtMachineState *vms)
 MIN(smp_cpus - redist0_count, redist1_capacity));
 }
 }
+qdev_gic_set_secure_bit(vms);
 qdev_gic_set_virt_bit(vms);
 qdev_init_nofail(vms->gic);
 gicbusdev = SYS_BUS_DEVICE(vms->gic);
-- 
2.18.1




[PATCH RFC 05/16] hw/arm: move shared smp_cpus member to ArmMachine

2020-02-16 Thread Xu Yandong
Move smp_cpus member from VirtMachineState to ArmMachineState.

Cc: Michael S. Tsirkin 
Cc: Igor Mammedov 
Cc: Shannon Zhao 
Signed-off-by: Xu Yandong 
---
 hw/arm/virt-acpi-build.c |  4 ++--
 hw/arm/virt.c| 12 ++--
 include/hw/arm/arm.h |  1 +
 include/hw/arm/virt.h|  3 +--
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 27e6c95eca..ef2761ef77 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -623,7 +623,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
 gicd->version = vms->gic_version;
 
-for (i = 0; i < vms->smp_cpus; i++) {
+for (i = 0; i < ams->smp_cpus; i++) {
 AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
sizeof(*gicc));
 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
@@ -742,7 +742,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
  * the RTC ACPI device at all when using UEFI.
  */
 scope = aml_scope("\\_SB");
-acpi_dsdt_add_cpus(scope, vms->smp_cpus);
+acpi_dsdt_add_cpus(scope, ams->smp_cpus);
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e7eee13385..9031fd6757 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -300,7 +300,7 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
 if (vms->gic_version == 2) {
 irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
  GIC_FDT_IRQ_PPI_CPU_WIDTH,
- (1 << vms->smp_cpus) - 1);
+ (1 << ams->smp_cpus) - 1);
 }
 
 qemu_fdt_add_subnode(ams->fdt, "/timer");
@@ -342,7 +342,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
  *  The simplest way to go is to examine affinity IDs of all our CPUs. If
  *  at least one of them has Aff3 populated, we set #address-cells to 2.
  */
-for (cpu = 0; cpu < vms->smp_cpus; cpu++) {
+for (cpu = 0; cpu < ams->smp_cpus; cpu++) {
 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
 
 if (armcpu->mp_affinity & ARM_AFF3_MASK) {
@@ -355,7 +355,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
 qemu_fdt_setprop_cell(ams->fdt, "/cpus", "#address-cells", addr_cells);
 qemu_fdt_setprop_cell(ams->fdt, "/cpus", "#size-cells", 0x0);
 
-for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) {
+for (cpu = ams->smp_cpus - 1; cpu >= 0; cpu--) {
 char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
 CPUState *cs = CPU(armcpu);
@@ -366,7 +366,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
 armcpu->dtb_compatible);
 
 if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED
-&& vms->smp_cpus > 1) {
+&& ams->smp_cpus > 1) {
 qemu_fdt_setprop_string(ams->fdt, nodename,
 "enable-method", "psci");
 }
@@ -525,7 +525,7 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
 if (vms->gic_version == 2) {
 irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
  GIC_FDT_IRQ_PPI_CPU_WIDTH,
- (1 << vms->smp_cpus) - 1);
+ (1 << ams->smp_cpus) - 1);
 }
 
 armcpu = ARM_CPU(qemu_get_cpu(0));
@@ -1641,7 +1641,7 @@ static void machvirt_init(MachineState *machine)
 exit(1);
 }
 
-vms->smp_cpus = smp_cpus;
+ams->smp_cpus = smp_cpus;
 
 if (vms->virt && kvm_enabled()) {
 error_report("mach-virt: KVM does not support providing "
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 97cb902b6a..469f603e77 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -89,6 +89,7 @@ typedef struct {
 MachineState parent;
 MemMapEntry *memmap;
 const int *irqmap;
+int smp_cpus;
 void *fdt;
 int fdt_size;
 } ArmMachineState;
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 4028821a09..dfc2a16010 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -71,7 +71,6 @@ typedef struct {
 int32_t gic_version;
 VirtIOMMUType iommu;
 struct arm_boot_info bootinfo;
-int smp_cpus;
 uint32_t clock_phandle;
 uint32_t gic_phandle;
 uint32_t msi_phandle;
@@ -104,7 +103,7 @@ static inline int 
virt_gicv3_redist_region_count(VirtMachineState *vms)
 
 assert(vms->gic_version == 3);
 
-return vms->smp_cpus > redist0_capacity ? 2 : 1;
+return ams->smp_cpus > redist0_capacity ? 2 : 1;
 }
 
 #endif /* QEMU_ARM_VIRT_H */
-- 
2.18.1




Re: [PATCH v3] Implement the Screamer sound chip for the mac99 machine type

2020-02-16 Thread Howard Spoelstra
Hi Howard, could you test out this patch for me on Fedora 31? It is to be
> applied over the v3 patch.
>
> Thank you.
>
> ---
>  hw/audio/screamer.c | 12 +++-
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/hw/audio/screamer.c b/hw/audio/screamer.c
> index ad4aba12eb..7de17fe8a6 100644
> --- a/hw/audio/screamer.c
> +++ b/hw/audio/screamer.c
> @@ -14,7 +14,7 @@
>  #include "migration/vmstate.h"
>  #include "include/hw/audio/screamer.h"
>
> -#define DEBUG_SCREAMER 0
> +#define DEBUG_SCREAMER 1
>  #define DPRINTF(fmt, ...) \
>  do { if (DEBUG_SCREAMER) { printf(fmt , ## __VA_ARGS__); } } while (0)
>
> @@ -836,11 +836,12 @@ static uint64_t screamer_mmio_read(void *opaque,
> hwaddr addr, unsigned size)
>  return_value = get_frame_count_reg(state);
>  break;
>  default:
> -DPRINTF("Unknown register read - addr:%llu\tsize:%d\n", addr,
> size);
> +DPRINTF("Unknown register read - addr:%" HWADDR_PRIx
> "\tsize:%d\n",
> +addr, size);
>  return_value = 12021981; /* Value used for debugging purposes */
>  }
> -DPRINTF("screamer_mmio_read() called addr: %llu  size: %d", addr >> 4,
> -size);
> +DPRINTF("screamer_mmio_read() called addr: %" HWADDR_PRIx "  size:
> %d",
> +addr >> 4, size);
>  DPRINTF("  returning 0x%x\n", return_value);
>  return return_value;
>  }
> @@ -875,7 +876,8 @@ static void screamer_mmio_write(void *opaque, hwaddr
> addr, uint64_t raw_value,
>  set_frame_count_reg(state, value);
>  break;
>  default:
> -DPRINTF("Unknown register write - addr:%llu\tvalue:%d\n", addr,
> value);
> +DPRINTF("Unknown register write - addr:%" HWADDR_PRIx
> "\tvalue:%d\n",
> +addr, value);
>  }
>  }
>
>
>
Tested, compiles cleanly. Debug output seems OK.

Best,
Howard


Re: [PATCH v4 1/4] qapi: Add a 'coroutine' flag for commands

2020-02-16 Thread Markus Armbruster
Kevin Wolf  writes:

> This patch adds a new 'coroutine' flag to QMP command definitions that
> tells the QMP dispatcher that the command handler is safe to be run in a
> coroutine.
>
> The documentation of the new flag pretends that this flag is already
> used as intended, which it isn't yet after this patch. We'll implement
> this in another patch in this series.
>
> Signed-off-by: Kevin Wolf 
> Reviewed-by: Marc-André Lureau 
> ---
>  docs/devel/qapi-code-gen.txt| 10 ++
>  include/qapi/qmp/dispatch.h |  1 +
>  tests/test-qmp-cmds.c   |  4 
>  scripts/qapi/commands.py| 10 +++---
>  scripts/qapi/doc.py |  2 +-
>  scripts/qapi/expr.py|  7 +--
>  scripts/qapi/introspect.py  |  2 +-
>  scripts/qapi/schema.py  |  9 ++---
>  tests/qapi-schema/test-qapi.py  |  7 ---
>  tests/Makefile.include  |  1 +
>  tests/qapi-schema/oob-coroutine.err |  2 ++
>  tests/qapi-schema/oob-coroutine.json|  2 ++
>  tests/qapi-schema/oob-coroutine.out |  0
>  tests/qapi-schema/qapi-schema-test.json |  1 +
>  tests/qapi-schema/qapi-schema-test.out  |  2 ++
>  15 files changed, 47 insertions(+), 13 deletions(-)
>  create mode 100644 tests/qapi-schema/oob-coroutine.err
>  create mode 100644 tests/qapi-schema/oob-coroutine.json
>  create mode 100644 tests/qapi-schema/oob-coroutine.out
>
> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
> index 59d6973e1e..9b65cd3ab3 100644
> --- a/docs/devel/qapi-code-gen.txt
> +++ b/docs/devel/qapi-code-gen.txt
> @@ -457,6 +457,7 @@ Syntax:
>  '*gen': false,
>  '*allow-oob': true,
>  '*allow-preconfig': true,
> +'*coroutine': true,
>  '*if': COND,
>  '*features': FEATURES }
>  
> @@ -581,6 +582,15 @@ before the machine is built.  It defaults to false.  For 
> example:
>  QMP is available before the machine is built only when QEMU was
>  started with --preconfig.
>  
> +Member 'coroutine' tells the QMP dispatcher whether the command handler
> +is safe to be run in a coroutine.  It defaults to false.  If it is true,
> +the command handler is called from coroutine context and may yield while
> +waiting for an external event (such as I/O completion) in order to avoid
> +blocking the guest and other background operations.
> +
> +It is an error to specify both 'coroutine': true and 'allow-oob': true
> +for a command.
> +
>  The optional 'if' member specifies a conditional.  See "Configuring
>  the schema" below for more on this.
>  
> diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
> index 9aa426a398..d6ce9efc8e 100644
> --- a/include/qapi/qmp/dispatch.h
> +++ b/include/qapi/qmp/dispatch.h
> @@ -24,6 +24,7 @@ typedef enum QmpCommandOptions
>  QCO_NO_SUCCESS_RESP   =  (1U << 0),
>  QCO_ALLOW_OOB =  (1U << 1),
>  QCO_ALLOW_PRECONFIG   =  (1U << 2),
> +QCO_COROUTINE =  (1U << 3),
>  } QmpCommandOptions;
>  
>  typedef struct QmpCommand
> diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c
> index 79507d9e54..6359cc28c7 100644
> --- a/tests/test-qmp-cmds.c
> +++ b/tests/test-qmp-cmds.c
> @@ -35,6 +35,10 @@ void qmp_cmd_success_response(Error **errp)
>  {
>  }
>  
> +void qmp_coroutine_cmd(Error **errp)
> +{
> +}
> +
>  Empty2 *qmp_user_def_cmd0(Error **errp)
>  {
>  return g_new0(Empty2, 1);
> diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
> index afa55b055c..f2f2f8948d 100644
> --- a/scripts/qapi/commands.py
> +++ b/scripts/qapi/commands.py
> @@ -194,7 +194,8 @@ out:
>  return ret
>  
>  
> -def gen_register_command(name, success_response, allow_oob, allow_preconfig):
> +def gen_register_command(name, success_response, allow_oob, allow_preconfig,
> + coroutine):
>  options = []
>  
>  if not success_response:
> @@ -203,6 +204,8 @@ def gen_register_command(name, success_response, 
> allow_oob, allow_preconfig):
>  options += ['QCO_ALLOW_OOB']
>  if allow_preconfig:
>  options += ['QCO_ALLOW_PRECONFIG']
> +if coroutine:
> +options += ['QCO_COROUTINE']
>  
>  if not options:
>  options = ['QCO_NO_OPTIONS']
> @@ -285,7 +288,7 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
>  
>  def visit_command(self, name, info, ifcond, arg_type, ret_type, gen,
>success_response, boxed, allow_oob, allow_preconfig,
> -  features):
> +  coroutine, features):
>  if not gen:
>  return
>  # FIXME: If T is a user-defined type, the user is responsible
> @@ -303,7 +306,8 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
>  self._genh.add(gen_marshal_decl(name))
>  self._genc.add(gen_marshal(name, arg_type, boxed, 

Re: QAPI schema for desired state of LUKS keyslots

2020-02-16 Thread Markus Armbruster
Maxim Levitsky  writes:

> On Sat, 2020-02-15 at 15:51 +0100, Markus Armbruster wrote:
>> Review of this patch led to a lengthy QAPI schema design discussion.
>> Let me try to condense it into a concrete proposal.
>> 
>> This is about the QAPI schema, and therefore about QMP.  The
>> human-friendly interface is out of scope.  Not because it's not
>> important (it clearly is!), only because we need to *focus* to have a
>> chance at success.
> 100% agree.
>> 
>> I'm going to include a few design options.  I'll mark them "Option:".
>> 
>> The proposed "amend" interface takes a specification of desired state,
>> and figures out how to get from here to there by itself.  LUKS keyslots
>> are one part of desired state.
>> 
>> We commonly have eight LUKS keyslots.  Each keyslot is either active or
>> inactive.  An active keyslot holds a secret.
>> 
>> Goal: a QAPI type for specifying desired state of LUKS keyslots.
>> 
>> Proposal:
>> 
>> { 'enum': 'LUKSKeyslotState',
>>   'data': [ 'active', 'inactive' ] }
>> 
>> { 'struct': 'LUKSKeyslotActive',
>>   'data': { 'secret': 'str',
>> '*iter-time': 'int } }
>> 
>> { 'struct': 'LUKSKeyslotInactive',
>>   'data': { '*old-secret': 'str' } }
>> 
>> { 'union': 'LUKSKeyslotAmend',
>>   'base': { '*keyslot': 'int',
>> 'state': 'LUKSKeyslotState' }
>>   'discriminator': 'state',
>>   'data': { 'active': 'LUKSKeyslotActive',
>> 'inactive': 'LUKSKeyslotInactive' } }
>> 
>> LUKSKeyslotAmend specifies desired state for a set of keyslots.
>> 
>> Four cases:
>> 
>> * @state is "active"
>> 
>>   Desired state is active holding the secret given by @secret.  Optional
>>   @iter-time tweaks key stretching.
>> 
>>   The keyslot is chosen either by the user or by the system, as follows:
>> 
>>   - @keyslot absent
>> 
>> One inactive keyslot chosen by the system.  If none exists, error.
>> 
>>   - @keyslot present
>> 
>> The keyslot given by @keyslot.
>> 
>> If it's already active holding @secret, no-op.  Rationale: the
>> current state is the desired state.
>> 
>> If it's already active holding another secret, error.  Rationale:
>> update in place is unsafe.
>> 
>> Option: delete the "already active holding @secret" case.  Feels
>> inelegant to me.  Okay if it makes things substantially simpler.
> I didn't really understand this, since in state=active we shouldn't
> delete anything. Looks OK otherwise.

Let me try to clarify.

Option: make the "already active holding @secret" case an error like the
"already active holding another secret" case.  In longhand:

 - @keyslot present

   The keyslot given by @keyslot.

   If it's already active, error.

It feels inelegant to me, because it deviates from "specify desired
state" paradigm: the specified desired state is fine, the way to get
there from current state is obvious (do nothing), yet it's still an
error.

>> * @state is "inactive"
>> 
>>   Desired state is inactive.
>> 
>>   Error if the current state has active keyslots, but the desired state
>>   has none.
>> 
>>   The user choses the keyslot by number and/or by the secret it holds,
>>   as follows:
>> 
>>   - @keyslot absent, @old-secret present
>> 
>> All active keyslots holding @old-secret.  If none exists, error.
>> 
>>   - @keyslot present, @old-secret absent
>> 
>> The keyslot given by @keyslot.
>> 
>> If it's already inactive, no-op.  Rationale: the current state is
>> the desired state.
>> 
>>   - both @keyslot and @old-secret present
>> 
>> The keyslot given by keyslot.
>> 
>> If it's inactive or holds a secret other than @old-secret, error.
> Yea, that would be very nice to have.
>> 
>> Option: error regardless of @old-secret, if that makes things
>> simpler.
>> 
>>   - neither @keyslot not @old-secret present
>> 
>> All keyslots.  Note that this will error out due to "desired state
>> has no active keyslots" unless the current state has none, either.
>> 
>> Option: error out unconditionally.
> Yep, that the best IMHO.

It's a matter of taste.

If we interpret "both absent" as "all keyslots", then all cases flow out
of the following simple spec:

0. Start with the set of all keyslots

1. If @old-secret is present, interset it with the set of slots
   holding that secret.

2. If @keyslots is present, intersect it with the set of slots with
   that slot number.

The order of steps 1 and 2 doesn't matter.

To error out unconditionally, we have to make "both absent" a special
case.

A good way to resolve such matters of taste is to try writing doc
comments for all proposals.  If you find you hate one of them much less,
you have a winner :)

[...]




Re: [PATCH v2 07/30] qapi/block-core.json: Use literal block for ascii art

2020-02-16 Thread Samuel Thibault
Hello,

Philippe Mathieu-Daudé, le lun. 17 févr. 2020 01:44:35 +0100, a ecrit:
> On Sat, Feb 15, 2020 at 10:01 PM Aleksandar Markovic
>  wrote:
> > 9:56 PM Sub, 15.02.2020. Philippe Mathieu-Daudé 
> >  је написао/ла:
> > > On Fri, Feb 14, 2020 at 12:04 AM Aleksandar Markovic
> > >  wrote:
> > > >
> > > > 6:59 PM Čet, 13.02.2020. Peter Maydell  је 
> > > > написао/ла:
> > > > >
> > > > > The ascii-art graph
> > > >
> > > > Just out of couriousity, are unicode characters allowed in rst files?
> > >
> > > I remember 2 years ago a blind developer thanked the QEMU community to
> > > still restrict commits to 80 characters, because while 4K display are
> > > available, he and other visually impaired developers cloud still
> > > browse the QEMU codebase with their refreshable Braille display (which
> > > was 80 cels). I don't know how many visually impaired developers are
> > > following this project. A quick google returns " There is no concept
> > > of Unicode in Braille. In that sense Braille is similar to old 8-bit
> > > code pages which represented different symbols in different languages
> > > for the same symbol code."
> > > (https://superuser.com/questions/629443/represent-unicode-characters-in-braille).
> > >
> > > (I'm Cc'ing Samuel who cares about Braille displays.)

Nowadays' screen reader do provide some translations for some unicode
fancies. But the analogy with codepage remains true: since there are
only 256 braille pattern, there will be ambiguity between representation
of plain text and representation of unicode fancies. Using plain ascii
avoids this issue, i.e. blind developers will know that '|' and '-' are
commonly used for drawing, and their Braille representations are not
ambiguous. So that's indeed better to keep them ascii.

More generally, ascii art is however hard to catch with a Braille device
anyway...

Samuel



Re: The issues about architecture of the COLO checkpoint

2020-02-16 Thread Zhang, Chen


On 2/15/2020 11:35 AM, Daniel Cho wrote:

Hi Dave,

Yes, I agree with you, it does need a timeout.



Hi Daniel and Dave,

Current colo-compare already have the timeout mechanism.

Named packet_check_timer,  It will scan primary packet queue to make 
sure all the primary packet not stay too long time.


If colo-compare got a primary packet without related secondary packet in 
a certain time , it will automatic trigger checkpoint.


https://github.com/qemu/qemu/blob/master/net/colo-compare.c#L847


Thanks

Zhang Chen




Hi Hailiang,

We base on qemu-4.1.0 for using COLO feature, in your patch, we found 
a lot of difference  between your version and ours.
Could you give us a latest release version which is close your 
developing code?


Thanks.

Regards
Daniel Cho

Dr. David Alan Gilbert > 於 2020年2月13日 週四 下午6:38寫道:


* Daniel Cho (daniel...@qnap.com ) wrote:
> Hi Hailiang,
>
> 1.
>     OK, we will try the patch
> “0001-COLO-Optimize-memory-back-up-process.patch”,
> and thanks for your help.
>
> 2.
>     We understand the reason to compare PVM and SVM's packet.
However, the
> empty of SVM's packet queue might happened on setting COLO
feature and SVM
> broken.
>
> On situation 1 ( setting COLO feature ):
>     We could force do checkpoint after setting COLO feature
finish, then it
> will protect the state of PVM and SVM . As the Zhang Chen said.
>
> On situation 2 ( SVM broken ):
>     COLO will do failover for PVM, so it might not cause any
wrong on PVM.
>
> However, those situations are our views, so there might be a big
difference
> between reality and our views.
> If we have any wrong views and opinions, please let us know, and
correct
> us.

It does need a timeout; the SVM being broken or being in a state where
it never sends the corresponding packet (because of a state
difference)
can happen and COLO needs to timeout when the packet hasn't arrived
after a while and trigger the checkpoint.

Dave

> Thanks.
>
> Best regards,
> Daniel Cho
>
> Zhang, Chen mailto:chen.zh...@intel.com>>
於 2020年2月13日 週四 上午10:17寫道:
>
> > Add cc Jason Wang, he is a network expert.
> >
> > In case some network things goes wrong.
> >
> >
> >
> > Thanks
> >
> > Zhang Chen
> >
> >
> >
> > *From:* Zhang, Chen
> > *Sent:* Thursday, February 13, 2020 10:10 AM
> > *To:* 'Zhanghailiang' mailto:zhang.zhanghaili...@huawei.com>>; Daniel Cho <
> > daniel...@qnap.com >
> > *Cc:* Dr. David Alan Gilbert mailto:dgilb...@redhat.com>>; qemu-devel@nongnu.org

> > *Subject:* RE: The issues about architecture of the COLO
checkpoint
> >
> >
> >
> > For the issue 2:
> >
> >
> >
> > COLO need use the network packets to confirm PVM and SVM in
the same state,
> >
> > Generally speaking, we can’t send PVM packets without compared
with SVM
> > packets.
> >
> > But to prevent jamming, I think COLO can do force checkpoint
and send the
> > PVM packets in this case.
> >
> >
> >
> > Thanks
> >
> > Zhang Chen
> >
> >
> >
> > *From:* Zhanghailiang mailto:zhang.zhanghaili...@huawei.com>>
> > *Sent:* Thursday, February 13, 2020 9:45 AM
> > *To:* Daniel Cho mailto:daniel...@qnap.com>>
> > *Cc:* Dr. David Alan Gilbert mailto:dgilb...@redhat.com>>; qemu-devel@nongnu.org
;
> > Zhang, Chen mailto:chen.zh...@intel.com>>
> > *Subject:* RE: The issues about architecture of the COLO
checkpoint
> >
> >
> >
> > Hi,
> >
> >
> >
> > 1.       After re-walked through the codes, yes, you are
right, actually,
> > after the first migration, we will keep dirty log on in
primary side,
> >
> > And only send the dirty pages in PVM to SVM. The ram cache in
secondary
> > side is always a backup of PVM, so we don’t have to
> >
> > Re-send the none-dirtied pages.
> >
> > The reason why the first checkpoint takes longer time is we
have to backup
> > the whole VM’s ram into ram cache, that is colo_init_ram_cache().
> >
> > It is time consuming, but I have optimized in the second patch
> > “0001-COLO-Optimize-memory-back-up-process.patch” which you
can find in my
> > previous reply.
> >
> >
> >
> > Besides, I found that, In my previous reply “We can only copy
the pages
> > that dirtied by PVM and SVM in last checkpoint.”,
> >
> > We have done this optimization in current upstream codes.
> >
> >
> >
> > 2.I don’t quite understand this question. For COLO, we always
need both
> > network packets of PVM’s and SVM’s 

[PATCH v2 2/2] hw: move timer_new from init() into realize() to avoid memleaks

2020-02-16 Thread pannengyuan
From: Pan Nengyuan 

There are some memleaks when we call 'device_list_properties'. This patch move 
timer_new from init into realize to fix it.
Meanwhile, do the null check in mos6522_reset() to avoid null deref if we move 
timer_new into realize().

Reported-by: Euler Robot 
Signed-off-by: Pan Nengyuan 
Reviewed-by: Philippe Mathieu-Daudé 
---
Changes v2 to v1:
- Send this patch in a series instead of a single patch but with wrong subject 
in v1.
---
 hw/arm/pxa2xx.c| 17 +++--
 hw/arm/spitz.c |  8 +++-
 hw/arm/strongarm.c | 18 --
 hw/misc/mos6522.c  | 14 --
 hw/timer/cadence_ttc.c | 16 +++-
 5 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index b33f8f1351..56a36202d7 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1134,18 +1134,22 @@ static void pxa2xx_rtc_init(Object *obj)
 s->last_rtcpicr = 0;
 s->last_hz = s->last_sw = s->last_pi = qemu_clock_get_ms(rtc_clock);
 
+sysbus_init_irq(dev, >rtc_irq);
+
+memory_region_init_io(>iomem, obj, _rtc_ops, s,
+  "pxa2xx-rtc", 0x1);
+sysbus_init_mmio(dev, >iomem);
+}
+
+static void pxa2xx_rtc_realize(DeviceState *dev, Error **errp)
+{
+PXA2xxRTCState *s = PXA2XX_RTC(dev);
 s->rtc_hz= timer_new_ms(rtc_clock, pxa2xx_rtc_hz_tick,s);
 s->rtc_rdal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
 s->rtc_rdal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
 s->rtc_swal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
 s->rtc_swal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
 s->rtc_pi= timer_new_ms(rtc_clock, pxa2xx_rtc_pi_tick,s);
-
-sysbus_init_irq(dev, >rtc_irq);
-
-memory_region_init_io(>iomem, obj, _rtc_ops, s,
-  "pxa2xx-rtc", 0x1);
-sysbus_init_mmio(dev, >iomem);
 }
 
 static int pxa2xx_rtc_pre_save(void *opaque)
@@ -1203,6 +1207,7 @@ static void pxa2xx_rtc_sysbus_class_init(ObjectClass 
*klass, void *data)
 
 dc->desc = "PXA2xx RTC Controller";
 dc->vmsd = _pxa2xx_rtc_regs;
+dc->realize = pxa2xx_rtc_realize;
 }
 
 static const TypeInfo pxa2xx_rtc_sysbus_info = {
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index e001088103..cbfa6934cf 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -524,11 +524,16 @@ static void spitz_keyboard_init(Object *obj)
 
 spitz_keyboard_pre_map(s);
 
-s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
 qdev_init_gpio_in(dev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
 qdev_init_gpio_out(dev, s->sense, SPITZ_KEY_SENSE_NUM);
 }
 
+static void spitz_keyboard_realize(DeviceState *dev, Error **errp)
+{
+SpitzKeyboardState *s = SPITZ_KEYBOARD(dev);
+s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
+}
+
 /* LCD backlight controller */
 
 #define LCDTG_RESCTL   0x00
@@ -1115,6 +1120,7 @@ static void spitz_keyboard_class_init(ObjectClass *klass, 
void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->vmsd = _spitz_kbd;
+dc->realize = spitz_keyboard_realize;
 }
 
 static const TypeInfo spitz_keyboard_info = {
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index cd8a99aaf2..3010d765bb 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -399,9 +399,6 @@ static void strongarm_rtc_init(Object *obj)
 s->last_rcnr = (uint32_t) mktimegm();
 s->last_hz = qemu_clock_get_ms(rtc_clock);
 
-s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
-s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
-
 sysbus_init_irq(dev, >rtc_irq);
 sysbus_init_irq(dev, >rtc_hz_irq);
 
@@ -410,6 +407,13 @@ static void strongarm_rtc_init(Object *obj)
 sysbus_init_mmio(dev, >iomem);
 }
 
+static void strongarm_rtc_realize(DeviceState *dev, Error **errp)
+{
+StrongARMRTCState *s = STRONGARM_RTC(dev);
+s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
+s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
+}
+
 static int strongarm_rtc_pre_save(void *opaque)
 {
 StrongARMRTCState *s = opaque;
@@ -451,6 +455,7 @@ static void strongarm_rtc_sysbus_class_init(ObjectClass 
*klass, void *data)
 
 dc->desc = "StrongARM RTC Controller";
 dc->vmsd = _strongarm_rtc_regs;
+dc->realize = strongarm_rtc_realize;
 }
 
 static const TypeInfo strongarm_rtc_sysbus_info = {
@@ -1240,15 +1245,16 @@ static void strongarm_uart_init(Object *obj)
   "uart", 0x1);
 sysbus_init_mmio(dev, >iomem);
 sysbus_init_irq(dev, >irq);
-
-s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
strongarm_uart_rx_to, s);
-s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
 }
 
 static void strongarm_uart_realize(DeviceState *dev, Error **errp)
 {
 StrongARMUARTState *s = STRONGARM_UART(dev);
 
+s->rx_timeout_timer = 

[PATCH v2 1/2] s390x: fix memleaks in cpu_finalize

2020-02-16 Thread pannengyuan
From: Pan Nengyuan 

This patch fix memleaks when we call tests/qtest/cpu-plug-test on s390x. The 
leak stack is as follow:

Direct leak of 48 byte(s) in 1 object(s) allocated from:
#0 0x7fb43c7cd970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970)
#1 0x7fb43be2149d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d)
#2 0x558ba96da716 in timer_new_full 
/mnt/sdb/qemu-new/qemu/include/qemu/timer.h:530
#3 0x558ba96da716 in timer_new 
/mnt/sdb/qemu-new/qemu/include/qemu/timer.h:551
#4 0x558ba96da716 in timer_new_ns 
/mnt/sdb/qemu-new/qemu/include/qemu/timer.h:569
#5 0x558ba96da716 in s390_cpu_initfn 
/mnt/sdb/qemu-new/qemu/target/s390x/cpu.c:285
#6 0x558ba9c969ab in object_init_with_type 
/mnt/sdb/qemu-new/qemu/qom/object.c:372
#7 0x558ba9c9eb5f in object_initialize_with_type 
/mnt/sdb/qemu-new/qemu/qom/object.c:516
#8 0x558ba9c9f053 in object_new_with_type 
/mnt/sdb/qemu-new/qemu/qom/object.c:684
#9 0x558ba967ede6 in s390x_new_cpu 
/mnt/sdb/qemu-new/qemu/hw/s390x/s390-virtio-ccw.c:64
#10 0x558ba99764b3 in hmp_cpu_add 
/mnt/sdb/qemu-new/qemu/hw/core/machine-hmp-cmds.c:57
#11 0x558ba9b1c27f in handle_hmp_command 
/mnt/sdb/qemu-new/qemu/monitor/hmp.c:1082
#12 0x558ba96c1b02 in qmp_human_monitor_command 
/mnt/sdb/qemu-new/qemu/monitor/misc.c:142

Reported-by: Euler Robot 
Signed-off-by: Pan Nengyuan 
Cc: Richard Henderson 
Cc: Cornelia Huck 
---
Changes v2 to v1:
- Similarly to other cleanups, move timer_new into realize, then do
timer_del in unrealize.
---
 target/s390x/cpu.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index cf84d307c6..f18dbc6fe4 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -170,7 +170,12 @@ static void s390_cpu_realizefn(DeviceState *dev, Error 
**errp)
 S390CPUClass *scc = S390_CPU_GET_CLASS(dev);
 #if !defined(CONFIG_USER_ONLY)
 S390CPU *cpu = S390_CPU(dev);
+cpu->env.tod_timer =
+timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
+cpu->env.cpu_timer =
+timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
 #endif
+
 Error *err = NULL;
 
 /* the model has to be realized before qemu_init_vcpu() due to kvm */
@@ -227,6 +232,16 @@ out:
 error_propagate(errp, err);
 }
 
+static void s390_cpu_unrealizefn(DeviceState *dev, Error **errp)
+{
+#if !defined(CONFIG_USER_ONLY)
+S390CPU *cpu = S390_CPU(dev);
+
+timer_del(cpu->env.tod_timer);
+timer_del(cpu->env.cpu_timer);
+#endif
+}
+
 static GuestPanicInformation *s390_cpu_get_crash_info(CPUState *cs)
 {
 GuestPanicInformation *panic_info;
@@ -279,10 +294,6 @@ static void s390_cpu_initfn(Object *obj)
 s390_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL);
 s390_cpu_model_register_props(obj);
 #if !defined(CONFIG_USER_ONLY)
-cpu->env.tod_timer =
-timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
-cpu->env.cpu_timer =
-timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
 s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
 #endif
 }
@@ -294,6 +305,8 @@ static void s390_cpu_finalize(Object *obj)
 
 qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
 g_free(cpu->irqstate);
+timer_free(cpu->env.tod_timer);
+timer_free(cpu->env.cpu_timer);
 #endif
 }
 
@@ -453,6 +466,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
 
 device_class_set_parent_realize(dc, s390_cpu_realizefn,
 >parent_realize);
+dc->unrealize = s390_cpu_unrealizefn;
 device_class_set_props(dc, s390x_cpu_properties);
 dc->user_creatable = true;
 
-- 
2.21.0.windows.1





[PATCH v2 0/2] delay timer_new from init to realize to fix memleaks.

2020-02-16 Thread pannengyuan
From: Pan Nengyuan 

v1:
   - Delay timer_new() from init() to realize() to fix memleaks.
v2:
   - Similarly to other cleanups, move timer_new into realize in 
target/s390x/cpu.c (Suggested by Philippe Mathieu-Daudé).
   - Send these two patches as a series instead of sending each as a single 
patch but with wrong subject in v1.

Pan Nengyuan (2):
  s390x: fix memleaks in cpu_finalize
  hw: move timer_new from init() into realize() to avoid memleaks

 hw/arm/pxa2xx.c| 17 +++--
 hw/arm/spitz.c |  8 +++-
 hw/arm/strongarm.c | 18 --
 hw/misc/mos6522.c  | 14 --
 hw/timer/cadence_ttc.c | 16 +++-
 target/s390x/cpu.c | 22 ++
 6 files changed, 71 insertions(+), 24 deletions(-)

-- 
2.21.0.windows.1





[Bug 1863508] Re: qemu-system-arm stops with SIGSEGV in helper_gvec_eq16

2020-02-16 Thread Richard Henderson
Fix posted:
http://patchwork.ozlabs.org/patch/1238946/

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

Title:
  qemu-system-arm stops with SIGSEGV in helper_gvec_eq16

Status in QEMU:
  In Progress

Bug description:
  Segmentation fault when trying to start FreeBSD-arm system with qemu-
  system-arm (version 4.1.1 on Fedora 31)

  Commandline:
  gdb -q --args /bin/qemu-system-arm \
   -name FreeBSD12,debug-threads=on \
   -m 1536 -machine virt -smp 2 \
   -M virt,highmem=off -serial mon:stdio -monitor telnet::45452,server,nowait \
   -machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2 \
   -overcommit mem-lock=off -no-reboot -device virtio-rng-device \
   -bios u-boot-qemu.bin \
   -drive 
file=FreeBSD-12.1-RELEASE-arm-armv7-CUBIEBOARD2.img,if=none,id=drive0,format=raw
 \
   -device ich9-ahci,id=ahci -device ide-drive,drive=drive0,bus=ahci.0 

  Results:
  
  Mounting local filesystems:.

  Thread 4 "CPU 1/TCG" received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0x7fffcedfe700 (LWP 53608)]
  0x558d9332 in helper_gvec_eq16 (d=0x566748d8, a=0x566748e0, 
b=0x566748d0, desc=0) at 
/usr/src/debug/qemu-4.1.1-1.fc31.x86_64/accel/tcg/tcg-runtime-gvec.c:948
  948 DO_CMP2(16)

  Tested different versions of qemu. qemu-3.0.1 worked, but qemu-3.1.1
  failed with the same error.

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



Re: [PATCH 0/4] tcg: Fix for Bug 1863508

2020-02-16 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200217025957.12031-1-richard.hender...@linaro.org/



Hi,

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

Subject: [PATCH 0/4] tcg: Fix for Bug 1863508
Message-id: 20200217025957.12031-1-richard.hender...@linaro.org
Type: series

=== 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 ===

From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/20200217025957.12031-1-richard.hender...@linaro.org -> 
patchew/20200217025957.12031-1-richard.hender...@linaro.org
Switched to a new branch 'test'
dcde5a4 tcg: Remove tcg-runtime-gvec.c DO_CMP0
d3d7297 tcg: Tidy tcg-runtime-gvec.c DUP*
1903cc8 tcg: Tidy tcg-runtime-gvec.c types
d57f62f tcg: Remove CONFIG_VECTOR16

=== OUTPUT BEGIN ===
1/4 Checking commit d57f62f5c6d4 (tcg: Remove CONFIG_VECTOR16)
2/4 Checking commit 1903cc856b87 (tcg: Tidy tcg-runtime-gvec.c types)
ERROR: spaces required around that '&' (ctx:WxO)
#441: FILE: accel/tcg/tcg-runtime-gvec.c:510:
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) &~ *(uint64_t *)(b + i);
 ^

ERROR: space prohibited after that '~' (ctx:OxW)
#441: FILE: accel/tcg/tcg-runtime-gvec.c:510:
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) &~ *(uint64_t *)(b + i);
  ^

ERROR: spaces required around that '|' (ctx:WxO)
#452: FILE: accel/tcg/tcg-runtime-gvec.c:521:
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) |~ *(uint64_t *)(b + i);
 ^

ERROR: space prohibited after that '~' (ctx:OxW)
#452: FILE: accel/tcg/tcg-runtime-gvec.c:521:
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) |~ *(uint64_t *)(b + i);
  ^

ERROR: spaces required around that '==' (ctx:WxB)
#676: FILE: accel/tcg/tcg-runtime-gvec.c:897:
+DO_CMP1(gvec_eq##SZ, uint##SZ##_t, ==)\
^

ERROR: spaces required around that '!=' (ctx:WxB)
#677: FILE: accel/tcg/tcg-runtime-gvec.c:898:
+DO_CMP1(gvec_ne##SZ, uint##SZ##_t, !=)\
^

ERROR: spaces required around that '<' (ctx:WxB)
#678: FILE: accel/tcg/tcg-runtime-gvec.c:899:
+DO_CMP1(gvec_lt##SZ, int##SZ##_t, <)  \
   ^

ERROR: spaces required around that '<=' (ctx:WxB)
#679: FILE: accel/tcg/tcg-runtime-gvec.c:900:
+DO_CMP1(gvec_le##SZ, int##SZ##_t, <=) \
   ^

ERROR: spaces required around that '<' (ctx:WxB)
#680: FILE: accel/tcg/tcg-runtime-gvec.c:901:
+DO_CMP1(gvec_ltu##SZ, uint##SZ##_t, <)\
 ^

ERROR: spaces required around that '<=' (ctx:WxB)
#681: FILE: accel/tcg/tcg-runtime-gvec.c:902:
+DO_CMP1(gvec_leu##SZ, uint##SZ##_t, <=)
 ^

total: 10 errors, 0 warnings, 630 lines checked

Patch 2/4 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

3/4 Checking commit d3d7297cffc8 (tcg: Tidy tcg-runtime-gvec.c DUP*)
4/4 Checking commit dcde5a461a28 (tcg: Remove tcg-runtime-gvec.c DO_CMP0)
ERROR: spaces required around that '*' (ctx:WxV)
#30: FILE: accel/tcg/tcg-runtime-gvec.c:869:
+*(TYPE *)(d + i) = -(*(TYPE *)(a + i) OP *(TYPE *)(b + i));\
  ^

total: 1 errors, 0 warnings, 23 lines checked

Patch 4/4 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20200217025957.12031-1-richard.hender...@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[PATCH 3/4] tcg: Tidy tcg-runtime-gvec.c DUP*

2020-02-16 Thread Richard Henderson
Partial cleanup from the CONFIG_VECTOR16 removal.
Replace the DUP* expansions with the scalar argument.

Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-runtime-gvec.c | 50 +++-
 1 file changed, 15 insertions(+), 35 deletions(-)

diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index 97852b515b..f2199f14b4 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -24,11 +24,6 @@
 #include "tcg/tcg-gvec-desc.h"
 
 
-#define DUP16(X)  X
-#define DUP8(X)   X
-#define DUP4(X)   X
-#define DUP2(X)   X
-
 static inline void clear_high(void *d, intptr_t oprsz, uint32_t desc)
 {
 intptr_t maxsz = simd_maxsz(desc);
@@ -88,11 +83,10 @@ void HELPER(gvec_add64)(void *d, void *a, void *b, uint32_t 
desc)
 void HELPER(gvec_adds8)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint8_t vecb = (uint8_t)DUP16(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
-*(uint8_t *)(d + i) = *(uint8_t *)(a + i) + vecb;
+*(uint8_t *)(d + i) = *(uint8_t *)(a + i) + (uint8_t)b;
 }
 clear_high(d, oprsz, desc);
 }
@@ -100,11 +94,10 @@ void HELPER(gvec_adds8)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_adds16)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint16_t vecb = (uint16_t)DUP8(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
-*(uint16_t *)(d + i) = *(uint16_t *)(a + i) + vecb;
+*(uint16_t *)(d + i) = *(uint16_t *)(a + i) + (uint16_t)b;
 }
 clear_high(d, oprsz, desc);
 }
@@ -112,11 +105,10 @@ void HELPER(gvec_adds16)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_adds32)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint32_t vecb = (uint32_t)DUP4(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
-*(uint32_t *)(d + i) = *(uint32_t *)(a + i) + vecb;
+*(uint32_t *)(d + i) = *(uint32_t *)(a + i) + (uint32_t)b;
 }
 clear_high(d, oprsz, desc);
 }
@@ -124,11 +116,10 @@ void HELPER(gvec_adds32)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_adds64)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint64_t vecb = (uint64_t)DUP2(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
-*(uint64_t *)(d + i) = *(uint64_t *)(a + i) + vecb;
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) + b;
 }
 clear_high(d, oprsz, desc);
 }
@@ -180,11 +171,10 @@ void HELPER(gvec_sub64)(void *d, void *a, void *b, 
uint32_t desc)
 void HELPER(gvec_subs8)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint8_t vecb = (uint8_t)DUP16(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
-*(uint8_t *)(d + i) = *(uint8_t *)(a + i) - vecb;
+*(uint8_t *)(d + i) = *(uint8_t *)(a + i) - (uint8_t)b;
 }
 clear_high(d, oprsz, desc);
 }
@@ -192,11 +182,10 @@ void HELPER(gvec_subs8)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_subs16)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint16_t vecb = (uint16_t)DUP8(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
-*(uint16_t *)(d + i) = *(uint16_t *)(a + i) - vecb;
+*(uint16_t *)(d + i) = *(uint16_t *)(a + i) - (uint16_t)b;
 }
 clear_high(d, oprsz, desc);
 }
@@ -204,11 +193,10 @@ void HELPER(gvec_subs16)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_subs32)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint32_t vecb = (uint32_t)DUP4(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
-*(uint32_t *)(d + i) = *(uint32_t *)(a + i) - vecb;
+*(uint32_t *)(d + i) = *(uint32_t *)(a + i) - (uint32_t)b;
 }
 clear_high(d, oprsz, desc);
 }
@@ -216,11 +204,10 @@ void HELPER(gvec_subs32)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_subs64)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint64_t vecb = (uint64_t)DUP2(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
-*(uint64_t *)(d + i) = *(uint64_t *)(a + i) - vecb;
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) - b;
 }
 clear_high(d, oprsz, desc);
 }
@@ -272,11 +259,10 @@ void HELPER(gvec_mul64)(void *d, void *a, void *b, 
uint32_t desc)
 void HELPER(gvec_muls8)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-uint8_t vecb = (uint8_t)DUP16(b);
 intptr_t i;
 
 for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
-*(uint8_t *)(d + i) = *(uint8_t *)(a + i) * vecb;
+*(uint8_t *)(d + i) = *(uint8_t *)(a + 

[PATCH 2/4] tcg: Tidy tcg-runtime-gvec.c types

2020-02-16 Thread Richard Henderson
Partial cleanup from the CONFIG_VECTOR16 removal.
Replace the vec* types with their scalar expansions.

Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-runtime-gvec.c | 270 +--
 1 file changed, 130 insertions(+), 140 deletions(-)

diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index 00da0938a5..97852b515b 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -24,16 +24,6 @@
 #include "tcg/tcg-gvec-desc.h"
 
 
-typedef uint8_t vec8;
-typedef uint16_t vec16;
-typedef uint32_t vec32;
-typedef uint64_t vec64;
-
-typedef int8_t svec8;
-typedef int16_t svec16;
-typedef int32_t svec32;
-typedef int64_t svec64;
-
 #define DUP16(X)  X
 #define DUP8(X)   X
 #define DUP4(X)   X
@@ -56,8 +46,8 @@ void HELPER(gvec_add8)(void *d, void *a, void *b, uint32_t 
desc)
 intptr_t oprsz = simd_oprsz(desc);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec8)) {
-*(vec8 *)(d + i) = *(vec8 *)(a + i) + *(vec8 *)(b + i);
+for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
+*(uint8_t *)(d + i) = *(uint8_t *)(a + i) + *(uint8_t *)(b + i);
 }
 clear_high(d, oprsz, desc);
 }
@@ -67,8 +57,8 @@ void HELPER(gvec_add16)(void *d, void *a, void *b, uint32_t 
desc)
 intptr_t oprsz = simd_oprsz(desc);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec16)) {
-*(vec16 *)(d + i) = *(vec16 *)(a + i) + *(vec16 *)(b + i);
+for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
+*(uint16_t *)(d + i) = *(uint16_t *)(a + i) + *(uint16_t *)(b + i);
 }
 clear_high(d, oprsz, desc);
 }
@@ -78,8 +68,8 @@ void HELPER(gvec_add32)(void *d, void *a, void *b, uint32_t 
desc)
 intptr_t oprsz = simd_oprsz(desc);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec32)) {
-*(vec32 *)(d + i) = *(vec32 *)(a + i) + *(vec32 *)(b + i);
+for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
+*(uint32_t *)(d + i) = *(uint32_t *)(a + i) + *(uint32_t *)(b + i);
 }
 clear_high(d, oprsz, desc);
 }
@@ -89,8 +79,8 @@ void HELPER(gvec_add64)(void *d, void *a, void *b, uint32_t 
desc)
 intptr_t oprsz = simd_oprsz(desc);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec64)) {
-*(vec64 *)(d + i) = *(vec64 *)(a + i) + *(vec64 *)(b + i);
+for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) + *(uint64_t *)(b + i);
 }
 clear_high(d, oprsz, desc);
 }
@@ -98,11 +88,11 @@ void HELPER(gvec_add64)(void *d, void *a, void *b, uint32_t 
desc)
 void HELPER(gvec_adds8)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-vec8 vecb = (vec8)DUP16(b);
+uint8_t vecb = (uint8_t)DUP16(b);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec8)) {
-*(vec8 *)(d + i) = *(vec8 *)(a + i) + vecb;
+for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
+*(uint8_t *)(d + i) = *(uint8_t *)(a + i) + vecb;
 }
 clear_high(d, oprsz, desc);
 }
@@ -110,11 +100,11 @@ void HELPER(gvec_adds8)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_adds16)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-vec16 vecb = (vec16)DUP8(b);
+uint16_t vecb = (uint16_t)DUP8(b);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec16)) {
-*(vec16 *)(d + i) = *(vec16 *)(a + i) + vecb;
+for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
+*(uint16_t *)(d + i) = *(uint16_t *)(a + i) + vecb;
 }
 clear_high(d, oprsz, desc);
 }
@@ -122,11 +112,11 @@ void HELPER(gvec_adds16)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_adds32)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-vec32 vecb = (vec32)DUP4(b);
+uint32_t vecb = (uint32_t)DUP4(b);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec32)) {
-*(vec32 *)(d + i) = *(vec32 *)(a + i) + vecb;
+for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
+*(uint32_t *)(d + i) = *(uint32_t *)(a + i) + vecb;
 }
 clear_high(d, oprsz, desc);
 }
@@ -134,11 +124,11 @@ void HELPER(gvec_adds32)(void *d, void *a, uint64_t b, 
uint32_t desc)
 void HELPER(gvec_adds64)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
-vec64 vecb = (vec64)DUP2(b);
+uint64_t vecb = (uint64_t)DUP2(b);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec64)) {
-*(vec64 *)(d + i) = *(vec64 *)(a + i) + vecb;
+for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) + vecb;
 }
 clear_high(d, oprsz, desc);
 }
@@ -148,8 +138,8 @@ void HELPER(gvec_sub8)(void *d, void *a, void *b, uint32_t 
desc)
 intptr_t oprsz = simd_oprsz(desc);
 intptr_t i;
 
-for (i = 0; i < oprsz; i += sizeof(vec8)) {
-*(vec8 *)(d + i) = *(vec8 *)(a + i) - *(vec8 *)(b + i);
+for (i 

[PATCH 1/4] tcg: Remove CONFIG_VECTOR16

2020-02-16 Thread Richard Henderson
The comment in tcg-runtime-gvec.c about CONFIG_VECTOR16 says that
tcg-op-gvec.c has eliminated size 8 vectors, and only passes on
multiples of 16.  This may have been true of the first few operations,
but is not true of all operations.

In particular, multiply, shift by scalar, and compare of 8- and 16-bit
elements are not expanded inline if host vector operations are not
supported.

For an x86_64 host that does not support AVX, this means that we will
fall back to the helper, which will attempt to use SSE instructions,
which will SEGV on an invalid 8-byte aligned memory operation.

This patch simply removes the CONFIG_VECTOR16 code and configuration
without further simplification.

Buglink: https://bugs.launchpad.net/bugs/1863508
Signed-off-by: Richard Henderson 
---
 configure| 56 
 accel/tcg/tcg-runtime-gvec.c | 35 +-
 2 files changed, 1 insertion(+), 90 deletions(-)

diff --git a/configure b/configure
index 16f94cd96b..bccb979aaf 100755
--- a/configure
+++ b/configure
@@ -5618,58 +5618,6 @@ if  test "$plugins" = "yes" &&
   "for this purpose. You can't build with --static."
 fi
 
-
-# See if 16-byte vector operations are supported.
-# Even without a vector unit the compiler may expand these.
-# There is a bug in old GCC for PPC that crashes here.
-# Unfortunately it's the system compiler for Centos 7.
-
-cat > $TMPC << EOF
-typedef unsigned char U1 __attribute__((vector_size(16)));
-typedef unsigned short U2 __attribute__((vector_size(16)));
-typedef unsigned int U4 __attribute__((vector_size(16)));
-typedef unsigned long long U8 __attribute__((vector_size(16)));
-typedef signed char S1 __attribute__((vector_size(16)));
-typedef signed short S2 __attribute__((vector_size(16)));
-typedef signed int S4 __attribute__((vector_size(16)));
-typedef signed long long S8 __attribute__((vector_size(16)));
-static U1 a1, b1;
-static U2 a2, b2;
-static U4 a4, b4;
-static U8 a8, b8;
-static S1 c1;
-static S2 c2;
-static S4 c4;
-static S8 c8;
-static int i;
-void helper(void *d, void *a, int shift, int i);
-void helper(void *d, void *a, int shift, int i)
-{
-  *(U1 *)(d + i) = *(U1 *)(a + i) << shift;
-  *(U2 *)(d + i) = *(U2 *)(a + i) << shift;
-  *(U4 *)(d + i) = *(U4 *)(a + i) << shift;
-  *(U8 *)(d + i) = *(U8 *)(a + i) << shift;
-}
-int main(void)
-{
-  a1 += b1; a2 += b2; a4 += b4; a8 += b8;
-  a1 -= b1; a2 -= b2; a4 -= b4; a8 -= b8;
-  a1 *= b1; a2 *= b2; a4 *= b4; a8 *= b8;
-  a1 &= b1; a2 &= b2; a4 &= b4; a8 &= b8;
-  a1 |= b1; a2 |= b2; a4 |= b4; a8 |= b8;
-  a1 ^= b1; a2 ^= b2; a4 ^= b4; a8 ^= b8;
-  a1 <<= i; a2 <<= i; a4 <<= i; a8 <<= i;
-  a1 >>= i; a2 >>= i; a4 >>= i; a8 >>= i;
-  c1 >>= i; c2 >>= i; c4 >>= i; c8 >>= i;
-  return 0;
-}
-EOF
-
-vector16=no
-if compile_prog "" "" ; then
-  vector16=yes
-fi
-
 
 # See if __attribute__((alias)) is supported.
 # This false for Xcode 9, but has been remedied for Xcode 10.
@@ -7266,10 +7214,6 @@ if test "$atomic64" = "yes" ; then
   echo "CONFIG_ATOMIC64=y" >> $config_host_mak
 fi
 
-if test "$vector16" = "yes" ; then
-  echo "CONFIG_VECTOR16=y" >> $config_host_mak
-fi
-
 if test "$attralias" = "yes" ; then
   echo "CONFIG_ATTRIBUTE_ALIAS=y" >> $config_host_mak
 fi
diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index 5b1902d591..00da0938a5 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -24,32 +24,6 @@
 #include "tcg/tcg-gvec-desc.h"
 
 
-/* Virtually all hosts support 16-byte vectors.  Those that don't can emulate
- * them via GCC's generic vector extension.  This turns out to be simpler and
- * more reliable than getting the compiler to autovectorize.
- *
- * In tcg-op-gvec.c, we asserted that both the size and alignment of the data
- * are multiples of 16.
- *
- * When the compiler does not support all of the operations we require, the
- * loops are written so that we can always fall back on the base types.
- */
-#ifdef CONFIG_VECTOR16
-typedef uint8_t vec8 __attribute__((vector_size(16)));
-typedef uint16_t vec16 __attribute__((vector_size(16)));
-typedef uint32_t vec32 __attribute__((vector_size(16)));
-typedef uint64_t vec64 __attribute__((vector_size(16)));
-
-typedef int8_t svec8 __attribute__((vector_size(16)));
-typedef int16_t svec16 __attribute__((vector_size(16)));
-typedef int32_t svec32 __attribute__((vector_size(16)));
-typedef int64_t svec64 __attribute__((vector_size(16)));
-
-#define DUP16(X)  { X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X }
-#define DUP8(X)   { X, X, X, X, X, X, X, X }
-#define DUP4(X)   { X, X, X, X }
-#define DUP2(X)   { X, X }
-#else
 typedef uint8_t vec8;
 typedef uint16_t vec16;
 typedef uint32_t vec32;
@@ -64,7 +38,6 @@ typedef int64_t svec64;
 #define DUP8(X)   X
 #define DUP4(X)   X
 #define DUP2(X)   X
-#endif /* CONFIG_VECTOR16 */
 
 static inline void clear_high(void *d, intptr_t oprsz, 

[PATCH 0/4] tcg: Fix for Bug 1863508

2020-02-16 Thread Richard Henderson
The comment in tcg-runtime-gvec.c about CONFIG_VECTOR16 says that
tcg-op-gvec.c has eliminated size 8 vectors, and only passes on
multiples of 16.  This may have been true of the first few operations,
but is not true of all operations.

In particular, multiply, shift by scalar, and compare of 8- and 16-bit
elements are not expanded inline if host vector operations are not
supported.

For an x86_64 host that does not support AVX, this means that we will
fall back to the helper, which will attempt to use SSE instructions,
which will SEGV on an invalid 8-byte aligned memory operation.

The first patch removes the CONFIG_VECTOR16 code and configuration;
the subsequent patches tidy up tcg-runtime-gvec.c.


r~


Richard Henderson (4):
  tcg: Remove CONFIG_VECTOR16
  tcg: Tidy tcg-runtime-gvec.c types
  tcg: Tidy tcg-runtime-gvec.c DUP*
  tcg: Remove tcg-runtime-gvec.c DO_CMP0

 configure|  56 ---
 accel/tcg/tcg-runtime-gvec.c | 298 ++-
 2 files changed, 116 insertions(+), 238 deletions(-)

-- 
2.20.1




[PATCH 4/4] tcg: Remove tcg-runtime-gvec.c DO_CMP0

2020-02-16 Thread Richard Henderson
Partial cleanup from the CONFIG_VECTOR16 removal.
Replace DO_CMP0 with its scalar expansion, a simple negation.

Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-runtime-gvec.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index f2199f14b4..ca449702e6 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -860,15 +860,13 @@ void HELPER(gvec_sar64v)(void *d, void *a, void *b, 
uint32_t desc)
 clear_high(d, oprsz, desc);
 }
 
-#define DO_CMP0(X)  -(X)
-
 #define DO_CMP1(NAME, TYPE, OP)\
 void HELPER(NAME)(void *d, void *a, void *b, uint32_t desc)\
 {  \
 intptr_t oprsz = simd_oprsz(desc); \
 intptr_t i;\
 for (i = 0; i < oprsz; i += sizeof(TYPE)) {\
-*(TYPE *)(d + i) = DO_CMP0(*(TYPE *)(a + i) OP *(TYPE *)(b + i));  \
+*(TYPE *)(d + i) = -(*(TYPE *)(a + i) OP *(TYPE *)(b + i));\
 }  \
 clear_high(d, oprsz, desc);\
 }
@@ -886,7 +884,6 @@ DO_CMP2(16)
 DO_CMP2(32)
 DO_CMP2(64)
 
-#undef DO_CMP0
 #undef DO_CMP1
 #undef DO_CMP2
 
-- 
2.20.1




Re: [PATCH v3 1/2] target/arm: Support SError injection

2020-02-16 Thread Gavin Shan

Hi Marc,

On 2/16/20 11:34 PM, Marc Zyngier wrote:

On 2020-02-14 05:59, Gavin Shan wrote:

This supports SError injection, which will be used by "virt" board to
simulating the behavior of NMI injection in next patch. As Peter Maydell
suggested, this adds a new interrupt (ARM_CPU_SERROR), which is parallel
to CPU_INTERRUPT_HARD. The backend depends on if kvm is enabled or not.
kvm_vcpu_ioctl(cpu, KVM_SET_VCPU_EVENTS) is leveraged to inject SError
or data abort to guest. When TCG is enabled, the behavior is simulated
by injecting SError and data abort to guest.

Signed-off-by: Gavin Shan 
---
 target/arm/cpu.c  | 69 +++
 target/arm/cpu.h  | 17 ++-
 target/arm/helper.c   |  6 
 target/arm/m_helper.c |  8 +
 4 files changed, 81 insertions(+), 19 deletions(-)



[...]


@@ -656,7 +682,8 @@ static void arm_cpu_set_irq(void *opaque, int irq,
int level)
 [ARM_CPU_IRQ] = CPU_INTERRUPT_HARD,
 [ARM_CPU_FIQ] = CPU_INTERRUPT_FIQ,
 [ARM_CPU_VIRQ] = CPU_INTERRUPT_VIRQ,
-    [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ
+    [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ,
+    [ARM_CPU_SERROR] = CPU_INTERRUPT_SERROR,


I'm a bit concerned with this. It makes sense for a host, but doesn't
allow the SError signal to be virtualised (there should be a VSError
signal in this list that can be injected via HCR_EL2.VA, just like
VIRQ is injected by HCR_EL2.VI).

Given that people use QEMU as a development platform for hypervisors,
I'd really like this functionality to be supported from day-1.

There is also the whole RAS stuff which quite a lot of work, but let's
start at least with the full ARMv8.0 semantics.



Thanks for the comments. Yes, I think it's reasonable to support virtual
SError as well. Lets have a separate patch to support it in v4. I think
you were talking about HCR_EL2.VSE, which is defined as below in 
target/arm/cpu.h:

#define HCR_VSE   (1ULL << 8)

Thanks,
Gavin




[RFC PATCH 2/2] target/ppc: Enable hardfloat for PPC

2020-02-16 Thread BALATON Zoltan
While other targets take advantage of using host FPU to do floating
point computations, this was disabled for PPC target because always
clearing exception flags before every FP op made it slightly slower
than emulating everyting with softfloat. To emulate some FPSCR bits,
clearing of fp_status may be necessary (unless these could be handled
e.g. using FP exceptions on host but there's no API for that in QEMU
yet) but preserving at least the inexact flag makes hardfloat usable
and faster than softfloat. Since most clients don't actually care
about this flag, we can gain some speed trading some emulation
accuracy.

This patch implements a simple way to keep the inexact flag set for
hardfloat while still allowing to revert to softfloat for workloads
that need more accurate albeit slower emulation. (Set hardfloat
property of CPU, i.e. -cpu name,hardfloat=false for that.) There are
still more places where flags are reset so there is place for further
improvement. Also having a conditional to test for the hardfloat flag
every time makes the softfloat case slower than before this patch so
some other way (like setting a function pointer once and use that
instead if possible) may be needed to avoid this otherwise this patch
only makes sense if the default is also set to enable hardfloat.

Because of the above this patch at the moment is mainly for testing
different workloads to evaluate how viable would this be in practice.
Thus, RFC and not ready for merge yet.

Signed-off-by: BALATON Zoltan 
---
 fpu/softfloat.c | 14 +++---
 target/ppc/fpu_helper.c |  7 ++-
 target/ppc/translate_init.inc.c |  2 +-
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 301ce3b537..6d3f4af72a 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -216,15 +216,15 @@ GEN_INPUT_FLUSH3(float64_input_flush3, float64)
 #endif
 
 /*
- * Some targets clear the FP flags before most FP operations. This prevents
- * the use of hardfloat, since hardfloat relies on the inexact flag being
- * already set.
+ * Disable hardfloat for known problem cases.
+ * Additionally, some targets clear the FP flags before most FP operations.
+ * This prevents the use of hardfloat, since it relies on the inexact flag
+ * being already set and clearing it often may result in slower computations.
+ * Those targets could also be listed here.
  */
-#if defined(TARGET_PPC) || defined(__FAST_MATH__)
-# if defined(__FAST_MATH__)
-#  warning disabling hardfloat due to -ffast-math: hardfloat requires an exact 
\
+#if defined(__FAST_MATH__)
+# warning disabling hardfloat due to -ffast-math: hardfloat requires an exact \
 IEEE implementation
-# endif
 # define QEMU_NO_HARDFLOAT 1
 # define QEMU_SOFTFLOAT_ATTR QEMU_FLATTEN
 #else
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index ae43b08eb5..33aa977970 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -659,7 +659,12 @@ void helper_float_check_status(CPUPPCState *env)
 
 void helper_reset_fpstatus(CPUPPCState *env)
 {
-set_float_exception_flags(0, >fp_status);
+if (env->hardfloat) {
+/* hardfloat needs inexact flag already set, clear only others */
+set_float_exception_flags(float_flag_inexact, >fp_status);
+} else {
+set_float_exception_flags(0, >fp_status);
+}
 }
 
 static void float_invalid_op_addsub(CPUPPCState *env, bool set_fpcc,
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index d6e1d66bc8..caac0c2d11 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10869,7 +10869,7 @@ static Property ppc_cpu_properties[] = {
  false),
 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
  false),
-DEFINE_PROP_BOOL("hardfloat", PowerPCCPU, hardfloat, false),
+DEFINE_PROP_BOOL("hardfloat", PowerPCCPU, hardfloat, true),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.21.1




[RFC PATCH 1/2] target/ppc/cpu: Add hardfloat property

2020-02-16 Thread BALATON Zoltan
Add a property to allow setting a flag in cpu env that will be used to
control if hardfloat is used for floating point ops (i.e. speed is
preferred over accuracy).

Signed-off-by: BALATON Zoltan 
---
 target/ppc/cpu.h| 2 ++
 target/ppc/translate_init.inc.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index b283042515..1b258a5db5 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1033,6 +1033,7 @@ struct CPUPPCState {
 float_status vec_status;
 float_status fp_status; /* Floating point execution context */
 target_ulong fpscr; /* Floating point status and control register */
+bool hardfloat; /* use hardfloat (this breaks FPSCR[FI] bit) */
 
 /* Internal devices resources */
 ppc_tb_t *tb_env;  /* Time base and decrementer */
@@ -1163,6 +1164,7 @@ struct PowerPCCPU {
 void *machine_data;
 int32_t node_id; /* NUMA node this CPU belongs to */
 PPCHash64Options *hash64_opts;
+bool hardfloat; /* pass on property to env */
 
 /* Those resources are used only during code translation */
 /* opcode handlers */
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 53995f62ea..d6e1d66bc8 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10736,6 +10736,7 @@ static void ppc_cpu_reset(CPUState *s)
 /* tininess for underflow is detected before rounding */
 set_float_detect_tininess(float_tininess_before_rounding,
   >fp_status);
+env->hardfloat = cpu->hardfloat;
 
 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
 ppc_spr_t *spr = >spr_cb[i];
@@ -10868,6 +10869,7 @@ static Property ppc_cpu_properties[] = {
  false),
 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
  false),
+DEFINE_PROP_BOOL("hardfloat", PowerPCCPU, hardfloat, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.21.1




[RFC PATCH 0/2] Enable hardfloat for PPC

2020-02-16 Thread BALATON Zoltan
Hello,

This is an RFC series to start exploring the possibility of enabling
hardfloat for PPC target that haven't progressed in the last two years.
Hopefully we can work out something now. Previously I've explored this
here:

https://lists.nongnu.org/archive/html/qemu-ppc/2018-07/msg00261.html

where some ad-hoc benchmarks using lame mp3 encoder is also explained
that has two versions: one using VMX and another only using FP. Both
are mostly floating point bounded. I've run this test on mac99 under
MorphOS before and after my patches, also verifying that md5sum of
resulting mp3 matches (this is no proof for correctness but maybe
shows it did not break too much at least those ops used by this
program).

I've got these measurements on an Intel i7-9700K CPU @ 3.60GHz (did
not bother to take multiple samples so these are just approximate):

1) before patch series using softfloat:
lame: 4:01, lame_vmx: 3:14

2) only enabling hardfloat in fpu/softfloat.c without other changes:
lame: 4:06, lame_vmx: 2:06
(this shows why hardfloat was disabled but VMX can benefit from this)

3) with this series, hardfloat=true:
lame: 3:15, lame_vmx: 1:59
(so the patch does something even if there should be more places to
preserve inexact flag to fully use hardfloat)

4) with this series but forcing softfloat with hardfloat=false:
lame: 4:11, lame_vmx: 2:08
(unfortunately it's slower than before, likely due to adding if () to
helper_reset_fpstatus() that should be avoided to at least get back
previous hardfloat enabled case that's still slower than softfloat so
this series only makes sense if the default can be hardfloat=true at
the moment but even that would need more testing)

I hope others can contribute to this by doing more testing to find out
what else this would break or give some ideas how this could be
improved.

Regards,
BALATON Zoltan

BALATON Zoltan (2):
  target/ppc/cpu: Add hardfloat property
  target/ppc: Enable hardfloat for PPC

 fpu/softfloat.c | 14 +++---
 target/ppc/cpu.h|  2 ++
 target/ppc/fpu_helper.c |  7 ++-
 target/ppc/translate_init.inc.c |  2 ++
 4 files changed, 17 insertions(+), 8 deletions(-)

-- 
2.21.1




Re: [PULL SUBSYSTEM qemu-pseries] pseries: Update SLOF firmware image

2020-02-16 Thread David Gibson
On Mon, Feb 17, 2020 at 01:12:17PM +1100, Alexey Kardashevskiy wrote:
> The following changes since commit 05943fb4ca41f626078014c0327781815c6584c5:
> 
>   ppc: free 'fdt' after reset the machine (2020-02-17 11:27:23 +1100)
> 
> are available in the Git repository at:
> 
>   g...@github.com:aik/qemu.git tags/qemu-slof-20200217
> 
> for you to fetch changes up to ea9a03e5aa023c5391bab5259898475d0298aac2:
> 
>   pseries: Update SLOF firmware image (2020-02-17 13:08:59 +1100)
> 
> 
> Alexey Kardashevskiy (1):
>   pseries: Update SLOF firmware image
> 
>  pc-bios/README   |   2 +-
>  pc-bios/slof.bin | Bin 931032 -> 968560 bytes
>  roms/SLOF|   2 +-
>  3 files changed, 2 insertions(+), 2 deletions(-)
> 
> 
> *** Note: this is not for master, this is for pseries

Merged to ppc-for-5.0, thanks.

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


signature.asc
Description: PGP signature


[PULL SUBSYSTEM qemu-pseries] pseries: Update SLOF firmware image

2020-02-16 Thread Alexey Kardashevskiy
The following changes since commit 05943fb4ca41f626078014c0327781815c6584c5:

  ppc: free 'fdt' after reset the machine (2020-02-17 11:27:23 +1100)

are available in the Git repository at:

  g...@github.com:aik/qemu.git tags/qemu-slof-20200217

for you to fetch changes up to ea9a03e5aa023c5391bab5259898475d0298aac2:

  pseries: Update SLOF firmware image (2020-02-17 13:08:59 +1100)


Alexey Kardashevskiy (1):
  pseries: Update SLOF firmware image

 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 931032 -> 968560 bytes
 roms/SLOF|   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)


*** Note: this is not for master, this is for pseries



Re: [PATCH RESEND v23 00/10] Add ARMv8 RAS virtualization support in QEMU

2020-02-16 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200217012737.30231-1-gengdong...@huawei.com/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#! /bin/bash
export ARCH=x86_64
make docker-image-fedora V=1 NETWORK=1
time make docker-test-mingw@fedora J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  hw/audio/sb16.o
In file included from /tmp/qemu-test/src/hw/acpi/ghes.c:29:
/tmp/qemu-test/src/hw/acpi/ghes.c: In function 'acpi_ghes_record_mem_error':
/tmp/qemu-test/src/include/qemu/uuid.h:38:3: error: missing braces around 
initializer [-Werror=missing-braces]
   { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
   ^
/tmp/qemu-test/src/hw/acpi/ghes.c:60:5: note: in expansion of macro 'UUID_LE'
---
 QemuUUID mem_section_id_le = UEFI_CPER_SEC_PLATFORM_MEM;
  ^~
cc1: all warnings being treated as errors
make: *** [/tmp/qemu-test/src/rules.mak:69: hw/acpi/ghes.o] Error 1
make: *** Waiting for unfinished jobs
  CC  hw/audio/es1370.o
Traceback (most recent call last):
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=9a76402463c345328be56ae4097cee3b', '-u', 
'1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-lfhq_j5a/src/docker-src.2020-02-16-20.55.36.13397:/var/tmp/qemu:z,ro',
 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=9a76402463c345328be56ae4097cee3b
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-lfhq_j5a/src'
make: *** [docker-run-test-mingw@fedora] Error 2

real2m35.466s
user0m8.231s


The full log is available at
http://patchew.org/logs/20200217012737.30231-1-gengdong...@huawei.com/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: BIOS updates

2020-02-16 Thread Alexey Kardashevskiy



On 17/02/2020 12:27, Alexey Kardashevskiy wrote:
> Hi!
> 
> We have a SLOF repo mirrored at git.qemu.org. Once I push an update to
> my github repo, it gets mirrored soon, it works fine.
> 
> Now to the problems :)
> 
> 1. by accident I pushed a branch with a lot of debug stuff on top. When
> I noticed, I force-pushed the correct one but it was too late - the
> incorrect branch got mirrored. Is there a way to fix this on
> https://git.qemu.org/git/SLOF.git? This is the correct one:
> 
> 42228d763f1f (tag: qemu-slof-20200217, github/master) version: update to
> 20200217
> 
> https://github.com/aik/SLOF/commits/qemu-slof-20200217

Huh, this one got resolved, was it a script or a person? :)


> 
> 2. it appears that the mirroring scripts pulls all branches from my
> github repo, can we please configure that mirroring script only to pull
> "master"?

I removed extra branches from my git repo and this got mirrored to
git.qemu.org so things are clean now but the question remains whether we
want anything but "master" mirrored.



-- 
Alexey



BIOS updates

2020-02-16 Thread Alexey Kardashevskiy
Hi!

We have a SLOF repo mirrored at git.qemu.org. Once I push an update to
my github repo, it gets mirrored soon, it works fine.

Now to the problems :)

1. by accident I pushed a branch with a lot of debug stuff on top. When
I noticed, I force-pushed the correct one but it was too late - the
incorrect branch got mirrored. Is there a way to fix this on
https://git.qemu.org/git/SLOF.git? This is the correct one:

42228d763f1f (tag: qemu-slof-20200217, github/master) version: update to
20200217

https://github.com/aik/SLOF/commits/qemu-slof-20200217


2. it appears that the mirroring scripts pulls all branches from my
github repo, can we please configure that mirroring script only to pull
"master"?

Thanks,


-- 
Alexey



RE: The issues about architecture of the COLO checkpoint

2020-02-16 Thread Zhanghailiang
Hi Daniel,

I have rebased these patches with newest upstream version, this series 
“Optimize VM's downtime while do checkpoint in COLO”,
It is not been tested, please let me known if there are any problems.

Thanks,
Hailiang

From: Daniel Cho [mailto:daniel...@qnap.com]
Sent: Saturday, February 15, 2020 11:36 AM
To: Dr. David Alan Gilbert 
Cc: Zhang, Chen ; Zhanghailiang 
; qemu-devel@nongnu.org; Jason Wang 

Subject: Re: The issues about architecture of the COLO checkpoint

Hi Dave,

Yes, I agree with you, it does need a timeout.

Hi Hailiang,

We base on qemu-4.1.0 for using COLO feature, in your patch, we found a lot of 
difference  between your version and ours.
Could you give us a latest release version which is close your developing code?

Thanks.

Regards
Daniel Cho

Dr. David Alan Gilbert mailto:dgilb...@redhat.com>> 於 
2020年2月13日 週四 下午6:38寫道:
* Daniel Cho (daniel...@qnap.com) wrote:
> Hi Hailiang,
>
> 1.
> OK, we will try the patch
> “0001-COLO-Optimize-memory-back-up-process.patch”,
> and thanks for your help.
>
> 2.
> We understand the reason to compare PVM and SVM's packet. However, the
> empty of SVM's packet queue might happened on setting COLO feature and SVM
> broken.
>
> On situation 1 ( setting COLO feature ):
> We could force do checkpoint after setting COLO feature finish, then it
> will protect the state of PVM and SVM . As the Zhang Chen said.
>
> On situation 2 ( SVM broken ):
> COLO will do failover for PVM, so it might not cause any wrong on PVM.
>
> However, those situations are our views, so there might be a big difference
> between reality and our views.
> If we have any wrong views and opinions, please let us know, and correct
> us.

It does need a timeout; the SVM being broken or being in a state where
it never sends the corresponding packet (because of a state difference)
can happen and COLO needs to timeout when the packet hasn't arrived
after a while and trigger the checkpoint.

Dave

> Thanks.
>
> Best regards,
> Daniel Cho
>
> Zhang, Chen mailto:chen.zh...@intel.com>> 於 2020年2月13日 
> 週四 上午10:17寫道:
>
> > Add cc Jason Wang, he is a network expert.
> >
> > In case some network things goes wrong.
> >
> >
> >
> > Thanks
> >
> > Zhang Chen
> >
> >
> >
> > *From:* Zhang, Chen
> > *Sent:* Thursday, February 13, 2020 10:10 AM
> > *To:* 'Zhanghailiang' 
> > mailto:zhang.zhanghaili...@huawei.com>>; 
> > Daniel Cho <
> > daniel...@qnap.com>
> > *Cc:* Dr. David Alan Gilbert 
> > mailto:dgilb...@redhat.com>>; 
> > qemu-devel@nongnu.org
> > *Subject:* RE: The issues about architecture of the COLO checkpoint
> >
> >
> >
> > For the issue 2:
> >
> >
> >
> > COLO need use the network packets to confirm PVM and SVM in the same state,
> >
> > Generally speaking, we can’t send PVM packets without compared with SVM
> > packets.
> >
> > But to prevent jamming, I think COLO can do force checkpoint and send the
> > PVM packets in this case.
> >
> >
> >
> > Thanks
> >
> > Zhang Chen
> >
> >
> >
> > *From:* Zhanghailiang 
> > mailto:zhang.zhanghaili...@huawei.com>>
> > *Sent:* Thursday, February 13, 2020 9:45 AM
> > *To:* Daniel Cho mailto:daniel...@qnap.com>>
> > *Cc:* Dr. David Alan Gilbert 
> > mailto:dgilb...@redhat.com>>; 
> > qemu-devel@nongnu.org;
> > Zhang, Chen mailto:chen.zh...@intel.com>>
> > *Subject:* RE: The issues about architecture of the COLO checkpoint
> >
> >
> >
> > Hi,
> >
> >
> >
> > 1.   After re-walked through the codes, yes, you are right, actually,
> > after the first migration, we will keep dirty log on in primary side,
> >
> > And only send the dirty pages in PVM to SVM. The ram cache in secondary
> > side is always a backup of PVM, so we don’t have to
> >
> > Re-send the none-dirtied pages.
> >
> > The reason why the first checkpoint takes longer time is we have to backup
> > the whole VM’s ram into ram cache, that is colo_init_ram_cache().
> >
> > It is time consuming, but I have optimized in the second patch
> > “0001-COLO-Optimize-memory-back-up-process.patch” which you can find in my
> > previous reply.
> >
> >
> >
> > Besides, I found that, In my previous reply “We can only copy the pages
> > that dirtied by PVM and SVM in last checkpoint.”,
> >
> > We have done this optimization in current upstream codes.
> >
> >
> >
> > 2.I don’t quite understand this question. For COLO, we always need both
> > network packets of PVM’s and SVM’s to compare before send this packets to
> > client.
> >
> > It depends on this to decide whether or not PVM and SVM are in same state.
> >
> >
> >
> > Thanks,
> >
> > hailiang
> >
> >
> >
> > *From:* Daniel Cho [mailto:daniel...@qnap.com 
> > mailto:daniel...@qnap.com>>]
> > *Sent:* Wednesday, February 12, 2020 4:37 PM
> > *To:* Zhang, Chen mailto:chen.zh...@intel.com>>
> > *Cc:* Zhanghailiang 
> > mailto:zhang.zhanghaili...@huawei.com>>; 
> > Dr. David Alan
> > Gilbert 

[PATCH RESEND v23 08/10] ACPI: Record Generic Error Status Block(GESB) table

2020-02-16 Thread Dongjiu Geng
kvm_arch_on_sigbus_vcpu() error injection uses source_id as
index in etc/hardware_errors to find out Error Status Data
Block entry corresponding to error source. So supported source_id
values should be assigned here and not be changed afterwards to
make sure that guest will write error into expected Error Status
Data Block.

Before QEMU writes a new error to ACPI table, it will check whether
previous error has been acknowledged. If not acknowledged, the new
errors will be ignored and not be recorded. For the errors section
type, QEMU simulate it to memory section error.

Signed-off-by: Dongjiu Geng 
Signed-off-by: Xiang Zheng 
---
 hw/acpi/ghes.c | 218 +
 include/hw/acpi/ghes.h |   1 +
 2 files changed, 219 insertions(+)

diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index cea2bff..8e114ee 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -26,6 +26,7 @@
 #include "qemu/error-report.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/nvram/fw_cfg.h"
+#include "qemu/uuid.h"
 
 #define ACPI_GHES_ERRORS_FW_CFG_FILE"etc/hardware_errors"
 #define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
@@ -43,6 +44,40 @@
 #define GAS_ADDR_OFFSET 4
 
 /*
+ * The total size of Generic Error Data Entry
+ * ACPI 6.1/6.2: 18.3.2.7.1 Generic Error Data,
+ * Table 18-343 Generic Error Data Entry
+ */
+#define ACPI_GHES_DATA_LENGTH   72
+
+/* The memory section CPER size, UEFI 2.6: N.2.5 Memory Error Section */
+#define ACPI_GHES_MEM_CPER_LENGTH   80
+
+/* Masks for block_status flags */
+#define ACPI_GEBS_UNCORRECTABLE 1
+
+#define UEFI_CPER_SEC_PLATFORM_MEM  \
+UUID_LE(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \
+0xED, 0x7C, 0x83, 0xB1)
+
+/*
+ * Total size for Generic Error Status Block except Generic Error Data Entries
+ * ACPI 6.2: 18.3.2.7.1 Generic Error Data,
+ * Table 18-380 Generic Error Status Block
+ */
+#define ACPI_GHES_GESB_SIZE 20
+
+/*
+ * Values for error_severity field
+ */
+enum AcpiGenericErrorSeverity {
+ACPI_CPER_SEV_RECOVERABLE = 0,
+ACPI_CPER_SEV_FATAL = 1,
+ACPI_CPER_SEV_CORRECTED = 2,
+ACPI_CPER_SEV_NONE = 3,
+};
+
+/*
  * Hardware Error Notification
  * ACPI 4.0: 17.3.2.7 Hardware Error Notification
  * Composes dummy Hardware Error Notification descriptor of specified type
@@ -73,6 +108,131 @@ static void build_ghes_hw_error_notification(GArray 
*table, const uint8_t type)
 }
 
 /*
+ * Generic Error Data Entry
+ * ACPI 6.1: 18.3.2.7.1 Generic Error Data
+ */
+static void acpi_ghes_generic_error_data(GArray *table, QemuUUID section_type,
+uint32_t error_severity, uint8_t validation_bits, uint8_t 
flags,
+uint32_t error_data_length, QemuUUID fru_id,
+uint64_t time_stamp)
+{
+/* Section Type */
+g_array_append_vals(table, section_type.data,
+ARRAY_SIZE(section_type.data));
+
+/* Error Severity */
+build_append_int_noprefix(table, error_severity, 4);
+/* Revision */
+build_append_int_noprefix(table, 0x300, 2);
+/* Validation Bits */
+build_append_int_noprefix(table, validation_bits, 1);
+/* Flags */
+build_append_int_noprefix(table, flags, 1);
+/* Error Data Length */
+build_append_int_noprefix(table, error_data_length, 4);
+
+/* FRU Id */
+g_array_append_vals(table, fru_id.data, ARRAY_SIZE(fru_id.data));
+
+/* FRU Text */
+build_append_int_noprefix(table, 0, 20);
+/* Timestamp */
+build_append_int_noprefix(table, time_stamp, 8);
+}
+
+/*
+ * Generic Error Status Block
+ * ACPI 6.1: 18.3.2.7.1 Generic Error Data
+ */
+static void acpi_ghes_generic_error_status(GArray *table, uint32_t 
block_status,
+uint32_t raw_data_offset, uint32_t raw_data_length,
+uint32_t data_length, uint32_t error_severity)
+{
+/* Block Status */
+build_append_int_noprefix(table, block_status, 4);
+/* Raw Data Offset */
+build_append_int_noprefix(table, raw_data_offset, 4);
+/* Raw Data Length */
+build_append_int_noprefix(table, raw_data_length, 4);
+/* Data Length */
+build_append_int_noprefix(table, data_length, 4);
+/* Error Severity */
+build_append_int_noprefix(table, error_severity, 4);
+}
+
+/* UEFI 2.6: N.2.5 Memory Error Section */
+static void acpi_ghes_build_append_mem_cper(GArray *table,
+uint64_t error_physical_addr)
+{
+/*
+ * Memory Error Record
+ */
+
+/* Validation Bits */
+build_append_int_noprefix(table,
+  (1ULL << 14) | /* Type Valid */
+  (1ULL << 1) /* Physical Address Valid */,
+  8);
+/* Error Status */
+build_append_int_noprefix(table, 0, 8);
+/* Physical Address */
+build_append_int_noprefix(table, error_physical_addr, 8);
+/* 

[PATCH RESEND v23 10/10] MAINTAINERS: Add ACPI/HEST/GHES entries

2020-02-16 Thread Dongjiu Geng
I and Xiang are willing to review the APEI-related patches and
volunteer as the reviewers for the HEST/GHES part.

Signed-off-by: Dongjiu Geng 
Signed-off-by: Xiang Zheng 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Michael S. Tsirkin 
---
 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c7717df..0748475 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1446,6 +1446,15 @@ F: tests/qtest/bios-tables-test.c
 F: tests/qtest/acpi-utils.[hc]
 F: tests/data/acpi/
 
+ACPI/HEST/GHES
+R: Dongjiu Geng 
+R: Xiang Zheng 
+L: qemu-...@nongnu.org
+S: Maintained
+F: hw/acpi/ghes.c
+F: include/hw/acpi/ghes.h
+F: docs/specs/acpi_hest_ghes.rst
+
 ppc4xx
 M: David Gibson 
 L: qemu-...@nongnu.org
-- 
1.8.3.1




[PATCH RESEND v23 09/10] target-arm: kvm64: handle SIGBUS signal from kernel or KVM

2020-02-16 Thread Dongjiu Geng
Add a SIGBUS signal handler. In this handler, it checks the SIGBUS type,
translates the host VA delivered by host to guest PA, then fills this PA
to guest APEI GHES memory, then notifies guest according to the SIGBUS
type.

When guest accesses the poisoned memory, it will generate a Synchronous
External Abort(SEA). Then host kernel gets an APEI notification and calls
memory_failure() to unmapped the affected page in stage 2, finally
returns to guest.

Guest continues to access the PG_hwpoison page, it will trap to KVM as
stage2 fault, then a SIGBUS_MCEERR_AR synchronous signal is delivered to
Qemu, Qemu records this error address into guest APEI GHES memory and
notifes guest using Synchronous-External-Abort(SEA).

In order to inject a vSEA, we introduce the kvm_inject_arm_sea() function
in which we can setup the type of exception and the syndrome information.
When switching to guest, the target vcpu will jump to the synchronous
external abort vector table entry.

The ESR_ELx.DFSC is set to synchronous external abort(0x10), and the
ESR_ELx.FnV is set to not valid(0x1), which will tell guest that FAR is
not valid and hold an UNKNOWN value. These values will be set to KVM
register structures through KVM_SET_ONE_REG IOCTL.

Signed-off-by: Dongjiu Geng 
Signed-off-by: Xiang Zheng 
Reviewed-by: Michael S. Tsirkin 
Acked-by: Xiang Zheng 
---
 include/sysemu/kvm.h|  3 +-
 target/arm/cpu.h|  4 +++
 target/arm/helper.c |  2 +-
 target/arm/internals.h  |  5 ++--
 target/arm/kvm64.c  | 73 +
 target/arm/tlb_helper.c |  2 +-
 target/i386/cpu.h   |  2 ++
 7 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 141342d..3b22504 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -379,8 +379,7 @@ bool kvm_vcpu_id_is_valid(int vcpu_id);
 /* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
 unsigned long kvm_arch_vcpu_id(CPUState *cpu);
 
-#ifdef TARGET_I386
-#define KVM_HAVE_MCE_INJECTION 1
+#ifdef KVM_HAVE_MCE_INJECTION
 void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
 #endif
 
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 0b3036c..a8b7fb0 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -28,6 +28,10 @@
 /* ARM processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)
 
+#ifdef TARGET_AARCH64
+#define KVM_HAVE_MCE_INJECTION 1
+#endif
+
 #define EXCP_UDEF1   /* undefined instruction */
 #define EXCP_SWI 2   /* software interrupt */
 #define EXCP_PREFETCH_ABORT  3
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7d15d5c..12a95b6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3310,7 +3310,7 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t 
value,
  * Report exception with ESR indicating a fault due to a
  * translation table walk for a cache maintenance instruction.
  */
-syn = syn_data_abort_no_iss(current_el == target_el,
+syn = syn_data_abort_no_iss(current_el == target_el, 0,
 fi.ea, 1, fi.s1ptw, 1, fsc);
 env->exception.vaddress = value;
 env->exception.fsr = fsr;
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 6d4a942..31b7b96 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -451,13 +451,14 @@ static inline uint32_t syn_insn_abort(int same_el, int 
ea, int s1ptw, int fsc)
 | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
 }
 
-static inline uint32_t syn_data_abort_no_iss(int same_el,
+static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
  int ea, int cm, int s1ptw,
  int wnr, int fsc)
 {
 return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
| ARM_EL_IL
-   | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
+   | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
+   | (wnr << 6) | fsc;
 }
 
 static inline uint32_t syn_data_abort_with_iss(int same_el,
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index fb21ab9..f91b611 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -28,6 +28,8 @@
 #include "sysemu/kvm_int.h"
 #include "kvm_arm.h"
 #include "internals.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/ghes.h"
 
 static bool have_guest_debug;
 
@@ -846,6 +848,30 @@ int kvm_arm_cpreg_level(uint64_t regidx)
 return KVM_PUT_RUNTIME_STATE;
 }
 
+/* Callers must hold the iothread mutex lock */
+static void kvm_inject_arm_sea(CPUState *c)
+{
+ARMCPU *cpu = ARM_CPU(c);
+CPUARMState *env = >env;
+CPUClass *cc = CPU_GET_CLASS(c);
+uint32_t esr;
+bool same_el;
+
+c->exception_index = EXCP_DATA_ABORT;
+env->exception.target_el = 1;
+
+/*
+ * Set the DFSC to synchronous external abort 

[PATCH RESEND v23 05/10] ACPI: Build Hardware Error Source Table

2020-02-16 Thread Dongjiu Geng
This patch builds Hardware Error Source Table(HEST) via fw_cfg blobs.
Now it only supports ARMv8 SEA, a type of Generic Hardware Error
Source version 2(GHESv2) error source. Afterwards, we can extend
the supported types if needed. For the CPER section, currently it
is memory section because kernel mainly wants userspace to handle
the memory errors.

This patch follows the spec ACPI 6.2 to build the Hardware Error
Source table. For more detailed information, please refer to
document: docs/specs/acpi_hest_ghes.rst

build_ghes_hw_error_notification() helper will help to add Hardware
Error Notification to ACPI tables without using packed C structures
and avoid endianness issues as API doesn't need explicit conversion.

Signed-off-by: Dongjiu Geng 
Signed-off-by: Xiang Zheng 
Acked-by: Xiang Zheng 
---
 hw/acpi/ghes.c   | 126 +++
 hw/arm/virt-acpi-build.c |   1 +
 include/hw/acpi/ghes.h   |  39 +++
 3 files changed, 166 insertions(+)

diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index e1b3f8f..7a7381d 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -23,6 +23,7 @@
 #include "qemu/units.h"
 #include "hw/acpi/ghes.h"
 #include "hw/acpi/aml-build.h"
+#include "qemu/error-report.h"
 
 #define ACPI_GHES_ERRORS_FW_CFG_FILE"etc/hardware_errors"
 #define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
@@ -33,6 +34,42 @@
 /* Now only support ARMv8 SEA notification type error source */
 #define ACPI_GHES_ERROR_SOURCE_COUNT1
 
+/* Generic Hardware Error Source version 2 */
+#define ACPI_GHES_SOURCE_GENERIC_ERROR_V2   10
+
+/* Address offset in Generic Address Structure(GAS) */
+#define GAS_ADDR_OFFSET 4
+
+/*
+ * Hardware Error Notification
+ * ACPI 4.0: 17.3.2.7 Hardware Error Notification
+ * Composes dummy Hardware Error Notification descriptor of specified type
+ */
+static void build_ghes_hw_error_notification(GArray *table, const uint8_t type)
+{
+/* Type */
+build_append_int_noprefix(table, type, 1);
+/*
+ * Length:
+ * Total length of the structure in bytes
+ */
+build_append_int_noprefix(table, 28, 1);
+/* Configuration Write Enable */
+build_append_int_noprefix(table, 0, 2);
+/* Poll Interval */
+build_append_int_noprefix(table, 0, 4);
+/* Vector */
+build_append_int_noprefix(table, 0, 4);
+/* Switch To Polling Threshold Value */
+build_append_int_noprefix(table, 0, 4);
+/* Switch To Polling Threshold Window */
+build_append_int_noprefix(table, 0, 4);
+/* Error Threshold Value */
+build_append_int_noprefix(table, 0, 4);
+/* Error Threshold Window */
+build_append_int_noprefix(table, 0, 4);
+}
+
 /*
  * Build table for the hardware error fw_cfg blob.
  * Initialize "etc/hardware_errors" and "etc/hardware_errors_addr" fw_cfg 
blobs.
@@ -87,3 +124,92 @@ void build_ghes_error_table(GArray *hardware_errors, 
BIOSLinker *linker)
 bios_linker_loader_write_pointer(linker, ACPI_GHES_DATA_ADDR_FW_CFG_FILE,
 0, sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE, 0);
 }
+
+/* Build Generic Hardware Error Source version 2 (GHESv2) */
+static void build_ghes_v2(GArray *table_data, int source_id, BIOSLinker 
*linker)
+{
+uint64_t address_offset;
+/*
+ * Type:
+ * Generic Hardware Error Source version 2(GHESv2 - Type 10)
+ */
+build_append_int_noprefix(table_data, ACPI_GHES_SOURCE_GENERIC_ERROR_V2, 
2);
+/* Source Id */
+build_append_int_noprefix(table_data, source_id, 2);
+/* Related Source Id */
+build_append_int_noprefix(table_data, 0x, 2);
+/* Flags */
+build_append_int_noprefix(table_data, 0, 1);
+/* Enabled */
+build_append_int_noprefix(table_data, 1, 1);
+
+/* Number of Records To Pre-allocate */
+build_append_int_noprefix(table_data, 1, 4);
+/* Max Sections Per Record */
+build_append_int_noprefix(table_data, 1, 4);
+/* Max Raw Data Length */
+build_append_int_noprefix(table_data, ACPI_GHES_MAX_RAW_DATA_LENGTH, 4);
+
+address_offset = table_data->len;
+/* Error Status Address */
+build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 0x40, 0,
+ 4 /* QWord access */, 0);
+bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+address_offset + GAS_ADDR_OFFSET, sizeof(uint64_t),
+ACPI_GHES_ERRORS_FW_CFG_FILE, source_id * sizeof(uint64_t));
+
+switch (source_id) {
+case ACPI_HEST_SRC_ID_SEA:
+/*
+ * Notification Structure
+ * Now only enable ARMv8 SEA notification type
+ */
+build_ghes_hw_error_notification(table_data, ACPI_GHES_NOTIFY_SEA);
+break;
+default:
+error_report("Not support this error source");
+abort();
+}
+
+/* Error Status Block Length */
+build_append_int_noprefix(table_data, ACPI_GHES_MAX_RAW_DATA_LENGTH, 4);
+
+/*
+ * Read Ack Register
+ * ACPI 6.1: 18.3.2.8 Generic Hardware Error 

[PATCH RESEND v23 06/10] ACPI: Record the Generic Error Status Block address

2020-02-16 Thread Dongjiu Geng
Record the GHEB address via fw_cfg file, when recording
a error to CPER, it will use this address to find out
Generic Error Data Entries and write the error.

In order to avoid migration failure, make hardware
error table address to a part of GED device instead
of global variable, then this address will be migrated
to target QEMU.

Signed-off-by: Dongjiu Geng 
Acked-by: Xiang Zheng 
---
 hw/acpi/generic_event_device.c | 18 ++
 hw/acpi/ghes.c | 17 +
 hw/arm/virt-acpi-build.c   | 10 ++
 include/hw/acpi/generic_event_device.h |  2 ++
 include/hw/acpi/ghes.h |  6 ++
 5 files changed, 53 insertions(+)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 021ed2b..d59607c 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -234,6 +234,23 @@ static const VMStateDescription vmstate_ged_state = {
 }
 };
 
+static bool ghes_needed(void *opaque)
+{
+return object_property_get_bool(qdev_get_machine(), "ras", NULL);
+}
+
+static const VMStateDescription vmstate_ghes_state = {
+.name = "acpi-ged/ghes",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = ghes_needed,
+.fields  = (VMStateField[]) {
+VMSTATE_STRUCT(ghes_state, AcpiGedState, 1,
+   vmstate_ghes_state, AcpiGhesState),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static const VMStateDescription vmstate_acpi_ged = {
 .name = "acpi-ged",
 .version_id = 1,
@@ -244,6 +261,7 @@ static const VMStateDescription vmstate_acpi_ged = {
 },
 .subsections = (const VMStateDescription * []) {
 _memhp_state,
+_ghes_state,
 NULL
 }
 };
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index 7a7381d..cea2bff 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -24,6 +24,8 @@
 #include "hw/acpi/ghes.h"
 #include "hw/acpi/aml-build.h"
 #include "qemu/error-report.h"
+#include "hw/acpi/generic_event_device.h"
+#include "hw/nvram/fw_cfg.h"
 
 #define ACPI_GHES_ERRORS_FW_CFG_FILE"etc/hardware_errors"
 #define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
@@ -213,3 +215,18 @@ void acpi_build_hest(GArray *table_data, BIOSLinker 
*linker)
 build_header(linker, table_data, (void *)(table_data->data + hest_start),
 "HEST", table_data->len - hest_start, 1, NULL, "");
 }
+
+void acpi_ghes_add_fw_cfg(AcpiGhesState *ags, FWCfgState *s,
+  GArray *hardware_error)
+{
+size_t size = 2 * sizeof(uint64_t) + ACPI_GHES_MAX_RAW_DATA_LENGTH;
+size_t request_block_size = ACPI_GHES_ERROR_SOURCE_COUNT * size;
+
+/* Create a read-only fw_cfg file for GHES */
+fw_cfg_add_file(s, ACPI_GHES_ERRORS_FW_CFG_FILE, hardware_error->data,
+request_block_size);
+
+/* Create a read-write fw_cfg file for Address */
+fw_cfg_add_file_callback(s, ACPI_GHES_DATA_ADDR_FW_CFG_FILE, NULL, NULL,
+NULL, &(ags->ghes_addr_le), sizeof(ags->ghes_addr_le), false);
+}
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 12a9a78..d6e7521 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -832,6 +832,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables 
*tables)
 build_spcr(tables_blob, tables->linker, vms);
 
 if (vms->ras) {
+assert(vms->acpi_dev);
 acpi_add_table(table_offsets, tables_blob);
 build_ghes_error_table(tables->hardware_errors, tables->linker);
 acpi_build_hest(tables_blob, tables->linker);
@@ -924,6 +925,7 @@ void virt_acpi_setup(VirtMachineState *vms)
 {
 AcpiBuildTables tables;
 AcpiBuildState *build_state;
+AcpiGedState *acpi_ged_state;
 
 if (!vms->fw_cfg) {
 trace_virt_acpi_setup();
@@ -954,6 +956,14 @@ void virt_acpi_setup(VirtMachineState *vms)
 fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
 acpi_data_len(tables.tcpalog));
 
+if (vms->ras) {
+assert(vms->acpi_dev);
+acpi_ged_state = ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED,
+   NULL));
+acpi_ghes_add_fw_cfg(_ged_state->ghes_state,
+ vms->fw_cfg, tables.hardware_errors);
+}
+
 build_state->rsdp_mr = acpi_add_rom_blob(virt_acpi_build_update,
  build_state, tables.rsdp,
  ACPI_BUILD_RSDP_FILE, 0);
diff --git a/include/hw/acpi/generic_event_device.h 
b/include/hw/acpi/generic_event_device.h
index d157eac..037d2b5 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -61,6 +61,7 @@
 
 #include "hw/sysbus.h"
 #include "hw/acpi/memory_hotplug.h"
+#include "hw/acpi/ghes.h"
 
 #define ACPI_POWER_BUTTON_DEVICE "PWRB"
 
@@ -95,6 +96,7 @@ typedef struct AcpiGedState {
 

[PATCH RESEND v23 04/10] ACPI: Build related register address fields via hardware error fw_cfg blob

2020-02-16 Thread Dongjiu Geng
This patch builds error_block_address and read_ack_register fields
in hardware errors table , the error_block_address points to Generic
Error Status Block(GESB) via bios_linker. The max size for one GESB
is 1kb in bytes, For more detailed information, please refer to
document: docs/specs/acpi_hest_ghes.rst

Now we only support one Error source, if necessary, we can extend to
support more.

Suggested-by: Laszlo Ersek 
Signed-off-by: Dongjiu Geng 
Signed-off-by: Xiang Zheng 
Reviewed-by: Jonathan Cameron 
---
 default-configs/arm-softmmu.mak |  1 +
 hw/acpi/Kconfig |  4 ++
 hw/acpi/Makefile.objs   |  1 +
 hw/acpi/aml-build.c |  2 +
 hw/acpi/ghes.c  | 89 +
 hw/arm/virt-acpi-build.c|  6 +++
 include/hw/acpi/aml-build.h |  1 +
 include/hw/acpi/ghes.h  | 28 +
 8 files changed, 132 insertions(+)
 create mode 100644 hw/acpi/ghes.c
 create mode 100644 include/hw/acpi/ghes.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 645e620..7648be0 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -41,3 +41,4 @@ CONFIG_FSL_IMX25=y
 CONFIG_FSL_IMX7=y
 CONFIG_FSL_IMX6UL=y
 CONFIG_SEMIHOSTING=y
+CONFIG_ACPI_APEI=y
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index 54209c6..1932f66 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -28,6 +28,10 @@ config ACPI_HMAT
 bool
 depends on ACPI
 
+config ACPI_APEI
+bool
+depends on ACPI
+
 config ACPI_PCI
 bool
 depends on ACPI && PCI
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 777da07..28c5ddb 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -8,6 +8,7 @@ common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
 common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
 common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
 common-obj-$(CONFIG_ACPI_HMAT) += hmat.o
+common-obj-$(CONFIG_ACPI_APEI) += ghes.o
 common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
 common-obj-$(call lnot,$(CONFIG_PC)) += acpi-x86-stub.o
 
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 2c3702b..3681ec6 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1578,6 +1578,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables)
 tables->table_data = g_array_new(false, true /* clear */, 1);
 tables->tcpalog = g_array_new(false, true /* clear */, 1);
 tables->vmgenid = g_array_new(false, true /* clear */, 1);
+tables->hardware_errors = g_array_new(false, true /* clear */, 1);
 tables->linker = bios_linker_loader_init();
 }
 
@@ -1588,6 +1589,7 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, 
bool mfre)
 g_array_free(tables->table_data, true);
 g_array_free(tables->tcpalog, mfre);
 g_array_free(tables->vmgenid, mfre);
+g_array_free(tables->hardware_errors, mfre);
 }
 
 /*
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
new file mode 100644
index 000..e1b3f8f
--- /dev/null
+++ b/hw/acpi/ghes.c
@@ -0,0 +1,89 @@
+/*
+ * Support for generating APEI tables and recording CPER for Guests
+ *
+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Author: Dongjiu Geng 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "hw/acpi/ghes.h"
+#include "hw/acpi/aml-build.h"
+
+#define ACPI_GHES_ERRORS_FW_CFG_FILE"etc/hardware_errors"
+#define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
+
+/* The max size in bytes for one error block */
+#define ACPI_GHES_MAX_RAW_DATA_LENGTH   (1 * KiB)
+
+/* Now only support ARMv8 SEA notification type error source */
+#define ACPI_GHES_ERROR_SOURCE_COUNT1
+
+/*
+ * Build table for the hardware error fw_cfg blob.
+ * Initialize "etc/hardware_errors" and "etc/hardware_errors_addr" fw_cfg 
blobs.
+ * See docs/specs/acpi_hest_ghes.rst for blobs format.
+ */
+void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker)
+{
+int i, error_status_block_offset;
+
+/* Build error_block_address */
+for (i = 0; i < ACPI_GHES_ERROR_SOURCE_COUNT; i++) {
+build_append_int_noprefix(hardware_errors, 0, sizeof(uint64_t));
+}
+
+/* Build read_ack_register */
+for (i = 0; i < ACPI_GHES_ERROR_SOURCE_COUNT; i++) {
+/*
+ * Initialize the 

[PATCH RESEND v23 03/10] docs: APEI GHES generation and CPER record description

2020-02-16 Thread Dongjiu Geng
Add APEI/GHES detailed design document

Signed-off-by: Dongjiu Geng 
Signed-off-by: Xiang Zheng 
Reviewed-by: Michael S. Tsirkin 
Reviewed-by: Igor Mammedov 
---
 docs/specs/acpi_hest_ghes.rst | 110 ++
 docs/specs/index.rst  |   1 +
 2 files changed, 111 insertions(+)
 create mode 100644 docs/specs/acpi_hest_ghes.rst

diff --git a/docs/specs/acpi_hest_ghes.rst b/docs/specs/acpi_hest_ghes.rst
new file mode 100644
index 000..68f1fbe
--- /dev/null
+++ b/docs/specs/acpi_hest_ghes.rst
@@ -0,0 +1,110 @@
+APEI tables generating and CPER record
+==
+
+..
+   Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
+
+   This work is licensed under the terms of the GNU GPL, version 2 or later.
+   See the COPYING file in the top-level directory.
+
+Design Details
+--
+
+::
+
+ etc/acpi/tables   etc/hardware_errors
+     ===
+  + +--+++
+  | | HEST | +->|error_block_address1
|--+
+  | +--+ |  ++ 
 |
+  | | GHES1| | +--->|error_block_address2
|--+-+
+  | +--+ | |++ 
 | |
+  | | .| | ||  ..| 
 | |
+  | | error_status_address-+-+ |-+ 
 | |
+  | | .|   |   +--->|error_block_addressN
|--+-+---+
+  | | read_ack_register+-+ |   |++ 
 | |   |
+  | | read_ack_preserve| +-+---+--->| read_ack_register1 | 
 | |   |
+  | | read_ack_write   |   |   |++ 
 | |   |
+  + +--+   | +-+--->| read_ack_register2 | 
 | |   |
+  | | GHES2|   | | |++ 
 | |   |
+  + +--+   | | ||   .| 
 | |   |
+  | | .|   | | |++ 
 | |   |
+  | | error_status_address-+---+ | | +->| read_ack_registerN | 
 | |   |
+  | | .| | | |  ++ 
 | |   |
+  | | read_ack_register+-+ | |  |Generic Error Status Block 
1|<-+ |   |
+  | | read_ack_preserve|   | |  |-++-+ 
   |   |
+  | | read_ack_write   |   | |  | |  CPER  | | 
   |   |
+  + +--|   | |  | |  CPER  | | 
   |   |
+  | | ...  |   | |  | |    | | 
   |   |
+  + +--+   | |  | |  CPER  | | 
   |   |
+  | | GHESN|   | |  |-++-| 
   |   |
+  + +--+   | |  |Generic Error Status Block 
2|<---+   |
+  | | .|   | |  |-++-+ 
   |
+  | | error_status_address-+---+ |  | |   CPER | | 
   |
+  | | .| |  | |   CPER | | 
   |
+  | | read_ack_register+-+  | |    | | 
   |
+  | | read_ack_preserve|| |   CPER | | 
   |
+  | | read_ack_write   |+-++-+ 
   |
+  + +--+| .. | 
   |
+|+ 
   |
+|Generic Error Status Block N 
|<--+
+|-+-+-+
+| |  CPER   | |
+| |  CPER   | |
+| |     | |
+| |  CPER   | |
++-+-+-+
+
+
+(1) QEMU generates the ACPI HEST table. This table goes in the current
+"etc/acpi/tables" fw_cfg blob. Each error source has different
+notification types.
+
+(2) A new fw_cfg blob called "etc/hardware_errors" is introduced. QEMU
+also needs to populate this blob. The "etc/hardware_errors" fw_cfg blob
+contains an address registers table and an Error Status Data Block table.
+
+(3) The address registers table contains N Error Block Address entries
+and N Read Ack 

[PATCH RESEND v23 02/10] hw/arm/virt: Introduce a RAS machine option

2020-02-16 Thread Dongjiu Geng
RAS Virtualization feature is not supported now, so add a RAS machine
option and disable it by default.

Reviewed-by: Peter Maydell 
Signed-off-by: Dongjiu Geng 
Signed-off-by: Xiang Zheng 
Reviewed-by: Jonathan Cameron 
---
 hw/arm/virt.c | 23 +++
 include/hw/arm/virt.h |  1 +
 2 files changed, 24 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f788fe2..9555b8b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1823,6 +1823,20 @@ static void virt_set_its(Object *obj, bool value, Error 
**errp)
 vms->its = value;
 }
 
+static bool virt_get_ras(Object *obj, Error **errp)
+{
+VirtMachineState *vms = VIRT_MACHINE(obj);
+
+return vms->ras;
+}
+
+static void virt_set_ras(Object *obj, bool value, Error **errp)
+{
+VirtMachineState *vms = VIRT_MACHINE(obj);
+
+vms->ras = value;
+}
+
 static char *virt_get_gic_version(Object *obj, Error **errp)
 {
 VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2126,6 +2140,15 @@ static void virt_instance_init(Object *obj)
 "Valid values are none and smmuv3",
 NULL);
 
+/* Default disallows RAS instantiation */
+vms->ras = false;
+object_property_add_bool(obj, "ras", virt_get_ras,
+ virt_set_ras, NULL);
+object_property_set_description(obj, "ras",
+"Set on/off to enable/disable reporting 
host memory errors "
+"to a KVM guest using ACPI and guest 
external abort exceptions",
+NULL);
+
 vms->irqmap = a15irqmap;
 
 virt_flash_create(vms);
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 71508bf..c32b7c7 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -123,6 +123,7 @@ typedef struct {
 bool highmem_ecam;
 bool its;
 bool virt;
+bool ras;
 int32_t gic_version;
 VirtIOMMUType iommu;
 struct arm_boot_info bootinfo;
-- 
1.8.3.1




[PATCH RESEND v23 01/10] acpi: nvdimm: change NVDIMM_UUID_LE to a common macro

2020-02-16 Thread Dongjiu Geng
The little end UUID is used in many places, so make
NVDIMM_UUID_LE to a common macro to convert the UUID
to a little end array.

Signed-off-by: Dongjiu Geng 
Reviewed-by: Xiang Zheng 
---
 hw/acpi/nvdimm.c| 8 ++--
 include/qemu/uuid.h | 5 +
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 9fdad6d..232b701 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -27,6 +27,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/uuid.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/aml-build.h"
 #include "hw/acpi/bios-linker-loader.h"
@@ -60,17 +61,12 @@ static GSList *nvdimm_get_device_list(void)
 return list;
 }
 
-#define NVDIMM_UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
-   { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
- (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff,  \
- (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }
-
 /*
  * define Byte Addressable Persistent Memory (PM) Region according to
  * ACPI 6.0: 5.2.25.1 System Physical Address Range Structure.
  */
 static const uint8_t nvdimm_nfit_spa_uuid[] =
-  NVDIMM_UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
+  UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
  0x18, 0xb7, 0x8c, 0xdb);
 
 /*
diff --git a/include/qemu/uuid.h b/include/qemu/uuid.h
index 129c45f..bd38af5 100644
--- a/include/qemu/uuid.h
+++ b/include/qemu/uuid.h
@@ -34,6 +34,11 @@ typedef struct {
 };
 } QemuUUID;
 
+#define UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+  { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
+ (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff,  \
+ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }
+
 #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-" \
  "%02hhx%02hhx-%02hhx%02hhx-" \
  "%02hhx%02hhx-" \
-- 
1.8.3.1




[PATCH RESEND v23 07/10] KVM: Move hwpoison page related functions into kvm-all.c

2020-02-16 Thread Dongjiu Geng
kvm_hwpoison_page_add() and kvm_unpoison_all() will both
be used by X86 and ARM platforms, so moving them into
"accel/kvm/kvm-all.c" to avoid duplicate code.

For architectures that don't use the poison-list functionality
the reset handler will harmlessly do nothing, so let's register
the kvm_unpoison_all() function in the generic kvm_init() function.

Reviewed-by: Peter Maydell 
Signed-off-by: Dongjiu Geng 
Signed-off-by: Xiang Zheng 
Acked-by: Xiang Zheng 
---
 accel/kvm/kvm-all.c  | 36 
 include/sysemu/kvm_int.h | 12 
 target/i386/kvm.c| 36 
 3 files changed, 48 insertions(+), 36 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c111312..fc4285e 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -44,6 +44,7 @@
 #include "qapi/visitor.h"
 #include "qapi/qapi-types-common.h"
 #include "qapi/qapi-visit-common.h"
+#include "sysemu/reset.h"
 
 #include "hw/boards.h"
 
@@ -873,6 +874,39 @@ int kvm_vm_check_extension(KVMState *s, unsigned int 
extension)
 return ret;
 }
 
+typedef struct HWPoisonPage {
+ram_addr_t ram_addr;
+QLIST_ENTRY(HWPoisonPage) list;
+} HWPoisonPage;
+
+static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list =
+QLIST_HEAD_INITIALIZER(hwpoison_page_list);
+
+static void kvm_unpoison_all(void *param)
+{
+HWPoisonPage *page, *next_page;
+
+QLIST_FOREACH_SAFE(page, _page_list, list, next_page) {
+QLIST_REMOVE(page, list);
+qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
+g_free(page);
+}
+}
+
+void kvm_hwpoison_page_add(ram_addr_t ram_addr)
+{
+HWPoisonPage *page;
+
+QLIST_FOREACH(page, _page_list, list) {
+if (page->ram_addr == ram_addr) {
+return;
+}
+}
+page = g_new(HWPoisonPage, 1);
+page->ram_addr = ram_addr;
+QLIST_INSERT_HEAD(_page_list, page, list);
+}
+
 static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size)
 {
 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
@@ -2075,6 +2109,8 @@ static int kvm_init(MachineState *ms)
 s->kernel_irqchip_split = mc->default_kernel_irqchip_split ? 
ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
 }
 
+qemu_register_reset(kvm_unpoison_all, NULL);
+
 if (s->kernel_irqchip_allowed) {
 kvm_irqchip_create(s);
 }
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index ac2d1f8..c660a70 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -42,4 +42,16 @@ void kvm_memory_listener_register(KVMState *s, 
KVMMemoryListener *kml,
   AddressSpace *as, int as_id);
 
 void kvm_set_max_memslot_size(hwaddr max_slot_size);
+
+/**
+ * kvm_hwpoison_page_add:
+ *
+ * Parameters:
+ *  @ram_addr: the address in the RAM for the poisoned page
+ *
+ * Add a poisoned page to the list
+ *
+ * Return: None.
+ */
+void kvm_hwpoison_page_add(ram_addr_t ram_addr);
 #endif
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 69eb43d..b8bd979 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -24,7 +24,6 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/hw_accel.h"
 #include "sysemu/kvm_int.h"
-#include "sysemu/reset.h"
 #include "sysemu/runstate.h"
 #include "kvm_i386.h"
 #include "hyperv.h"
@@ -525,40 +524,6 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, 
uint32_t index)
 }
 }
 
-
-typedef struct HWPoisonPage {
-ram_addr_t ram_addr;
-QLIST_ENTRY(HWPoisonPage) list;
-} HWPoisonPage;
-
-static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list =
-QLIST_HEAD_INITIALIZER(hwpoison_page_list);
-
-static void kvm_unpoison_all(void *param)
-{
-HWPoisonPage *page, *next_page;
-
-QLIST_FOREACH_SAFE(page, _page_list, list, next_page) {
-QLIST_REMOVE(page, list);
-qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
-g_free(page);
-}
-}
-
-static void kvm_hwpoison_page_add(ram_addr_t ram_addr)
-{
-HWPoisonPage *page;
-
-QLIST_FOREACH(page, _page_list, list) {
-if (page->ram_addr == ram_addr) {
-return;
-}
-}
-page = g_new(HWPoisonPage, 1);
-page->ram_addr = ram_addr;
-QLIST_INSERT_HEAD(_page_list, page, list);
-}
-
 static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
  int *max_banks)
 {
@@ -2169,7 +2134,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 fprintf(stderr, "e820_add_entry() table is full\n");
 return ret;
 }
-qemu_register_reset(kvm_unpoison_all, NULL);
 
 shadow_mem = object_property_get_int(OBJECT(s), "kvm-shadow-mem", 
_abort);
 if (shadow_mem != -1) {
-- 
1.8.3.1




[PATCH RESEND v23 00/10] Add ARMv8 RAS virtualization support in QEMU

2020-02-16 Thread Dongjiu Geng
In the ARMv8 platform, the CPU error types includes synchronous external 
abort(SEA)
and SError Interrupt (SEI). If exception happens in guest, host does not know 
the
detailed information of guest, so it is expected that guest can do the recovery.
For example, if an exception happens in a guest user-space application, host 
does
not know which application encounters errors, only guest knows it.

For the ARMv8 SEA/SEI, KVM or host kernel delivers SIGBUS to notify userspace.
After user space gets the notification, it will record the CPER into guest GHES
buffer and inject an exception or IRQ to guest.

In the current implementation, if the type of SIGBUS is BUS_MCEERR_AR, we will
treat it as a synchronous exception, and notify guest with ARMv8 SEA
notification type after recording CPER into guest.

A) This series of patches are based on Qemu 4.2, which include two parts:
1. Generate APEI/GHES table.
2. Handle the SIGBUS signal, record the CPER in runtime and fill it into guest
   memory, then notify guest according to the type of SIGBUS.

B) The solution was suggested by James(james.mo...@arm.com); The APEI part 
solution was suggested by Laszlo(ler...@redhat.com). Show some discussions in 
[1].

C) This series of patches have already been tested on ARM64 platform with RAS
feature enabled:
1. Show the APEI part verification result in [2].
2. Show the SIGBUS of BUS_MCEERR_AR handling verification result in [3].

D) Add 'ras' option in command Line to enable guest RAS error recovery feature, 
For example:
KVM model: ./qemu-system-aarch64 --enable-kvm -cpu host --bios QEMU_EFI.fd_new  
-machine virt,gic-version=3,ras,kernel-irqchip=on  -smp 4 -nographic -kernel 
Image  -append "rdinit=/init console=ttyAMA0 mem=512M root=/dev/ram0" -initrd 
guestfs_new.cpio.gz
TCG model: ./qemu-system-aarch64 -cpu cortex-a57 --bios QEMU_EFI.fd_new  
-machine virt,gic-version=3,ras,kernel-irqchip=on  -smp 4 -nographic -kernel 
Image  -append "rdinit=/init console=ttyAMA0 mem=512M root=/dev/ram0" -initrd 
guestfs_new.cpio.gz
---
Change since v22:
1. Using 1 * KiB instead of 0x400 to define max size of one error block
2. Make the alignment to 8 bytes in bios_linker_loader_alloc()
3. Change "Copyright (c) 2019" to "Copyright (c) 2020" in file header
4. Fix some code style warnings/errors and add some comments in code
5. Address Jonathan's comments to easily support CCIX error injection
6. Add vmstate_ghes_state .subsections in vmstate_acpi_ged

Change since v21:
1. Make the user-facing 'ras' option description more clearly to address 
Peter's comments.
2. Update the doc description in "docs/specs/acpi_hest_ghes.rst"
3. Split HEST/GHES patches to more patches to make the review easily
4. Using source_id to index the location to save the CPER.
5. Optimize and simplify the logic to build HEST/GHES table to address 
Igor/Michael/Beata comments.
6. make ghes_addr_le a part of GED device.

Change since v20:
1. Move some implementation details from acpi_ghes.h to acpi_ghes.c
2. Add the reviewers for the ACPI/APEI/GHES part

Change since v19:
1. Fix clang compile error
2. Fix sphinx build error

Change since v18:
1. Fix some code-style and typo/grammar problems.
2. Remove no_ras in the VirtMachineClass struct.
3. Convert documentation to rst format.
4. Simplize the code and add comments for some magic value.
5. Move kvm_inject_arm_sea() function into the patch where it's used.
6. Register the reset handler(kvm_unpoison_all()) in the kvm_init() function.

Change since v17:
1. Improve some commit messages and comments.
2. Fix some code-style problems.
3. Add a *ras* machine option.
4. Move HEST/GHES related structures and macros into "hw/acpi/acpi_ghes.*".
5. Move HWPoison page functions into "include/sysemu/kvm_int.h".
6. Fix some bugs.
7. Improve the design document.

Change since v16:
1. check whether ACPI table is enabled when handling the memory error in the 
SIGBUS handler.

Change since v15:
1. Add a doc-comment in the proper format for 'include/exec/ram_addr.h'
2. Remove write_part_cpustate_to_list() because there is another bug fix patch
   has been merged "arm: Allow system registers for KVM guests to be changed by 
QEMU code"
3. Add some comments for kvm_inject_arm_sea() in 'target/arm/kvm64.c'
4. Compare the arm_current_el() return value to 0,1,2,3, not to PSTATE_MODE_* 
constants.
5. Change the RAS support wasn't introduced before 4.1 QEMU version.
6. Move the no_ras flag  patch to begin in this series

Change since v14:
1. Remove the BUS_MCEERR_AO handling logic because this asynchronous signal was 
masked by main thread
2. Address some Igor Mammedov's comments(ACPI part)
   1) change the comments for the enum AcpiHestNotifyType definition and remove 
ditto in patch 1
   2) change some patch commit messages and separate "APEI GHES table 
generation" patch to more patches.
3. Address some peter's comments(arm64 Synchronous External Abort injection)
   1) change some code notes
   2) using arm_current_el() for current EL
   2) 

[PATCH 2/3] COLO: Migrate dirty pages during the gap of checkpointing

2020-02-16 Thread Hailiang Zhang
We can migrate some dirty pages during the gap of checkpointing,
by this way, we can reduce the amount of ram migrated during checkpointing.

Signed-off-by: Hailiang Zhang 
---
 migration/colo.c   | 69 +++---
 migration/migration.h  |  1 +
 migration/trace-events |  1 +
 qapi/migration.json|  4 ++-
 4 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/migration/colo.c b/migration/colo.c
index 93c5a452fb..d30c6bc4ad 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -46,6 +46,13 @@ static COLOMode last_colo_mode;
 
 #define COLO_BUFFER_BASE_SIZE (4 * 1024 * 1024)
 
+#define DEFAULT_RAM_PENDING_CHECK 1000
+
+/* should be calculated by bandwidth and max downtime ? */
+#define THRESHOLD_PENDING_SIZE (100 * 1024 * 1024UL)
+
+static int checkpoint_request;
+
 bool migration_in_colo_state(void)
 {
 MigrationState *s = migrate_get_current();
@@ -516,6 +523,20 @@ static void colo_compare_notify_checkpoint(Notifier 
*notifier, void *data)
 colo_checkpoint_notify(data);
 }
 
+static bool colo_need_migrate_ram_background(MigrationState *s)
+{
+uint64_t pending_size, pend_pre, pend_compat, pend_post;
+int64_t max_size = THRESHOLD_PENDING_SIZE;
+
+qemu_savevm_state_pending(s->to_dst_file, max_size, _pre,
+  _compat, _post);
+pending_size = pend_pre + pend_compat + pend_post;
+
+trace_colo_need_migrate_ram_background(pending_size);
+return (pending_size >= max_size);
+}
+
+
 static void colo_process_checkpoint(MigrationState *s)
 {
 QIOChannelBuffer *bioc;
@@ -571,6 +592,8 @@ static void colo_process_checkpoint(MigrationState *s)
 
 timer_mod(s->colo_delay_timer,
 current_time + s->parameters.x_checkpoint_delay);
+timer_mod(s->pending_ram_check_timer,
+current_time + DEFAULT_RAM_PENDING_CHECK);
 
 while (s->state == MIGRATION_STATUS_COLO) {
 if (failover_get_state() != FAILOVER_STATUS_NONE) {
@@ -583,10 +606,25 @@ static void colo_process_checkpoint(MigrationState *s)
 if (s->state != MIGRATION_STATUS_COLO) {
 goto out;
 }
-ret = colo_do_checkpoint_transaction(s, bioc, fb);
-if (ret < 0) {
-goto out;
-}
+if (atomic_xchg(_request, 0)) {
+/* start a colo checkpoint */
+ret = colo_do_checkpoint_transaction(s, bioc, fb);
+if (ret < 0) {
+goto out;
+}
+} else {
+if (colo_need_migrate_ram_background(s)) {
+colo_send_message(s->to_dst_file,
+  COLO_MESSAGE_MIGRATE_RAM_BACKGROUND,
+  _err);
+if (local_err) {
+goto out;
+}
+
+qemu_savevm_state_iterate(s->to_dst_file, false);
+qemu_put_byte(s->to_dst_file, QEMU_VM_EOF);
+}
+ }
 }
 
 out:
@@ -626,6 +664,8 @@ out:
 colo_compare_unregister_notifier(_compare_notifier);
 timer_del(s->colo_delay_timer);
 timer_free(s->colo_delay_timer);
+timer_del(s->pending_ram_check_timer);
+timer_free(s->pending_ram_check_timer);
 qemu_sem_destroy(>colo_checkpoint_sem);
 
 /*
@@ -643,6 +683,7 @@ void colo_checkpoint_notify(void *opaque)
 MigrationState *s = opaque;
 int64_t next_notify_time;
 
+atomic_inc(_request);
 qemu_sem_post(>colo_checkpoint_sem);
 s->colo_checkpoint_time = qemu_clock_get_ms(QEMU_CLOCK_HOST);
 next_notify_time = s->colo_checkpoint_time +
@@ -650,6 +691,19 @@ void colo_checkpoint_notify(void *opaque)
 timer_mod(s->colo_delay_timer, next_notify_time);
 }
 
+static void colo_pending_ram_check_notify(void *opaque)
+{
+int64_t next_notify_time;
+MigrationState *s = opaque;
+
+if (migration_in_colo_state()) {
+next_notify_time = DEFAULT_RAM_PENDING_CHECK +
+   qemu_clock_get_ms(QEMU_CLOCK_HOST);
+timer_mod(s->pending_ram_check_timer, next_notify_time);
+qemu_sem_post(>colo_checkpoint_sem);
+}
+}
+
 void migrate_start_colo_process(MigrationState *s)
 {
 qemu_mutex_unlock_iothread();
@@ -657,6 +711,8 @@ void migrate_start_colo_process(MigrationState *s)
 s->colo_delay_timer =  timer_new_ms(QEMU_CLOCK_HOST,
 colo_checkpoint_notify, s);
 
+s->pending_ram_check_timer = timer_new_ms(QEMU_CLOCK_HOST,
+colo_pending_ram_check_notify, s);
 qemu_sem_init(>colo_exit_sem, 0);
 migrate_set_state(>state, MIGRATION_STATUS_ACTIVE,
   MIGRATION_STATUS_COLO);
@@ -805,6 +861,11 @@ static void 
colo_wait_handle_message(MigrationIncomingState *mis,
 case COLO_MESSAGE_CHECKPOINT_REQUEST:
 colo_incoming_process_checkpoint(mis, fb, bioc, errp);
 break;
+case COLO_MESSAGE_MIGRATE_RAM_BACKGROUND:
+if (qemu_loadvm_state_main(mis->from_src_file, mis) < 0) {
+

[PATCH 0/3] Optimize VM's downtime while do checkpoint in COLO

2020-02-16 Thread Hailiang Zhang
Hi,

This is an untested serial that tries to reduce VM's pause time
while do checkpoint in COLO state.

The second patch tries to reduce the total number of dirty pages
while do checkpoint with VM been paused, instead of sending all
dirty pages while VM been pause, it sends part of dirty pages during
the gap time of two checkpoints when SVM and PVM are running.

The third patch tries to reduce the pause time of backup ram into
cache in secondary part.


Hailiang Zhang (3):
  migration/colo: wrap incoming checkpoint process into new helper
  COLO: Migrate dirty pages during the gap of checkpointing
  COLO: Optimize memory back-up process

 migration/colo.c   | 332 +
 migration/migration.h  |   1 +
 migration/ram.c|  35 -
 migration/ram.h|   1 +
 migration/trace-events |   1 +
 qapi/migration.json|   4 +-
 6 files changed, 234 insertions(+), 140 deletions(-)

-- 
2.21.0





[PATCH 3/3] COLO: Optimize memory back-up process

2020-02-16 Thread Hailiang Zhang
This patch will reduce the downtime of VM for the initial process,
Privously, we copied all these memory in preparing stage of COLO
while we need to stop VM, which is a time-consuming process.
Here we optimize it by a trick, back-up every page while in migration
process while COLO is enabled, though it affects the speed of the
migration, but it obviously reduce the downtime of back-up all SVM'S
memory in COLO preparing stage.

Signed-off-by: Hailiang Zhang 
---
 migration/colo.c |  3 +++
 migration/ram.c  | 35 +++
 migration/ram.h  |  1 +
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/migration/colo.c b/migration/colo.c
index d30c6bc4ad..febf010571 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -26,6 +26,7 @@
 #include "qemu/main-loop.h"
 #include "qemu/rcu.h"
 #include "migration/failover.h"
+#include "migration/ram.h"
 #ifdef CONFIG_REPLICATION
 #include "replication.h"
 #endif
@@ -906,6 +907,8 @@ void *colo_process_incoming_thread(void *opaque)
  */
 qemu_file_set_blocking(mis->from_src_file, true);
 
+colo_incoming_start_dirty_log();
+
 bioc = qio_channel_buffer_new(COLO_BUFFER_BASE_SIZE);
 fb = qemu_fopen_channel_input(QIO_CHANNEL(bioc));
 object_unref(OBJECT(bioc));
diff --git a/migration/ram.c b/migration/ram.c
index ed23ed1c7c..24a8aa3527 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2986,7 +2986,6 @@ int colo_init_ram_cache(void)
 }
 return -errno;
 }
-memcpy(block->colo_cache, block->host, block->used_length);
 }
 }
 
@@ -3005,12 +3004,16 @@ int colo_init_ram_cache(void)
 bitmap_set(block->bmap, 0, pages);
 }
 }
+
+return 0;
+}
+
+void colo_incoming_start_dirty_log(void)
+{
 ram_state = g_new0(RAMState, 1);
 ram_state->migration_dirty_pages = 0;
 qemu_mutex_init(_state->bitmap_mutex);
 memory_global_dirty_log_start();
-
-return 0;
 }
 
 /* It is need to hold the global lock to call this helper */
@@ -3348,7 +3351,7 @@ static int ram_load_precopy(QEMUFile *f)
 
 while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {
 ram_addr_t addr, total_ram_bytes;
-void *host = NULL;
+void *host = NULL, *host_bak = NULL;
 uint8_t ch;
 
 /*
@@ -3378,13 +3381,26 @@ static int ram_load_precopy(QEMUFile *f)
 if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
  RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
 RAMBlock *block = ram_block_from_stream(f, flags);
-
 /*
- * After going into COLO, we should load the Page into colo_cache.
+ * After going into COLO, we should load the Page into colo_cache
+ * NOTE: We need to keep a copy of SVM's ram in colo_cache.
+ * Privously, we copied all these memory in preparing stage of COLO
+ * while we need to stop VM, which is a time-consuming process.
+ * Here we optimize it by a trick, back-up every page while in
+ * migration process while COLO is enabled, though it affects the
+ * speed of the migration, but it obviously reduce the downtime of
+ * back-up all SVM'S memory in COLO preparing stage.
  */
-if (migration_incoming_in_colo_state()) {
+if (migration_incoming_colo_enabled()) {
 host = colo_cache_from_block_offset(block, addr);
-} else {
+/*
+ * After going into COLO, load the Page into colo_cache.
+ */
+if (!migration_incoming_in_colo_state()) {
+host_bak = host;
+}
+}
+if (!migration_incoming_in_colo_state()) {
 host = host_from_ram_block_offset(block, addr);
 }
 if (!host) {
@@ -3506,6 +3522,9 @@ static int ram_load_precopy(QEMUFile *f)
 if (!ret) {
 ret = qemu_file_get_error(f);
 }
+if (!ret && host_bak && host) {
+memcpy(host_bak, host, TARGET_PAGE_SIZE);
+}
 }
 
 ret |= wait_for_decompress_done();
diff --git a/migration/ram.h b/migration/ram.h
index a553d40751..5ceaff7cb4 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -66,5 +66,6 @@ int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *rb);
 /* ram cache */
 int colo_init_ram_cache(void);
 void colo_release_ram_cache(void);
+void colo_incoming_start_dirty_log(void);
 
 #endif
-- 
2.21.0





[PATCH 1/3] migration/colo: wrap incoming checkpoint process into new helper

2020-02-16 Thread Hailiang Zhang
Split checkpoint incoming process into a helper.

Signed-off-by: Hailiang Zhang 
---
 migration/colo.c | 260 ---
 1 file changed, 133 insertions(+), 127 deletions(-)

diff --git a/migration/colo.c b/migration/colo.c
index 2c88aa57a2..93c5a452fb 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -664,13 +664,138 @@ void migrate_start_colo_process(MigrationState *s)
 qemu_mutex_lock_iothread();
 }
 
-static void colo_wait_handle_message(QEMUFile *f, int *checkpoint_request,
- Error **errp)
+static void colo_incoming_process_checkpoint(MigrationIncomingState *mis,
+  QEMUFile *fb, QIOChannelBuffer *bioc, Error **errp)
+{
+uint64_t total_size;
+uint64_t value;
+Error *local_err = NULL;
+int ret;
+
+qemu_mutex_lock_iothread();
+vm_stop_force_state(RUN_STATE_COLO);
+trace_colo_vm_state_change("run", "stop");
+qemu_mutex_unlock_iothread();
+
+/* FIXME: This is unnecessary for periodic checkpoint mode */
+colo_send_message(mis->to_src_file, COLO_MESSAGE_CHECKPOINT_REPLY,
+ _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+colo_receive_check_message(mis->from_src_file,
+   COLO_MESSAGE_VMSTATE_SEND, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+qemu_mutex_lock_iothread();
+cpu_synchronize_all_pre_loadvm();
+ret = qemu_loadvm_state_main(mis->from_src_file, mis);
+qemu_mutex_unlock_iothread();
+
+if (ret < 0) {
+error_setg(errp, "Load VM's live state (ram) error");
+return;
+}
+
+value = colo_receive_message_value(mis->from_src_file,
+ COLO_MESSAGE_VMSTATE_SIZE, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+/*
+ * Read VM device state data into channel buffer,
+ * It's better to re-use the memory allocated.
+ * Here we need to handle the channel buffer directly.
+ */
+if (value > bioc->capacity) {
+bioc->capacity = value;
+bioc->data = g_realloc(bioc->data, bioc->capacity);
+}
+total_size = qemu_get_buffer(mis->from_src_file, bioc->data, value);
+if (total_size != value) {
+error_setg(errp, "Got %" PRIu64 " VMState data, less than expected"
+" %" PRIu64, total_size, value);
+return;
+}
+bioc->usage = total_size;
+qio_channel_io_seek(QIO_CHANNEL(bioc), 0, 0, NULL);
+
+colo_send_message(mis->to_src_file, COLO_MESSAGE_VMSTATE_RECEIVED,
+ _err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+qemu_mutex_lock_iothread();
+vmstate_loading = true;
+ret = qemu_load_device_state(fb);
+if (ret < 0) {
+error_setg(errp, "COLO: load device state failed");
+qemu_mutex_unlock_iothread();
+return;
+}
+
+#ifdef CONFIG_REPLICATION
+replication_get_error_all(_err);
+if (local_err) {
+error_propagate(errp, local_err);
+qemu_mutex_unlock_iothread();
+return;
+}
+
+/* discard colo disk buffer */
+replication_do_checkpoint_all(_err);
+if (local_err) {
+error_propagate(errp, local_err);
+qemu_mutex_unlock_iothread();
+return;
+}
+#else
+abort();
+#endif
+/* Notify all filters of all NIC to do checkpoint */
+colo_notify_filters_event(COLO_EVENT_CHECKPOINT, _err);
+
+if (local_err) {
+error_propagate(errp, local_err);
+qemu_mutex_unlock_iothread();
+return;
+}
+
+vmstate_loading = false;
+vm_start();
+trace_colo_vm_state_change("stop", "run");
+qemu_mutex_unlock_iothread();
+
+if (failover_get_state() == FAILOVER_STATUS_RELAUNCH) {
+failover_set_state(FAILOVER_STATUS_RELAUNCH,
+FAILOVER_STATUS_NONE);
+failover_request_active(NULL);
+return;
+}
+
+colo_send_message(mis->to_src_file, COLO_MESSAGE_VMSTATE_LOADED,
+ _err);
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
+static void colo_wait_handle_message(MigrationIncomingState *mis,
+QEMUFile *fb, QIOChannelBuffer *bioc, Error **errp)
 {
 COLOMessage msg;
 Error *local_err = NULL;
 
-msg = colo_receive_message(f, _err);
+msg = colo_receive_message(mis->from_src_file, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
@@ -678,10 +803,9 @@ static void colo_wait_handle_message(QEMUFile *f, int 
*checkpoint_request,
 
 switch (msg) {
 case COLO_MESSAGE_CHECKPOINT_REQUEST:
-*checkpoint_request = 1;
+colo_incoming_process_checkpoint(mis, fb, bioc, errp);
 break;
 default:
-*checkpoint_request = 0;
 error_setg(errp, "Got unknown 

Re: [PATCH v3] Implement the Screamer sound chip for the mac99 machine type

2020-02-16 Thread Programmingkid


> On Feb 16, 2020, at 2:57 PM, Howard Spoelstra  wrote:
> 
> 
> 
> 
> On Sun, Feb 16, 2020 at 5:32 PM John Arbuckle  
> wrote:
> Signed-off-by: John Arbuckle 
> ---
> v3 changes:
> - Updated the location of patched code in hw/ppc/kconfig.
> - Removed setting the props variable in screamer.c.
> - Removed the screamer_properties variable in screamer.c.
> 
> v2 changes:
> - Fixed a bug that prevented the sampling rate from being changed.
> 
>  hw/audio/Kconfig  |   3 +
>  hw/audio/Makefile.objs|   2 +
>  hw/audio/screamer.c   | 983 
> ++
>  hw/misc/macio/macio.c |  35 +-
>  hw/ppc/Kconfig|   1 +
>  hw/ppc/mac.h  |   5 +
>  include/hw/audio/screamer.h   |  42 ++
>  include/hw/misc/macio/macio.h |   2 +
>  8 files changed, 1072 insertions(+), 1 deletion(-)
>  create mode 100644 hw/audio/screamer.c
>  create mode 100644 include/hw/audio/screamer.h
> 
> diff --git a/hw/audio/Kconfig b/hw/audio/Kconfig
> index e9c6fed826..196da6c3fe 100644
> --- a/hw/audio/Kconfig
> +++ b/hw/audio/Kconfig
> @@ -50,3 +50,6 @@ config CS4231
> 
>  config MARVELL_88W8618
>  bool
> +
> +config SCREAMER
> +bool
> diff --git a/hw/audio/Makefile.objs b/hw/audio/Makefile.objs
> index 63db383709..55906886bc 100644
> --- a/hw/audio/Makefile.objs
> +++ b/hw/audio/Makefile.objs
> @@ -15,4 +15,6 @@ common-obj-$(CONFIG_CS4231) += cs4231.o
>  common-obj-$(CONFIG_MARVELL_88W8618) += marvell_88w8618.o
>  common-obj-$(CONFIG_MILKYMIST) += milkymist-ac97.o
> 
> +common-obj-$(CONFIG_SCREAMER) += screamer.o
> +
>  common-obj-y += soundhw.o
> diff --git a/hw/audio/screamer.c b/hw/audio/screamer.c
> new file mode 100644
> index 00..ad4aba12eb
> --- /dev/null
> +++ b/hw/audio/screamer.c
> @@ -0,0 +1,983 @@
> +/*
> + * File: Screamer.c
> + * Description: Implement the Screamer sound chip used in Apple Macintoshes.
> + * It works by filling a buffer, then playing the buffer.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "audio/audio.h"
> +#include "hw/hw.h"
> +#include "hw/irq.h"
> +#include 
> +#include "hw/ppc/mac.h"
> +#include "hw/qdev-properties.h"
> +#include "migration/vmstate.h"
> +#include "include/hw/audio/screamer.h"
> +
> +#define DEBUG_SCREAMER 0
> +#define DPRINTF(fmt, ...) \
> +do { if (DEBUG_SCREAMER) { printf(fmt , ## __VA_ARGS__); } } while (0)
> +
> +#define SOUND_CONTROL_REG  0
> +#define CODEC_CONTROL_REG  1
> +#define CODEC_STATUS_REG   2
> +#define CLIP_COUNT_REG 3
> +#define BYTE_SWAP_REG  4
> +#define FRAME_COUNT_REG5
> +
> +#define AWACS_BUSY 0x0100
> +
> +/* Used with AWACS register 1 */
> +#define RECALIBRATE 0x004
> +#define LOOPTHRU0x040
> +#define SPEAKER_MUTE0x080
> +#define HEADPHONE_MUTE  0x200
> +#define OUTPUT_ZERO 0x400
> +#define OUTPUT_ONE  0x800
> +#define PARALLEL_OUTPUT 0xc00
> +
> +/* Function prototypes */
> +static uint32_t set_busy_bit(uint32_t value, int bit);
> +static uint32_t set_part_ready_bit(uint32_t value, int bit_value);
> +static uint32_t set_revision(uint32_t input_value);
> +static uint32_t set_manufacturer(uint32_t input_value);
> +static int get_sampling_rate(ScreamerState *s);
> +static uint32_t get_frame_count_reg(ScreamerState *s);
> +static void add_to_speaker_buffer(DBDMA_io *io);
> +static void dma_request(DBDMA_io *io);
> +
> +
> +/ Getters */
> +
> +/* Returns the codec control register's encoded AWACS address */
> +static uint8_t get_codec_control_address(uint32_t value)
> +{
> +uint8_t return_value;
> +return_value = (value >> 12) & 0x0fff;
> +return return_value;
> +}
> +
> +
> +static uint32_t get_sound_control_reg(ScreamerState *s)
> +{
> +DPRINTF("%s() called - returned 0x%x\n", __func__, s->sound_control);
> +return s->sound_control;
> +}
> +
> +/* The AWACS registers are accessed thru this register */
> +static uint32_t get_codec_control_reg(ScreamerState *s)
> +{
> +int awacs_register = get_codec_control_address(s->codec_control);
> +uint32_t return_value = s->awacs[awacs_register];
> +return_value = set_busy_bit(return_value, 0); /* Tell CPU we are ready */
> +DPRINTF("%s() called - returned 0x%x\tAWACS register: %d\n", __func__,
> +return_value, awacs_register);
> +return return_value;
> +}
> +
> +/*
> + * Determines if the readback bit is set.
> + * It is used by the Codec Control register.
> + */
> +static bool readback_enabled(ScreamerState *s)
> +{
> +/* Note: bit zero is the readback enabled bit */
> +if (s->awacs[7] & 1) {
> +return true;
> +} else {
> +return false;
> +}
> +}
> +
> +static uint32_t get_codec_status_reg(ScreamerState *s)
> +{
> +uint32_t return_value;
> +
> +/* if in readback mode - return AWACS register value */
> +if (readback_enabled(s)) {
> +int awacs_register = (s->awacs[7] & 0xe) >> 1;
> +   

Re: [PATCH v3] Implement the Screamer sound chip for the mac99 machine type

2020-02-16 Thread Programmingkid


> On Feb 16, 2020, at 4:59 PM, BALATON Zoltan  wrote:
> 
> On Sun, 16 Feb 2020, Howard Spoelstra wrote:
>> On Sun, Feb 16, 2020 at 5:32 PM John Arbuckle 
>> wrote:
>>> diff --git a/hw/audio/screamer.c b/hw/audio/screamer.c
>>> new file mode 100644
>>> index 00..ad4aba12eb
>>> --- /dev/null
>>> +++ b/hw/audio/screamer.c
>>> @@ -0,0 +1,983 @@
>>> +/*
>>> + * File: Screamer.c
>>> + * Description: Implement the Screamer sound chip used in Apple
>>> Macintoshes.
>>> + * It works by filling a buffer, then playing the buffer.
>>> + */
> 
> Do you need a copyright and license header here? Especially if this is not 
> all your original work but based on previous code (don't know if it is just 
> saying in case as I know Mark also had some similar patches before but not 
> sure how are those related if at all). If this contains code from somewhere 
> else then license and author of that code may need to be included too.

That is a good question. According to this page https://wiki.qemu.org/License, 
files that don't have licensing information default under the GNU GPL v2. I'm 
fine with that.

> 
>>> +/* Called when the CPU writes to the memory addresses assigned to
>>> Screamer */
>>> +static void screamer_mmio_write(void *opaque, hwaddr addr, uint64_t
>>> raw_value,
>>> +unsigned size)
>>> +{
>>> +DPRINTF("screamer_mmio_write() called - size: %d\n", size);
>>> +ScreamerState *state = opaque;
>>> +uint32_t value = raw_value & 0x;
>>> +addr = addr >> 4;
>>> +
>>> +switch (addr) {
>>> +case SOUND_CONTROL_REG:
>>> +set_sound_control_reg(state, value);
>>> +break;
>>> +case CODEC_CONTROL_REG:
>>> +set_codec_control_reg(state, value);
>>> +break;
>>> +case CODEC_STATUS_REG:
>>> +set_codec_status_reg(state, value);
>>> +break;
>>> +case CLIP_COUNT_REG:
>>> +set_clip_count_reg(state, value);
>>> +break;
>>> +case BYTE_SWAP_REG:
>>> +set_byte_swap_reg(state, value);
>>> +break;
>>> +case FRAME_COUNT_REG:
>>> +set_frame_count_reg(state, value);
>>> +break;
>>> +default:
>>> +DPRINTF("Unknown register write - addr:%llu\tvalue:%d\n", addr,
>>> value);
>>> +}
>>> +}
>>> 
>>> Hi,
>> 
>> This patch will not compile without errors. Host is Fedora 31.
>> The compiler suggests changing lines 839, 842 and 878 in screamer.c so the
>> DPRINTF arguments use %lu instead of %llu.
>> With that fixed, compiling completes succesfully.
> 
> Replacing with %lu may fix 32bit build but would break 64bit one. Use 
> HWADDR_PRIx format string instead to print hwaddr but others will probably 
> tell to remove DPRINTFs alltogether when they are not needed any more and 
> replace the remaining few useful ones with traces if debugging is still 
> needed. I don't mind DPRINTFs that much at least until things are stable 
> enough but once the code is stable most DPRINTFs may not be needed any more.
> 
> I can't really review the actual patch because I don't know audio in QEMU.
> 
> Regards,
> BALATON Zoltan

Your HWADDR_PRIx suggestion was great. I am making a small patch to test out 
your suggestion.

Thank you.




Re: [PATCH v2 07/30] qapi/block-core.json: Use literal block for ascii art

2020-02-16 Thread Philippe Mathieu-Daudé
On Sat, Feb 15, 2020 at 10:01 PM Aleksandar Markovic
 wrote:
> 9:56 PM Sub, 15.02.2020. Philippe Mathieu-Daudé  
> је написао/ла:
> > On Fri, Feb 14, 2020 at 12:04 AM Aleksandar Markovic
> >  wrote:
> > >
> > > 6:59 PM Čet, 13.02.2020. Peter Maydell  је 
> > > написао/ла:
> > > >
> > > > The ascii-art graph
> > >
> > > Just out of couriousity, are unicode characters allowed in rst files?
> >
> > I remember 2 years ago a blind developer thanked the QEMU community to
> > still restrict commits to 80 characters, because while 4K display are
> > available, he and other visually impaired developers cloud still
> > browse the QEMU codebase with their refreshable Braille display (which
> > was 80 cels). I don't know how many visually impaired developers are
> > following this project. A quick google returns " There is no concept
> > of Unicode in Braille. In that sense Braille is similar to old 8-bit
> > code pages which represented different symbols in different languages
> > for the same symbol code."
> > (https://superuser.com/questions/629443/represent-unicode-characters-in-braille).
> >
> > (I'm Cc'ing Samuel who cares about Braille displays.)
> >
>
> Got it.

AFAIK there are no particular care in the project regarding visually
impaired developers, maybe we are already using things that exclude
them.
IOW without a project policy to include visually impaired developers,
my comment is irrelevant and it shouldn't restrict the use of unicode
to improve documentation.
Personally I'd rather we keep the project open to all possible contributors.

> > >
> > > The boxes could've been rendered in a much more beautifull way using 
> > > "lines and corners" group of unicode characters.
> > >
> > > Aleksandar



Re: [PATCH] configure: Avoid compiling system tools on user build by default

2020-02-16 Thread Philippe Mathieu-Daudé
On Sun, Feb 16, 2020 at 8:27 PM Aleksandar Markovic
 wrote:
>
> 5:23 PM Sub, 15.02.2020. Philippe Mathieu-Daudé  је 
> написао/ла:
> >
> > User-mode does not need the sytem tools. Do not build them by
> > default if user specified --disable-system.
> >
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> >  configure | 11 ++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> >
>
> It would be nice if somebody comes up with more detailed analysis on what is 
> built for --disable-system, but in fact not needed at all.

This patch disable building the following binary on a user-only build:

- elf2dmp
- qemu-edid
- qemu-ga
- qemu-img
- qemu-io
- qemu-nbd
- ivshmem-client
- ivshmem-server

Maybe Laurent can amend that to the description, else I can respin.

> How does your change affect the size of the executable?

Their size depends of the build option used (i.e. -ggdb vs -Os -s).

The bigger difference is the build runs faster.

> > diff --git a/configure b/configure
> > index 16f94cd96b..557ca4bd04 100755
> > --- a/configure
> > +++ b/configure
> > @@ -455,7 +455,7 @@ guest_agent_ntddscsi="no"
> >  guest_agent_msi=""
> >  vss_win32_sdk=""
> >  win_sdk="no"
> > -want_tools="yes"
> > +want_tools=""
> >  libiscsi=""
> >  libnfs=""
> >  coroutine=""
> > @@ -2199,6 +2199,15 @@ else
> >  echo big/little test failed
> >  fi
> >
> > +##
> > +# system tools
> > +if test "$want_tools" != "yes" && test "$softmmu" = "no"; then
> > +want_tools=no
> > +fi
> > +if test -z "$want_tools"; then
> > +want_tools=yes
> > +fi
> > +
> >  ##
> >  # cocoa implies not SDL or GTK
> >  # (the cocoa UI code currently assumes it is always the active UI
> > --
> > 2.21.1
> >
> >



Re: [PATCH] ppc: free 'fdt' after reset the machine

2020-02-16 Thread David Gibson
On Sat, Feb 15, 2020 at 09:30:56AM +0800, Pan Nengyuan wrote:
> 
> 
> On 2/14/2020 11:48 PM, Greg Kurz wrote:
> > On Fri, 14 Feb 2020 11:32:06 +0800
> >  wrote:
> > 
> >> From: Pan Nengyuan 
> >>
> >> 'fdt' forgot to clean both e500 and pnv when we call 'system_reset' on ppc,
> >> this patch fix it. The leak stacks are as follow:
> >>
> >> Direct leak of 4194304 byte(s) in 4 object(s) allocated from:
> >> #0 0x7fafe37dd970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970)
> >> #1 0x7fafe2e3149d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d)
> >> #2 0x561876f7f80d in create_device_tree 
> >> /mnt/sdb/qemu-new/qemu/device_tree.c:40
> >> #3 0x561876b7ac29 in ppce500_load_device_tree 
> >> /mnt/sdb/qemu-new/qemu/hw/ppc/e500.c:364
> >> #4 0x561876b7f437 in ppce500_reset_device_tree 
> >> /mnt/sdb/qemu-new/qemu/hw/ppc/e500.c:617
> >> #5 0x56187718b1ae in qemu_devices_reset 
> >> /mnt/sdb/qemu-new/qemu/hw/core/reset.c:69
> >> #6 0x561876f6938d in qemu_system_reset /mnt/sdb/qemu-new/qemu/vl.c:1412
> >> #7 0x561876f6a25b in main_loop_should_exit 
> >> /mnt/sdb/qemu-new/qemu/vl.c:1645
> >> #8 0x561876f6a398 in main_loop /mnt/sdb/qemu-new/qemu/vl.c:1679
> >> #9 0x561876f7da8e in main /mnt/sdb/qemu-new/qemu/vl.c:4438
> >> #10 0x7fafde16b812 in __libc_start_main ../csu/libc-start.c:308
> >> #11 0x5618765c055d in _start 
> >> (/mnt/sdb/qemu-new/qemu/build/ppc64-softmmu/qemu-system-ppc64+0x2b1555d)
> >>
> >> Direct leak of 1048576 byte(s) in 1 object(s) allocated from:
> >> #0 0x7fc0a6f1b970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970)
> >> #1 0x7fc0a656f49d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d)
> >> #2 0x55eb05acd2ca in pnv_dt_create 
> >> /mnt/sdb/qemu-new/qemu/hw/ppc/pnv.c:507
> >> #3 0x55eb05ace5bf in pnv_reset /mnt/sdb/qemu-new/qemu/hw/ppc/pnv.c:578
> >> #4 0x55eb05f2f395 in qemu_system_reset /mnt/sdb/qemu-new/qemu/vl.c:1410
> >> #5 0x55eb05f43850 in main /mnt/sdb/qemu-new/qemu/vl.c:4403
> >> #6 0x7fc0a18a9812 in __libc_start_main ../csu/libc-start.c:308
> >> #7 0x55eb0558655d in _start 
> >> (/mnt/sdb/qemu-new/qemu/build/ppc64-softmmu/qemu-system-ppc64+0x2b1555d)
> >>
> >> Reported-by: Euler Robot 
> > 
> > The recipient list and 'git log' seem to agree on the fact that 'Euler 
> > Robot'
> > has its own email address, that is not yours ;-)
> > 
> > Reported-by: Euler Robot 
> > 
> > I guess David can fix this when applying the patch. No need to repost
> > unless explicitly asked to do so.
> 
> Yes, your guess is right. I'm sorry for my carelessness.

Corrected inline and merged, thanks.

Oddly, the original mail of this series didn't seem to appear in my
inbox, although the replies did, even though I see that you've CCed
me.

I hope that just means that it did appear and I accidentally deleted
it, not that something is wrong with my mail setup.

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


signature.asc
Description: PGP signature


Re: [PATCH v2 0/2] spapr: Fix device unplug vs CAS or migration

2020-02-16 Thread David Gibson
On Fri, Feb 14, 2020 at 04:01:16PM +0100, Greg Kurz wrote:
> While working on getting rid of CAS reboot, I realized that we currently
> don't handle device hot unplug properly in the following situations:
> 
> 1) if the device is unplugged between boot and CAS, SLOF doesn't handle
>the even, which is a known limitation. The device hence stays around
>forever (specifically, until some other event is emitted and the guest
>eventually completes the unplug or a reboot). Until we can teach SLOF
>to correctly process the full FDT at CAS, we should trigger a CAS reboot,
>like we already do for hotplug.
> 
> 2) if the guest is migrated after the even was emitted but before the
>guest could process it, the destination is unaware of the pending
>unplug operation and doesn't remove the device when the guests
>releases it. The 'unplug_requested' field of the DRC is actually state
>that should be migrated.
> 
> Changes since v1:
>- new spapr_drc_transient() helper that covers pending plug and unplug
>  situations for both CAS and migration
>- as a mechanical consequence, fix unplug for CAS an migration in the
>  same patch

Applied to ppc-for-5.0, thanks.

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


signature.asc
Description: PGP signature


[Bug 1863508] Re: qemu-system-arm stops with SIGSEGV in helper_gvec_eq16

2020-02-16 Thread Richard Henderson
I infer from the traceback that your host does not support AVX1.

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

** Changed in: qemu
 Assignee: (unassigned) => Richard Henderson (rth)

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

Title:
  qemu-system-arm stops with SIGSEGV in helper_gvec_eq16

Status in QEMU:
  In Progress

Bug description:
  Segmentation fault when trying to start FreeBSD-arm system with qemu-
  system-arm (version 4.1.1 on Fedora 31)

  Commandline:
  gdb -q --args /bin/qemu-system-arm \
   -name FreeBSD12,debug-threads=on \
   -m 1536 -machine virt -smp 2 \
   -M virt,highmem=off -serial mon:stdio -monitor telnet::45452,server,nowait \
   -machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2 \
   -overcommit mem-lock=off -no-reboot -device virtio-rng-device \
   -bios u-boot-qemu.bin \
   -drive 
file=FreeBSD-12.1-RELEASE-arm-armv7-CUBIEBOARD2.img,if=none,id=drive0,format=raw
 \
   -device ich9-ahci,id=ahci -device ide-drive,drive=drive0,bus=ahci.0 

  Results:
  
  Mounting local filesystems:.

  Thread 4 "CPU 1/TCG" received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0x7fffcedfe700 (LWP 53608)]
  0x558d9332 in helper_gvec_eq16 (d=0x566748d8, a=0x566748e0, 
b=0x566748d0, desc=0) at 
/usr/src/debug/qemu-4.1.1-1.fc31.x86_64/accel/tcg/tcg-runtime-gvec.c:948
  948 DO_CMP2(16)

  Tested different versions of qemu. qemu-3.0.1 worked, but qemu-3.1.1
  failed with the same error.

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



[Bug 1863508] Re: qemu-system-arm stops with SIGSEGV in helper_gvec_eq16

2020-02-16 Thread Richard Henderson
** 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/1863508

Title:
  qemu-system-arm stops with SIGSEGV in helper_gvec_eq16

Status in QEMU:
  In Progress

Bug description:
  Segmentation fault when trying to start FreeBSD-arm system with qemu-
  system-arm (version 4.1.1 on Fedora 31)

  Commandline:
  gdb -q --args /bin/qemu-system-arm \
   -name FreeBSD12,debug-threads=on \
   -m 1536 -machine virt -smp 2 \
   -M virt,highmem=off -serial mon:stdio -monitor telnet::45452,server,nowait \
   -machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2 \
   -overcommit mem-lock=off -no-reboot -device virtio-rng-device \
   -bios u-boot-qemu.bin \
   -drive 
file=FreeBSD-12.1-RELEASE-arm-armv7-CUBIEBOARD2.img,if=none,id=drive0,format=raw
 \
   -device ich9-ahci,id=ahci -device ide-drive,drive=drive0,bus=ahci.0 

  Results:
  
  Mounting local filesystems:.

  Thread 4 "CPU 1/TCG" received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0x7fffcedfe700 (LWP 53608)]
  0x558d9332 in helper_gvec_eq16 (d=0x566748d8, a=0x566748e0, 
b=0x566748d0, desc=0) at 
/usr/src/debug/qemu-4.1.1-1.fc31.x86_64/accel/tcg/tcg-runtime-gvec.c:948
  948 DO_CMP2(16)

  Tested different versions of qemu. qemu-3.0.1 worked, but qemu-3.1.1
  failed with the same error.

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



Re: [PATCH v3 1/2] target/arm: Support SError injection

2020-02-16 Thread Gavin Shan

On 2/16/20 2:41 PM, Richard Henderson wrote:

On 2/13/20 9:59 PM, Gavin Shan wrote:

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index b0762a76c4..180e29fb83 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -78,7 +78,7 @@ static bool arm_cpu_has_work(CPUState *cs)
  && cs->interrupt_request &
  (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
   | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ
- | CPU_INTERRUPT_EXITTB);
+ | ARM_CPU_SERROR | CPU_INTERRUPT_EXITTB);


CPU_INTERRUPT_SERROR, not ARM_CPU_SERROR.



Yep, will be corrected in v4.


@@ -570,6 +573,16 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
  goto found;
  }
  }
+
+if (interrupt_request & CPU_INTERRUPT_SERROR) {
+excp_idx = EXCP_SERROR;
+target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
+if (arm_excp_unmasked(cs, excp_idx, target_el,
+  cur_el, secure, hcr_el2)) {
+goto found;
+}
+}
+
  return false;
  
   found:


If you're intending to use Serror for NMI, perhaps it should be the first bit
tested, not the last.  Otherwise some bug that leaves a normal hard interrupt
line high will keep delivering the interrupt, and not the Serror.

As the comment at the top of the function says, the priority is implementation
defined, so we can put it anywhere we like.



Yes, SError will have highest priority in v4.


@@ -594,13 +607,26 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
   * (which depends on state like BASEPRI, FAULTMASK and the
   * currently active exception).
   */
-if (interrupt_request & CPU_INTERRUPT_HARD
-&& (armv7m_nvic_can_take_pending_exception(env->nvic))) {
-cs->exception_index = EXCP_IRQ;
-cc->do_interrupt(cs);
-ret = true;
+if (!armv7m_nvic_can_take_pending_exception(env->nvic)) {
+return false;
+}
+
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+excp_idx = EXCP_IRQ;
+goto found;
  }
-return ret;
+
+if (interrupt_request & CPU_INTERRUPT_SERROR) {
+excp_idx = EXCP_SERROR;
+goto found;
+}


Likewise.



Thanks, SError will have highest priority in v4.


-qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 4);
+qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 5);
  } else {
-qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 4);
+qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 5);


I wonder if we should have an ARM_CPU_NUM_IRQ define so that this is more
automatic.



Yes, It makes sense. ARM_CPU_NUM_IRQ will be introduced in v4.


@@ -98,10 +100,11 @@ enum {
  #endif
  
  /* Meanings of the ARMCPU object's four inbound GPIO lines */

-#define ARM_CPU_IRQ 0
-#define ARM_CPU_FIQ 1
-#define ARM_CPU_VIRQ 2
-#define ARM_CPU_VFIQ 3
+#define ARM_CPU_IRQ0
+#define ARM_CPU_FIQ1
+#define ARM_CPU_VIRQ   2
+#define ARM_CPU_VFIQ   3
+#define ARM_CPU_SERROR 4


Comment is now wrong about the count.



Yes, It will be corrected to "ARMCPU object's inbound GPIO lines" in v4.

Thanks,
Gavin




[Bug 1863526] [NEW] NVIC CCR register not 8-bit accessible using Cortex-M4

2020-02-16 Thread Philippe Mathieu-Daudé
Public bug reported:

Head at commit b29c3e23f64938.

Running with '-d unimp,guest_errors -trace nvic\*' I get:

8871@1581892794.295746:nvic_sysreg_read NVIC sysreg read addr 0xd88 data 
0xf0 size 4
8871@1581892794.295752:nvic_sysreg_write NVIC sysreg write addr 0xd88 data 
0xf0 size 4
8871@1581892794.297780:nvic_sysreg_write NVIC sysreg write addr 0xd08 data 
0x4200 size 4
8871@1581892794.298040:nvic_sysreg_write NVIC sysreg write addr 0xd15 data 0x0 
size 1
NVIC: Bad write of size 1 at offset 0xd15
8871@1581892794.298081:nvic_sysreg_write NVIC sysreg write addr 0xd16 data 0x0 
size 1
NVIC: Bad write of size 1 at offset 0xd16
8871@1581892794.298116:nvic_sysreg_write NVIC sysreg write addr 0xd17 data 0x0 
size 1
NVIC: Bad write of size 1 at offset 0xd17
8871@1581892794.298156:nvic_sysreg_write NVIC sysreg write addr 0xd18 data 0x0 
size 1
8871@1581892794.298161:nvic_set_prio NVIC set irq 4 secure-bank 0 priority 0
8871@1581892794.298164:nvic_recompute_state NVIC state recomputed: vectpending 
0 vectpending_prio 256 exception_prio 256
8871@1581892794.298168:nvic_irq_update NVIC vectpending 0 pending prio 256 
exception_prio 256: setting irq line to 0
8871@1581892794.298201:nvic_sysreg_write NVIC sysreg write addr 0xd19 data 0x0 
size 1
8871@1581892794.298206:nvic_set_prio NVIC set irq 5 secure-bank 0 priority 0

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: arm nvic

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

Title:
  NVIC CCR register not 8-bit accessible using Cortex-M4

Status in QEMU:
  New

Bug description:
  Head at commit b29c3e23f64938.

  Running with '-d unimp,guest_errors -trace nvic\*' I get:

  8871@1581892794.295746:nvic_sysreg_read NVIC sysreg read addr 0xd88 data 
0xf0 size 4
  8871@1581892794.295752:nvic_sysreg_write NVIC sysreg write addr 0xd88 data 
0xf0 size 4
  8871@1581892794.297780:nvic_sysreg_write NVIC sysreg write addr 0xd08 data 
0x4200 size 4
  8871@1581892794.298040:nvic_sysreg_write NVIC sysreg write addr 0xd15 data 
0x0 size 1
  NVIC: Bad write of size 1 at offset 0xd15
  8871@1581892794.298081:nvic_sysreg_write NVIC sysreg write addr 0xd16 data 
0x0 size 1
  NVIC: Bad write of size 1 at offset 0xd16
  8871@1581892794.298116:nvic_sysreg_write NVIC sysreg write addr 0xd17 data 
0x0 size 1
  NVIC: Bad write of size 1 at offset 0xd17
  8871@1581892794.298156:nvic_sysreg_write NVIC sysreg write addr 0xd18 data 
0x0 size 1
  8871@1581892794.298161:nvic_set_prio NVIC set irq 4 secure-bank 0 priority 0
  8871@1581892794.298164:nvic_recompute_state NVIC state recomputed: 
vectpending 0 vectpending_prio 256 exception_prio 256
  8871@1581892794.298168:nvic_irq_update NVIC vectpending 0 pending prio 256 
exception_prio 256: setting irq line to 0
  8871@1581892794.298201:nvic_sysreg_write NVIC sysreg write addr 0xd19 data 
0x0 size 1
  8871@1581892794.298206:nvic_set_prio NVIC set irq 5 secure-bank 0 priority 0

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



[Bug 1863526] Re: NVIC CCR register not 8-bit accessible using Cortex-M4

2020-02-16 Thread Philippe Mathieu-Daudé
I am not sure this register can not be accessed differently than 32-bit.
Still I used this patch as a kludge, but it doesn't seem a clean fix:

-- >8 --
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2160,6 +2161,10 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr 
addr,
 }
 }
 break;
+case 0xd14 ... 0xd17: /* Configuration and Control Register */
+val = extract32(nvic_readl(s, offset & ~3, attrs),
+(offset - 0xd14) * 8, size * 8);
+break;
 case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
 if (!arm_feature(>cpu->env, ARM_FEATURE_M_MAIN)) {
 val = 0;
@@ -2282,6 +2287,11 @@ static MemTxResult nvic_sysreg_write(void *opaque, 
hwaddr addr,
 }
 nvic_irq_update(s);
 goto exit_ok;
+case 0xd14 ... 0xd17: /* Configuration and Control Register */
+value = deposit32(value, (offset - 0xd14) * 8, size * 8,
+  nvic_readl(s, offset & ~3, attrs));
+nvic_writel(s, offset & ~3, value, attrs);
+goto exit_ok;
 case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
 if (!arm_feature(>cpu->env, ARM_FEATURE_M_MAIN)) {
 goto exit_ok;
---

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

Title:
  NVIC CCR register not 8-bit accessible using Cortex-M4

Status in QEMU:
  New

Bug description:
  Head at commit b29c3e23f64938.

  Running with '-d unimp,guest_errors -trace nvic\*' I get:

  8871@1581892794.295746:nvic_sysreg_read NVIC sysreg read addr 0xd88 data 
0xf0 size 4
  8871@1581892794.295752:nvic_sysreg_write NVIC sysreg write addr 0xd88 data 
0xf0 size 4
  8871@1581892794.297780:nvic_sysreg_write NVIC sysreg write addr 0xd08 data 
0x4200 size 4
  8871@1581892794.298040:nvic_sysreg_write NVIC sysreg write addr 0xd15 data 
0x0 size 1
  NVIC: Bad write of size 1 at offset 0xd15
  8871@1581892794.298081:nvic_sysreg_write NVIC sysreg write addr 0xd16 data 
0x0 size 1
  NVIC: Bad write of size 1 at offset 0xd16
  8871@1581892794.298116:nvic_sysreg_write NVIC sysreg write addr 0xd17 data 
0x0 size 1
  NVIC: Bad write of size 1 at offset 0xd17
  8871@1581892794.298156:nvic_sysreg_write NVIC sysreg write addr 0xd18 data 
0x0 size 1
  8871@1581892794.298161:nvic_set_prio NVIC set irq 4 secure-bank 0 priority 0
  8871@1581892794.298164:nvic_recompute_state NVIC state recomputed: 
vectpending 0 vectpending_prio 256 exception_prio 256
  8871@1581892794.298168:nvic_irq_update NVIC vectpending 0 pending prio 256 
exception_prio 256: setting irq line to 0
  8871@1581892794.298201:nvic_sysreg_write NVIC sysreg write addr 0xd19 data 
0x0 size 1
  8871@1581892794.298206:nvic_set_prio NVIC set irq 5 secure-bank 0 priority 0

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



Re: [PATCH] MAINTAINERS: Orphan MIPS KVM CPUs

2020-02-16 Thread James Hogan
On Sun, Feb 16, 2020 at 05:33:44PM +0100, Aleksandar Markovic wrote:
> OK, I will add the patch in the next MIPS queue, since I think its
> significance is more than trivial. It will be sent no later than two weeks
> from now.

Thanks Aleksandar.

> I just wanted the patch to be in the same queue when we will
> provide replacement. But, honestly, if the factual state lasted that long,
> I don't see the reason for such sudden hurry, do you?

Yes.

My main reasons for not wanting this dragged out any longer are:

1) Personally, I just want to let go of it now, and that's slightly
   harder to do when I'm still keeping an eye on whether this patch is
   merged yet, or worse, waiting for Wave to act.

2) In principle it feels wrong to delay a maintainer's name being
   removed at their own request (even if it came late!) for an
   indeterminate amount of time. This patch simply shouldn't be blocked
   waiting for Wave to make a decision I've been waiting to see if it
   would make for too long already.

3) Maybe publicly recognising the orphaned state might motivate Wave or
   others to step up and take a lead with further development.

> Of course I respect James' decision, although I am trully sorry about it.
> My only slight objection is that James should have sent this patch sooner,
> rather than just leave an impression that there is a maintainer, while in
> fact there wasn't. What did you wait?

LOL, well I doubt MIPS (as a company) was under any illusion since they
pulled the trigger :-P

Seriously though, I intended to keep an eye on things in my own time
(both on kernel & QEMU side) and just be ready to answer questions and
hand over the reigns if/when somebody from Wave got up to speed. I was
probably also wary of making MIPS look bad for closing their UK
operation (again) and "orphaning" my code (that I was probably too
emotionally invested in, LOL!).

In practice Paul took care of the MIPS arch stuff and there was
virtually no activity on the MIPS KVM front from Wave so real life
mostly pushed it off my radar. I did discuss orphaning it with Paul last
year but there was mention of Wave folk getting up to speed with it so I
held off for a bit longer.

Anyway FWIW I'm sorry for any confusion caused by my hesitation.

> But, never mind, I understand your
> hesitation. The best outcome would be that James remained in that role (I
> do remember him as an excellent, thorough engineer, that is approachable
> and very helpful to others), but what can we do now. I wish we work
> together in future, who knows? Thanks, James, for taking care of KVM for
> MIPS for number of years!

Thanks, my pleasure.

Cheers
James



Re: [PATCH 0/2] Small clean up in target/ppc/cpu.h

2020-02-16 Thread David Gibson
On Sun, Feb 16, 2020 at 10:33:54PM +0100, BALATON Zoltan wrote:
> Just some small clean ups to improve readability of struct CPUPPCState.

Applied to ppc-for-5.0, thanks.

> BALATON Zoltan (2):
>   target/ppc/cpu.h: Move fpu related members closer in cpu env
>   target/ppc/cpu.h: Clean up comments in the struct CPUPPCState
> definition
> 
>  target/ppc/cpu.h | 146 ++-
>  1 file changed, 54 insertions(+), 92 deletions(-)
> 

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


signature.asc
Description: PGP signature


Re: [PATCH v2 0/4] target/arm vector improvements

2020-02-16 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200216214232.4230-1-richard.hender...@linaro.org/



Hi,

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

Subject: [PATCH v2 0/4] target/arm vector improvements
Message-id: 20200216214232.4230-1-richard.hender...@linaro.org
Type: series

=== 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 ===

From https://github.com/patchew-project/qemu
 * [new tag] patchew/20200216214232.4230-1-richard.hender...@linaro.org 
-> patchew/20200216214232.4230-1-richard.hender...@linaro.org
Switched to a new branch 'test'
2236552 target/arm: Convert PMULL.8 to gvec
8892524 target/arm: Convert PMULL.64 to gvec
a438d40 target/arm: Convert PMUL.8 to gvec
39164de target/arm: Vectorize USHL and SSHL

=== OUTPUT BEGIN ===
1/4 Checking commit 39164de944d5 (target/arm: Vectorize USHL and SSHL)
ERROR: trailing statements should be on next line
#161: FILE: target/arm/translate.c:3578:
+case 2: gen_ushl_i32(var, var, shift); break;

ERROR: trailing statements should be on next line
#168: FILE: target/arm/translate.c:3584:
+case 2: gen_sshl_i32(var, var, shift); break;

total: 2 errors, 0 warnings, 569 lines checked

Patch 1/4 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

2/4 Checking commit a438d4012b70 (target/arm: Convert PMUL.8 to gvec)
3/4 Checking commit 889252410254 (target/arm: Convert PMULL.64 to gvec)
4/4 Checking commit 2236552a4b44 (target/arm: Convert PMULL.8 to gvec)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20200216214232.4230-1-richard.hender...@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH v3] Implement the Screamer sound chip for the mac99 machine type

2020-02-16 Thread BALATON Zoltan

On Sun, 16 Feb 2020, Howard Spoelstra wrote:

On Sun, Feb 16, 2020 at 5:32 PM John Arbuckle 
wrote:

diff --git a/hw/audio/screamer.c b/hw/audio/screamer.c
new file mode 100644
index 00..ad4aba12eb
--- /dev/null
+++ b/hw/audio/screamer.c
@@ -0,0 +1,983 @@
+/*
+ * File: Screamer.c
+ * Description: Implement the Screamer sound chip used in Apple
Macintoshes.
+ * It works by filling a buffer, then playing the buffer.
+ */


Do you need a copyright and license header here? Especially if this is not 
all your original work but based on previous code (don't know if it is 
just saying in case as I know Mark also had some similar patches before 
but not sure how are those related if at all). If this contains code from 
somewhere else then license and author of that code may need to be 
included too.



+/* Called when the CPU writes to the memory addresses assigned to
Screamer */
+static void screamer_mmio_write(void *opaque, hwaddr addr, uint64_t
raw_value,
+unsigned size)
+{
+DPRINTF("screamer_mmio_write() called - size: %d\n", size);
+ScreamerState *state = opaque;
+uint32_t value = raw_value & 0x;
+addr = addr >> 4;
+
+switch (addr) {
+case SOUND_CONTROL_REG:
+set_sound_control_reg(state, value);
+break;
+case CODEC_CONTROL_REG:
+set_codec_control_reg(state, value);
+break;
+case CODEC_STATUS_REG:
+set_codec_status_reg(state, value);
+break;
+case CLIP_COUNT_REG:
+set_clip_count_reg(state, value);
+break;
+case BYTE_SWAP_REG:
+set_byte_swap_reg(state, value);
+break;
+case FRAME_COUNT_REG:
+set_frame_count_reg(state, value);
+break;
+default:
+DPRINTF("Unknown register write - addr:%llu\tvalue:%d\n", addr,
value);
+}
+}

Hi,


This patch will not compile without errors. Host is Fedora 31.
The compiler suggests changing lines 839, 842 and 878 in screamer.c so the
DPRINTF arguments use %lu instead of %llu.
With that fixed, compiling completes succesfully.


Replacing with %lu may fix 32bit build but would break 64bit one. Use 
HWADDR_PRIx format string instead to print hwaddr but others will probably 
tell to remove DPRINTFs alltogether when they are not needed any more and 
replace the remaining few useful ones with traces if debugging is still 
needed. I don't mind DPRINTFs that much at least until things are stable 
enough but once the code is stable most DPRINTFs may not be needed any 
more.


I can't really review the actual patch because I don't know audio in QEMU.

Regards,
BALATON Zoltan



Re: [PATCH 4/7] commit: Inline commit_populate()

2020-02-16 Thread Ján Tomko

On Fri, Feb 14, 2020 at 09:08:09PM +0100, Kevin Wolf wrote:

commit_populate() is a very short function and only called in a single
place. Its return value doesn't tell us whether an error happened while
reading or writing, which would be necessary for sending the right data
in the BLOCK_JOB_ERROR QMP event.

Signed-off-by: Kevin Wolf 
---
block/commit.c | 28 ++--
1 file changed, 6 insertions(+), 22 deletions(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [PATCH 6/7] commit: Expose on-error option in QMP

2020-02-16 Thread Ján Tomko

On Fri, Feb 14, 2020 at 09:08:11PM +0100, Kevin Wolf wrote:

Now that the error handling in the common block job is fixed, we can
expose the on-error option in QMP instead of hard-coding it as 'report'
in qmp_block_commit().

This fulfills the promise that the old comment in that function made,
even if a bit later than expected: "This will be part of the QMP
command, if/when the BlockdevOnError change for blkmirror makes it in".

Signed-off-by: Kevin Wolf 
---
qapi/block-core.json | 4 
blockdev.c   | 8 
2 files changed, 8 insertions(+), 4 deletions(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [PATCH 5/7] commit: Fix is_read for block_job_error_action()

2020-02-16 Thread Ján Tomko

On Fri, Feb 14, 2020 at 09:08:10PM +0100, Kevin Wolf wrote:

block_job_error_action() needs to know if reading from the top node or
writing to the base node failed so that it can set the right 'operation'
in the BLOCK_JOB_ERROR QMP event.

Signed-off-by: Kevin Wolf 
---
block/commit.c | 7 ++-
1 file changed, 6 insertions(+), 1 deletion(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [PATCH 1/7] qapi: Document meaning of 'ignore' BlockdevOnError for jobs

2020-02-16 Thread Ján Tomko

On Fri, Feb 14, 2020 at 09:08:06PM +0100, Kevin Wolf wrote:

It is not obvious what 'ignore' actually means for block jobs: It could
be continuing the job and returning success in the end despite the error
(no block job does this). It could also mean continuing and returning
failure in the end (this is what stream does). And it can mean retrying
the failed request later (this is what backup, commit and mirror do).

This (somewhat inconsistent) behaviour was introduced and described for
stream and mirror in commit ae586d6158. backup and commit were


fatal: ambiguous argument 'ae586d6158': unknown revision or path not in the 
working tree.


introduced later and use the same model as mirror.

Signed-off-by: Kevin Wolf 
---
qapi/block-core.json | 5 -
1 file changed, 4 insertions(+), 1 deletion(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [PATCH 2/7] commit: Remove unused bytes_written

2020-02-16 Thread Ján Tomko

On Fri, Feb 14, 2020 at 09:08:07PM +0100, Kevin Wolf wrote:

The bytes_written variable is only ever written to, it serves no
purpose. This has actually been the case since the commit job was first
introduced in commit 747ff602636.

Signed-off-by: Kevin Wolf 
---
block/commit.c | 2 --
1 file changed, 2 deletions(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [PATCH 3/7] commit: Fix argument order for block_job_error_action()

2020-02-16 Thread Ján Tomko

On Fri, Feb 14, 2020 at 09:08:08PM +0100, Kevin Wolf wrote:

The block_job_error_action() error call in the commit job gives the
on_err and is_read arguments in the wrong order. Fix this.

(Of course, hard-coded is_read = false is wrong, too, but that's a
separate problem for a separate patch.)

Signed-off-by: Kevin Wolf 
---
block/commit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


[PATCH v2 4/4] target/arm: Convert PMULL.8 to gvec

2020-02-16 Thread Richard Henderson
We still need two different helpers, since NEON and SVE2 get the
inputs from different locations within the source vector.  However,
we can convert both to the same internal form for computation.

The sve2 helper is not used yet, but adding it with this patch
helps illustrate why the neon changes are helpful.

Tested-by: Alex Bennée 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper-sve.h|  2 ++
 target/arm/helper.h|  3 +-
 target/arm/neon_helper.c   | 32 
 target/arm/translate-a64.c | 27 +++--
 target/arm/translate.c | 26 -
 target/arm/vec_helper.c| 60 ++
 6 files changed, 95 insertions(+), 55 deletions(-)

diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
index 9e79182ab4..2f47279155 100644
--- a/target/arm/helper-sve.h
+++ b/target/arm/helper-sve.h
@@ -1574,3 +1574,5 @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
 DEF_HELPER_FLAGS_6(sve_stdd_be_zd, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
+
+DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 4352fae3db..fcbf504121 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -342,7 +342,6 @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
 DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
 DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
 DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
-DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
 
 DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
 DEF_HELPER_2(neon_tst_u16, i32, i32, i32)
@@ -695,6 +694,8 @@ DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
 #include "helper-sve.h"
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
index 6a107da0e1..c7a8438b42 100644
--- a/target/arm/neon_helper.c
+++ b/target/arm/neon_helper.c
@@ -1129,38 +1129,6 @@ NEON_VOP(mul_u8, neon_u8, 4)
 NEON_VOP(mul_u16, neon_u16, 2)
 #undef NEON_FN
 
-/* Polynomial multiplication is like integer multiplication except the
-   partial products are XORed, not added.  */
-uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
-{
-uint64_t result = 0;
-uint64_t mask;
-uint64_t op2ex = op2;
-op2ex = (op2ex & 0xff) |
-((op2ex & 0xff00) << 8) |
-((op2ex & 0xff) << 16) |
-((op2ex & 0xff00) << 24);
-while (op1) {
-mask = 0;
-if (op1 & 1) {
-mask |= 0x;
-}
-if (op1 & (1 << 8)) {
-mask |= (0xU << 16);
-}
-if (op1 & (1 << 16)) {
-mask |= (0xULL << 32);
-}
-if (op1 & (1 << 24)) {
-mask |= (0xULL << 48);
-}
-result ^= op2ex & mask;
-op1 = (op1 >> 1) & 0x7f7f7f7f;
-op2ex <<= 1;
-}
-return result;
-}
-
 #define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
 NEON_VOP(tst_u8, neon_u8, 4)
 NEON_VOP(tst_u16, neon_u16, 2)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 6ce1131860..63ff042d60 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -10533,10 +10533,6 @@ static void handle_3rd_widening(DisasContext *s, int 
is_q, int is_u, int size,
 gen_helper_neon_addl_saturate_s32(tcg_passres, cpu_env,
   tcg_passres, tcg_passres);
 break;
-case 14: /* PMULL */
-assert(size == 0);
-gen_helper_neon_mull_p8(tcg_passres, tcg_op1, tcg_op2);
-break;
 default:
 g_assert_not_reached();
 }
@@ -10700,11 +10696,21 @@ static void disas_simd_three_reg_diff(DisasContext 
*s, uint32_t insn)
 handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
 break;
 case 14: /* PMULL, PMULL2 */
-if (is_u || size == 1 || size == 2) {
+if (is_u) {
 unallocated_encoding(s);
 return;
 }
-if (size == 3) {
+switch (size) {
+case 0: /* PMULL.P8 */
+if (!fp_access_check(s)) {
+return;
+}
+/* The Q field specifies lo/hi half input for this insn.  */
+gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
+ gen_helper_neon_pmull_h);
+break;
+
+case 3: /* PMULL.P64 */
 if (!dc_isar_feature(aa64_pmull, s)) {
 unallocated_encoding(s);
 return;
@@ -10715,9 +10721,13 @@ static void 

[PATCH v2 3/4] target/arm: Convert PMULL.64 to gvec

2020-02-16 Thread Richard Henderson
The gvec form will be needed for implementing SVE2.

Tested-by: Alex Bennée 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  4 +---
 target/arm/neon_helper.c   | 30 --
 target/arm/translate-a64.c | 28 +++-
 target/arm/translate.c | 16 ++--
 target/arm/vec_helper.c| 33 +
 5 files changed, 39 insertions(+), 72 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 82450a3f96..4352fae3db 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -562,9 +562,6 @@ DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, 
i32, i32)
 DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 DEF_HELPER_2(dc_zva, void, env, i64)
 
-DEF_HELPER_FLAGS_2(neon_pmull_64_lo, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(neon_pmull_64_hi, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-
 DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s16, TCG_CALL_NO_RWG,
@@ -696,6 +693,7 @@ DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
index 9e7a9a1ac5..6a107da0e1 100644
--- a/target/arm/neon_helper.c
+++ b/target/arm/neon_helper.c
@@ -2152,33 +2152,3 @@ void HELPER(neon_zip16)(void *vd, void *vm)
 rm[0] = m0;
 rd[0] = d0;
 }
-
-/* Helper function for 64 bit polynomial multiply case:
- * perform PolynomialMult(op1, op2) and return either the top or
- * bottom half of the 128 bit result.
- */
-uint64_t HELPER(neon_pmull_64_lo)(uint64_t op1, uint64_t op2)
-{
-int bitnum;
-uint64_t res = 0;
-
-for (bitnum = 0; bitnum < 64; bitnum++) {
-if (op1 & (1ULL << bitnum)) {
-res ^= op2 << bitnum;
-}
-}
-return res;
-}
-uint64_t HELPER(neon_pmull_64_hi)(uint64_t op1, uint64_t op2)
-{
-int bitnum;
-uint64_t res = 0;
-
-/* bit 0 of op1 can't influence the high 64 bits at all */
-for (bitnum = 1; bitnum < 64; bitnum++) {
-if (op1 & (1ULL << bitnum)) {
-res ^= op2 >> (64 - bitnum);
-}
-}
-return res;
-}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c96ed28f9d..6ce1131860 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -10648,30 +10648,6 @@ static void handle_3rd_narrowing(DisasContext *s, int 
is_q, int is_u, int size,
 clear_vec_high(s, is_q, rd);
 }
 
-static void handle_pmull_64(DisasContext *s, int is_q, int rd, int rn, int rm)
-{
-/* PMULL of 64 x 64 -> 128 is an odd special case because it
- * is the only three-reg-diff instruction which produces a
- * 128-bit wide result from a single operation. However since
- * it's possible to calculate the two halves more or less
- * separately we just use two helper calls.
- */
-TCGv_i64 tcg_op1 = tcg_temp_new_i64();
-TCGv_i64 tcg_op2 = tcg_temp_new_i64();
-TCGv_i64 tcg_res = tcg_temp_new_i64();
-
-read_vec_element(s, tcg_op1, rn, is_q, MO_64);
-read_vec_element(s, tcg_op2, rm, is_q, MO_64);
-gen_helper_neon_pmull_64_lo(tcg_res, tcg_op1, tcg_op2);
-write_vec_element(s, tcg_res, rd, 0, MO_64);
-gen_helper_neon_pmull_64_hi(tcg_res, tcg_op1, tcg_op2);
-write_vec_element(s, tcg_res, rd, 1, MO_64);
-
-tcg_temp_free_i64(tcg_op1);
-tcg_temp_free_i64(tcg_op2);
-tcg_temp_free_i64(tcg_res);
-}
-
 /* AdvSIMD three different
  *   31  30  29 28   24 23  22  21 20  16 1512 11 10 95 40
  * +---+---+---+---+--+---+--++-+--+--+
@@ -10736,7 +10712,9 @@ static void disas_simd_three_reg_diff(DisasContext *s, 
uint32_t insn)
 if (!fp_access_check(s)) {
 return;
 }
-handle_pmull_64(s, is_q, rd, rn, rm);
+/* The Q field specifies lo/hi half input for this insn.  */
+gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
+ gen_helper_gvec_pmull_q);
 return;
 }
 goto is_widening;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 4581373e31..e2dbafa161 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5870,23 +5870,11 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
  * outside the loop below as it only performs a single pass.
  */
 if (op == 14 && size == 2) {
-TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
-
 if (!dc_isar_feature(aa32_pmull, s)) {
  

[PATCH v2 1/4] target/arm: Vectorize USHL and SSHL

2020-02-16 Thread Richard Henderson
These instructions shift left or right depending on the sign
of the input, and 7 bits are significant to the shift.  This
requires several masks and selects in addition to the actual
shifts to form the complete answer.

That said, the operation is still a small improvement even for
two 64-bit elements -- 13 vector operations instead of 2 * 7
integer operations.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
v2: Fix operand ordering for aa32 VSHL.
v3: Rename operand for inline tcg expanders (ajb).
---
 target/arm/helper.h|  11 +-
 target/arm/translate.h |   6 +
 target/arm/neon_helper.c   |  33 
 target/arm/translate-a64.c |  18 +--
 target/arm/translate.c | 299 +++--
 target/arm/vec_helper.c|  88 +++
 6 files changed, 389 insertions(+), 66 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index aa3d8cd08f..459a278b5c 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -303,14 +303,8 @@ DEF_HELPER_2(neon_abd_s16, i32, i32, i32)
 DEF_HELPER_2(neon_abd_u32, i32, i32, i32)
 DEF_HELPER_2(neon_abd_s32, i32, i32, i32)
 
-DEF_HELPER_2(neon_shl_u8, i32, i32, i32)
-DEF_HELPER_2(neon_shl_s8, i32, i32, i32)
 DEF_HELPER_2(neon_shl_u16, i32, i32, i32)
 DEF_HELPER_2(neon_shl_s16, i32, i32, i32)
-DEF_HELPER_2(neon_shl_u32, i32, i32, i32)
-DEF_HELPER_2(neon_shl_s32, i32, i32, i32)
-DEF_HELPER_2(neon_shl_u64, i64, i64, i64)
-DEF_HELPER_2(neon_shl_s64, i64, i64, i64)
 DEF_HELPER_2(neon_rshl_u8, i32, i32, i32)
 DEF_HELPER_2(neon_rshl_s8, i32, i32, i32)
 DEF_HELPER_2(neon_rshl_u16, i32, i32, i32)
@@ -697,6 +691,11 @@ DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, 
ptr)
 DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
 DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
 
+DEF_HELPER_FLAGS_4(gvec_sshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
 #include "helper-sve.h"
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 5b167c416a..d9ea0c99cc 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -278,6 +278,8 @@ uint64_t vfp_expand_imm(int size, uint8_t imm8);
 extern const GVecGen3 mla_op[4];
 extern const GVecGen3 mls_op[4];
 extern const GVecGen3 cmtst_op[4];
+extern const GVecGen3 sshl_op[4];
+extern const GVecGen3 ushl_op[4];
 extern const GVecGen2i ssra_op[4];
 extern const GVecGen2i usra_op[4];
 extern const GVecGen2i sri_op[4];
@@ -287,6 +289,10 @@ extern const GVecGen4 sqadd_op[4];
 extern const GVecGen4 uqsub_op[4];
 extern const GVecGen4 sqsub_op[4];
 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
+void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
+void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
+void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
+void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 
 /*
  * Forward to the isar_feature_* tests given a DisasContext pointer.
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
index 4259056723..c581ffb7d3 100644
--- a/target/arm/neon_helper.c
+++ b/target/arm/neon_helper.c
@@ -615,24 +615,9 @@ NEON_VOP(abd_u32, neon_u32, 1)
 } else { \
 dest = src1 << tmp; \
 }} while (0)
-NEON_VOP(shl_u8, neon_u8, 4)
 NEON_VOP(shl_u16, neon_u16, 2)
-NEON_VOP(shl_u32, neon_u32, 1)
 #undef NEON_FN
 
-uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
-{
-int8_t shift = (int8_t)shiftop;
-if (shift >= 64 || shift <= -64) {
-val = 0;
-} else if (shift < 0) {
-val >>= -shift;
-} else {
-val <<= shift;
-}
-return val;
-}
-
 #define NEON_FN(dest, src1, src2) do { \
 int8_t tmp; \
 tmp = (int8_t)src2; \
@@ -645,27 +630,9 @@ uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t 
shiftop)
 } else { \
 dest = src1 << tmp; \
 }} while (0)
-NEON_VOP(shl_s8, neon_s8, 4)
 NEON_VOP(shl_s16, neon_s16, 2)
-NEON_VOP(shl_s32, neon_s32, 1)
 #undef NEON_FN
 
-uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop)
-{
-int8_t shift = (int8_t)shiftop;
-int64_t val = valop;
-if (shift >= 64) {
-val = 0;
-} else if (shift <= -64) {
-val >>= 63;
-} else if (shift < 0) {
-val >>= -shift;
-} else {
-val <<= shift;
-}
-return val;
-}
-
 #define NEON_FN(dest, src1, src2) do { \
 int8_t tmp; \
 tmp = (int8_t)src2; \
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 7c26c3bfeb..e42dcfebdd 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -8735,9 +8735,9 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 break;
 case 0x8: /* SSHL, USHL */
 if (u) {
-

[PATCH v2 0/4] target/arm vector improvements

2020-02-16 Thread Richard Henderson
Changes for v2:

* Rename function arguments as requested by ajb.
* Minor optimization in helper_gvec_pmul_b.

Original blurb:

The first patch has been seen before.

  https://patchwork.ozlabs.org/patch/1115039/

It had a bug and I didn't fix it right away and then forgot.
Fixed now; I had mixed up the operand ordering for aarch32.

The next 3 are something that I noticed while doing other stuff.

In particular, pmull is used heavily during https transfers.
While cloning a repository, the old code peaks at 27% of the
total runtime, as measured by perf top.  The new code does
not quite reach 3% repeating the same clone.

In addition, the new helper functions are in the form that
will be required for the implementation of SVE2.


r~

Richard Henderson (4):
  target/arm: Vectorize USHL and SSHL
  target/arm: Convert PMUL.8 to gvec
  target/arm: Convert PMULL.64 to gvec
  target/arm: Convert PMULL.8 to gvec

 target/arm/helper-sve.h|   2 +
 target/arm/helper.h|  21 ++-
 target/arm/translate.h |   6 +
 target/arm/neon_helper.c   | 117 -
 target/arm/translate-a64.c |  83 -
 target/arm/translate.c | 348 -
 target/arm/vec_helper.c| 211 ++
 7 files changed, 560 insertions(+), 228 deletions(-)

-- 
2.20.1




[PATCH v2 2/4] target/arm: Convert PMUL.8 to gvec

2020-02-16 Thread Richard Henderson
The gvec form will be needed for implementing SVE2.

Extend the implementation to operate on uint64_t instead of uint32_t.
Use a counted inner loop instead of terminating when op1 goes to zero,
looking toward the required implementation for ARMv8.4-DIT.

Tested-by: Alex Bennée 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
v3: Elide mask after right-shift on N, as we already do N & 1
at the top of the loop.
---
 target/arm/helper.h|  3 ++-
 target/arm/neon_helper.c   | 22 --
 target/arm/translate-a64.c | 10 +++---
 target/arm/translate.c | 11 ---
 target/arm/vec_helper.c| 30 ++
 5 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 459a278b5c..82450a3f96 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -342,7 +342,6 @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
 DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
 DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
 DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
-DEF_HELPER_2(neon_mul_p8, i32, i32, i32)
 DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
 
 DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
@@ -696,6 +695,8 @@ DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_4(gvec_pmul_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
 #include "helper-sve.h"
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
index c581ffb7d3..9e7a9a1ac5 100644
--- a/target/arm/neon_helper.c
+++ b/target/arm/neon_helper.c
@@ -1131,28 +1131,6 @@ NEON_VOP(mul_u16, neon_u16, 2)
 
 /* Polynomial multiplication is like integer multiplication except the
partial products are XORed, not added.  */
-uint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2)
-{
-uint32_t mask;
-uint32_t result;
-result = 0;
-while (op1) {
-mask = 0;
-if (op1 & 1)
-mask |= 0xff;
-if (op1 & (1 << 8))
-mask |= (0xff << 8);
-if (op1 & (1 << 16))
-mask |= (0xff << 16);
-if (op1 & (1 << 24))
-mask |= (0xff << 24);
-result ^= op2 & mask;
-op1 = (op1 >> 1) & 0x7f7f7f7f;
-op2 = (op2 << 1) & 0xfefefefe;
-}
-return result;
-}
-
 uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
 {
 uint64_t result = 0;
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index e42dcfebdd..c96ed28f9d 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11160,9 +11160,10 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 case 0x13: /* MUL, PMUL */
 if (!u) { /* MUL */
 gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
-return;
+} else {  /* PMUL */
+gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0, gen_helper_gvec_pmul_b);
 }
-break;
+return;
 case 0x12: /* MLA, MLS */
 if (u) {
 gen_gvec_op3(s, is_q, rd, rn, rm, _op[size]);
@@ -11292,11 +11293,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 genfn = fns[size][u];
 break;
 }
-case 0x13: /* MUL, PMUL */
-assert(u); /* PMUL */
-assert(size == 0);
-genfn = gen_helper_neon_mul_p8;
-break;
 case 0x16: /* SQDMULH, SQRDMULH */
 {
 static NeonGenTwoOpEnvFn * const fns[2][2] = {
diff --git a/target/arm/translate.c b/target/arm/translate.c
index c4dd14e053..4581373e31 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5007,16 +5007,17 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 
 case NEON_3R_VMUL: /* VMUL */
 if (u) {
-/* Polynomial case allows only P8 and is handled below.  */
+/* Polynomial case allows only P8.  */
 if (size != 0) {
 return 1;
 }
+tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
+   0, gen_helper_gvec_pmul_b);
 } else {
 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
  vec_size, vec_size);
-return 0;
 }
-break;
+return 0;
 
 case NEON_3R_VML: /* VMLA, VMLS */
 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
@@ -5206,10 +5207,6 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 tmp2 = neon_load_reg(rd, pass);
 gen_neon_add(size, tmp, tmp2);
 break;
-case NEON_3R_VMUL:
-/* VMUL.P8; other 

[PATCH 0/2] Small clean up in target/ppc/cpu.h

2020-02-16 Thread BALATON Zoltan
Just some small clean ups to improve readability of struct CPUPPCState.

BALATON Zoltan (2):
  target/ppc/cpu.h: Move fpu related members closer in cpu env
  target/ppc/cpu.h: Clean up comments in the struct CPUPPCState
definition

 target/ppc/cpu.h | 146 ++-
 1 file changed, 54 insertions(+), 92 deletions(-)

-- 
2.21.1




[PATCH 2/2] target/ppc/cpu.h: Clean up comments in the struct CPUPPCState definition

2020-02-16 Thread BALATON Zoltan
The cpu env struct is quite complex but comments supposed to explain
it in its definition just make it harder to read. Reformat and reword
some comments to make it clearer and more readable.

Signed-off-by: BALATON Zoltan 
---
 target/ppc/cpu.h | 145 ++-
 1 file changed, 54 insertions(+), 91 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index c3b0a00064..b283042515 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -960,116 +960,88 @@ struct ppc_radix_page_info {
 #define PPC_CPU_INDIRECT_OPCODES_LEN 0x20
 
 struct CPUPPCState {
-/*
- * First are the most commonly used resources during translated
- * code execution
- */
-/* general purpose registers */
-target_ulong gpr[32];
-/* Storage for GPR MSB, used by the SPE extension */
-target_ulong gprh[32];
-/* LR */
+/* Most commonly used resources during translated code execution first */
+target_ulong gpr[32];  /* general purpose registers */
+target_ulong gprh[32]; /* storage for GPR MSB, used by the SPE extension */
 target_ulong lr;
-/* CTR */
 target_ulong ctr;
-/* condition register */
-uint32_t crf[8];
+uint32_t crf[8];   /* condition register */
 #if defined(TARGET_PPC64)
-/* CFAR */
 target_ulong cfar;
 #endif
-/* XER (with SO, OV, CA split out) */
-target_ulong xer;
+target_ulong xer;  /* XER (with SO, OV, CA split out) */
 target_ulong so;
 target_ulong ov;
 target_ulong ca;
 target_ulong ov32;
 target_ulong ca32;
-/* Reservation address */
-target_ulong reserve_addr;
-/* Reservation value */
-target_ulong reserve_val;
-target_ulong reserve_val2;
 
-/* Those ones are used in supervisor mode only */
-/* machine state register */
-target_ulong msr;
-/* temporary general purpose registers */
-target_ulong tgpr[4]; /* Used to speed-up TLB assist handlers */
+target_ulong reserve_addr; /* Reservation address */
+target_ulong reserve_val;  /* Reservation value */
+target_ulong reserve_val2;
 
-/* Next instruction pointer */
-target_ulong nip;
+/* These are used in supervisor mode only */
+target_ulong msr;  /* machine state register */
+target_ulong tgpr[4];  /* temporary general purpose registers, */
+   /* used to speed-up TLB assist handlers */
 
-/* High part of 128-bit helper return.  */
-uint64_t retxh;
+target_ulong nip;  /* next instruction pointer */
+uint64_t retxh;/* high part of 128-bit helper return */
 
 /* when a memory exception occurs, the access type is stored here */
 int access_type;
 
-/* MMU context - only relevant for full system emulation */
 #if !defined(CONFIG_USER_ONLY)
+/* MMU context, only relevant for full system emulation */
 #if defined(TARGET_PPC64)
-/* PowerPC 64 SLB area */
-ppc_slb_t slb[MAX_SLB_ENTRIES];
-/* tcg TLB needs flush (deferred slb inval instruction typically) */
+ppc_slb_t slb[MAX_SLB_ENTRIES]; /* PowerPC 64 SLB area */
 #endif
-/* segment registers */
-target_ulong sr[32];
-/* BATs */
-uint32_t nb_BATs;
+target_ulong sr[32];   /* segment registers */
+uint32_t nb_BATs;  /* number of BATs */
 target_ulong DBAT[2][8];
 target_ulong IBAT[2][8];
 /* PowerPC TLB registers (for 4xx, e500 and 60x software driven TLBs) */
-int32_t nb_tlb;  /* Total number of TLB  */
+int32_t nb_tlb;  /* Total number of TLB */
 int tlb_per_way; /* Speed-up helper: used to avoid divisions at run time */
-int nb_ways; /* Number of ways in the TLB set*/
-int last_way;/* Last used way used to allocate TLB in a LRU way  */
+int nb_ways; /* Number of ways in the TLB set */
+int last_way;/* Last used way used to allocate TLB in a LRU way */
 int id_tlbs; /* If 1, MMU has separated TLBs for instructions & data */
-int nb_pids; /* Number of available PID registers*/
-int tlb_type;/* Type of TLB we're dealing with   */
-ppc_tlb_t tlb;   /* TLB is optional. Allocate them only if needed*/
-/* 403 dedicated access protection registers */
-target_ulong pb[4];
-bool tlb_dirty;   /* Set to non-zero when modifying TLB  */
-bool kvm_sw_tlb;  /* non-zero if KVM SW TLB API is active*/
+int nb_pids; /* Number of available PID registers */
+int tlb_type;/* Type of TLB we're dealing with */
+ppc_tlb_t tlb;   /* TLB is optional. Allocate them only if needed */
+target_ulong pb[4]; /* 403 dedicated access protection registers */
+bool tlb_dirty;  /* Set to non-zero when modifying TLB */
+bool kvm_sw_tlb; /* non-zero if KVM SW TLB API is active */
 uint32_t tlb_need_flush; /* Delayed flush needed */
 #define 

[PATCH 1/2] target/ppc/cpu.h: Move fpu related members closer in cpu env

2020-02-16 Thread BALATON Zoltan
Move fp_status and fpscr closer to other floating point and vector
related members in cpu env definition so they are in one group.

Signed-off-by: BALATON Zoltan 
---
 target/ppc/cpu.h | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 07dd2b4da7..c3b0a00064 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -997,11 +997,6 @@ struct CPUPPCState {
 /* temporary general purpose registers */
 target_ulong tgpr[4]; /* Used to speed-up TLB assist handlers */
 
-/* Floating point execution context */
-float_status fp_status;
-/* floating point status and control register */
-target_ulong fpscr;
-
 /* Next instruction pointer */
 target_ulong nip;
 
@@ -1060,6 +1055,10 @@ struct CPUPPCState {
  * used simultaneously
  */
 float_status vec_status;
+/* Floating point execution context */
+float_status fp_status;
+/* floating point status and control register */
+target_ulong fpscr;
 
 /* Internal devices resources */
 /* Time base and decrementer */
-- 
2.21.1




Re: [PATCH 3/3] tools/virtiofsd/fuse_lowlevel: Fix fuse_out_header.error value

2020-02-16 Thread Ján Tomko

On Sat, Feb 15, 2020 at 05:07:16PM +0100, Philippe Mathieu-Daudé wrote:

Fix warning reported by Clang static code analyzer:

   CC  tools/virtiofsd/fuse_lowlevel.o
 tools/virtiofsd/fuse_lowlevel.c:195:9: warning: Value stored to 'error' is 
never read
 error = -ERANGE;
 ^   ~~~

Fixes: 2de121f01e
Reported-by: Clang Static Analyzer
Signed-off-by: Philippe Mathieu-Daudé 
---
RFC because untested
---
tools/virtiofsd/fuse_lowlevel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [PATCH 2/3] tools/virtiofsd/passthrough_ll: Remove unneeded variable assignment

2020-02-16 Thread Ján Tomko

On Sat, Feb 15, 2020 at 05:07:15PM +0100, Philippe Mathieu-Daudé wrote:

Fix warning reported by Clang static code analyzer:

   CC  tools/virtiofsd/passthrough_ll.o
 tools/virtiofsd/passthrough_ll.c:925:9: warning: Value stored to 'newfd' is 
never read
 newfd = -1;
 ^   ~~
 tools/virtiofsd/passthrough_ll.c:942:9: warning: Value stored to 'newfd' is 
never read
 newfd = -1;
 ^   ~~

Fixes: 7c6b66027
Reported-by: Clang Static Analyzer
Signed-off-by: Philippe Mathieu-Daudé 
---
tools/virtiofsd/passthrough_ll.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index e9e71d5fc2..b38e0e4d84 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -922,7 +922,6 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, 
const char *name,
inode = lo_find(lo, >attr);
if (inode) {
close(newfd);
-newfd = -1;
} else {
inode = calloc(1, sizeof(struct lo_inode));
if (!inode) {
@@ -938,8 +937,7 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, 
const char *name,
g_atomic_int_set(>refcount, 2);

inode->nlookup = 1;
-inode->fd = newfd;
-newfd = -1;
+inode->fd = -1;


The functional equivalent is:
inode->fd = newfd;

newfd cannot contain -1 here, as checked a few lines above:
 newfd = openat(dir->fd, name, O_PATH | O_NOFOLLOW);
 if (newfd == -1) {
 goto out_err;
 }

Jano


inode->key.ino = e->attr.st_ino;
inode->key.dev = e->attr.st_dev;
pthread_mutex_init(>plock_mutex, NULL);
--
2.21.1




signature.asc
Description: PGP signature


Re: [PATCH 1/3] tools/virtiofsd/passthrough_ll: Remove unneeded variable assignment

2020-02-16 Thread Ján Tomko

On Sat, Feb 15, 2020 at 05:07:14PM +0100, Philippe Mathieu-Daudé wrote:

Fix warning reported by Clang static code analyzer:

   CC  tools/virtiofsd/passthrough_ll.o
 tools/virtiofsd/passthrough_ll.c:1083:5: warning: Value stored to 'saverr' is 
never read
 saverr = ENOMEM;
 ^~~

Fixes: 7c6b66027
Reported-by: Clang Static Analyzer
Signed-off-by: Philippe Mathieu-Daudé 
---
tools/virtiofsd/passthrough_ll.c | 2 --
1 file changed, 2 deletions(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [PULL] RISC-V Patches for the 5.0 Soft Freeze, Part 2

2020-02-16 Thread Peter Maydell
On Wed, 12 Feb 2020 at 17:30, Palmer Dabbelt  wrote:
>
> The following changes since commit 81a23caf47956778c5a5056ad656d1ef92bf9659:
>
>   Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' 
> into staging (2020-02-10 17:08:51 +)
>
> are available in the Git repository at:
>
>   g...@github.com:palmer-dabbelt/qemu.git tags/riscv-for-master-5.0-sf2
>
> for you to fetch changes up to 9c8fdcece53e05590441785ab22d91a22da36e29:
>
>   MAINTAINERS: Add maintainer entry for Goldfish RTC (2020-02-10 12:01:39 
> -0800)
>
> 
> RISC-V Patches for the 5.0 Soft Freeze, Part 2
>
> This is a fairly light-weight pull request, but I wanted to send it out to
> avoid the Goldfish stuff getting buried as the next PR should contain the H
> extension implementation.
>
> As far as this PR goes, it contains:
>
> * The addition of syscon device tree nodes for reboot and poweroff, which
>   allows Linux to control QEMU without an additional driver.  The existing
>   device was already compatible with the syscon interface.
> * A fix to our GDB stub to avoid confusing XLEN and FLEN, specifically useful
>   for rv32id-based systems.
> * A device emulation for the Goldfish RTC device, a simple memory-mapped RTC.
> * The addition of the Goldfish RTC device to the RISC-V virt board.
>
> This passes "make check" and boots buildroot for me.
>
> 
>
> Peter: I'm sending hw/rtc code because it was suggested that the Goldfish
> implementation gets handled via the RISC-V tree as our virt board is the only
> user.  I'm happy to do things differently in the future (maybe send
> goldfish-specific PRs?) if that's better for you.  Just LMK what makes sense, 
> I
> anticipate that this'll be a pretty low traffic device so I'm fine with pretty
> much anything.

If it's a device that's only used in risc-v boards I'm happy for
you to just fold those patches into the main risc-v pullreq.

Applied, thanks.

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

-- PMM



Re: [PATCH 1/3] block/qcow2-bitmap: Remove unneeded variable assignment

2020-02-16 Thread Ján Tomko

On Sat, Feb 15, 2020 at 05:15:55PM +0100, Philippe Mathieu-Daudé wrote:

Fix warning reported by Clang static code analyzer:

   CC  block/qcow2-bitmap.o
 block/qcow2-bitmap.c:650:5: warning: Value stored to 'ret' is never read
 ret = -EINVAL;
 ^ ~~~

Reported-by: Clang Static Analyzer
Signed-off-by: Philippe Mathieu-Daudé 
---
block/qcow2-bitmap.c | 1 -
1 file changed, 1 deletion(-)



Reviewed-by: Ján Tomko 

Unused since its introduction in 88ddffae8fc1e30cc907c2dbb989b7eba9e62319

Jano


signature.asc
Description: PGP signature


Re: [PATCH v3 1/4] target/arm: Use bit 55 explicitly for pauth

2020-02-16 Thread Peter Maydell
On Sun, 16 Feb 2020 at 19:43, Richard Henderson
 wrote:
>
> The psuedocode in aarch64/functions/pac/auth/Auth and
> aarch64/functions/pac/strip/Strip always uses bit 55 for
> extfield and do not consider if the current regime has 2 ranges.
>
> Suggested-by: Peter Maydell 
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/pauth_helper.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Peter Maydell 

('pseudocode', but I'll fix the typo when I apply it if
it doesn't need a respin for some other reason)

thanks
-- PMM



Re: [PATCH v3] Implement the Screamer sound chip for the mac99 machine type

2020-02-16 Thread Howard Spoelstra
On Sun, Feb 16, 2020 at 5:32 PM John Arbuckle 
wrote:

> Signed-off-by: John Arbuckle 
> ---
> v3 changes:
> - Updated the location of patched code in hw/ppc/kconfig.
> - Removed setting the props variable in screamer.c.
> - Removed the screamer_properties variable in screamer.c.
>
> v2 changes:
> - Fixed a bug that prevented the sampling rate from being changed.
>
>  hw/audio/Kconfig  |   3 +
>  hw/audio/Makefile.objs|   2 +
>  hw/audio/screamer.c   | 983
> ++
>  hw/misc/macio/macio.c |  35 +-
>  hw/ppc/Kconfig|   1 +
>  hw/ppc/mac.h  |   5 +
>  include/hw/audio/screamer.h   |  42 ++
>  include/hw/misc/macio/macio.h |   2 +
>  8 files changed, 1072 insertions(+), 1 deletion(-)
>  create mode 100644 hw/audio/screamer.c
>  create mode 100644 include/hw/audio/screamer.h
>
> diff --git a/hw/audio/Kconfig b/hw/audio/Kconfig
> index e9c6fed826..196da6c3fe 100644
> --- a/hw/audio/Kconfig
> +++ b/hw/audio/Kconfig
> @@ -50,3 +50,6 @@ config CS4231
>
>  config MARVELL_88W8618
>  bool
> +
> +config SCREAMER
> +bool
> diff --git a/hw/audio/Makefile.objs b/hw/audio/Makefile.objs
> index 63db383709..55906886bc 100644
> --- a/hw/audio/Makefile.objs
> +++ b/hw/audio/Makefile.objs
> @@ -15,4 +15,6 @@ common-obj-$(CONFIG_CS4231) += cs4231.o
>  common-obj-$(CONFIG_MARVELL_88W8618) += marvell_88w8618.o
>  common-obj-$(CONFIG_MILKYMIST) += milkymist-ac97.o
>
> +common-obj-$(CONFIG_SCREAMER) += screamer.o
> +
>  common-obj-y += soundhw.o
> diff --git a/hw/audio/screamer.c b/hw/audio/screamer.c
> new file mode 100644
> index 00..ad4aba12eb
> --- /dev/null
> +++ b/hw/audio/screamer.c
> @@ -0,0 +1,983 @@
> +/*
> + * File: Screamer.c
> + * Description: Implement the Screamer sound chip used in Apple
> Macintoshes.
> + * It works by filling a buffer, then playing the buffer.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "audio/audio.h"
> +#include "hw/hw.h"
> +#include "hw/irq.h"
> +#include 
> +#include "hw/ppc/mac.h"
> +#include "hw/qdev-properties.h"
> +#include "migration/vmstate.h"
> +#include "include/hw/audio/screamer.h"
> +
> +#define DEBUG_SCREAMER 0
> +#define DPRINTF(fmt, ...) \
> +do { if (DEBUG_SCREAMER) { printf(fmt , ## __VA_ARGS__); } } while (0)
> +
> +#define SOUND_CONTROL_REG  0
> +#define CODEC_CONTROL_REG  1
> +#define CODEC_STATUS_REG   2
> +#define CLIP_COUNT_REG 3
> +#define BYTE_SWAP_REG  4
> +#define FRAME_COUNT_REG5
> +
> +#define AWACS_BUSY 0x0100
> +
> +/* Used with AWACS register 1 */
> +#define RECALIBRATE 0x004
> +#define LOOPTHRU0x040
> +#define SPEAKER_MUTE0x080
> +#define HEADPHONE_MUTE  0x200
> +#define OUTPUT_ZERO 0x400
> +#define OUTPUT_ONE  0x800
> +#define PARALLEL_OUTPUT 0xc00
> +
> +/* Function prototypes */
> +static uint32_t set_busy_bit(uint32_t value, int bit);
> +static uint32_t set_part_ready_bit(uint32_t value, int bit_value);
> +static uint32_t set_revision(uint32_t input_value);
> +static uint32_t set_manufacturer(uint32_t input_value);
> +static int get_sampling_rate(ScreamerState *s);
> +static uint32_t get_frame_count_reg(ScreamerState *s);
> +static void add_to_speaker_buffer(DBDMA_io *io);
> +static void dma_request(DBDMA_io *io);
> +
> +
> +/ Getters */
> +
> +/* Returns the codec control register's encoded AWACS address */
> +static uint8_t get_codec_control_address(uint32_t value)
> +{
> +uint8_t return_value;
> +return_value = (value >> 12) & 0x0fff;
> +return return_value;
> +}
> +
> +
> +static uint32_t get_sound_control_reg(ScreamerState *s)
> +{
> +DPRINTF("%s() called - returned 0x%x\n", __func__, s->sound_control);
> +return s->sound_control;
> +}
> +
> +/* The AWACS registers are accessed thru this register */
> +static uint32_t get_codec_control_reg(ScreamerState *s)
> +{
> +int awacs_register = get_codec_control_address(s->codec_control);
> +uint32_t return_value = s->awacs[awacs_register];
> +return_value = set_busy_bit(return_value, 0); /* Tell CPU we are
> ready */
> +DPRINTF("%s() called - returned 0x%x\tAWACS register: %d\n", __func__,
> +return_value, awacs_register);
> +return return_value;
> +}
> +
> +/*
> + * Determines if the readback bit is set.
> + * It is used by the Codec Control register.
> + */
> +static bool readback_enabled(ScreamerState *s)
> +{
> +/* Note: bit zero is the readback enabled bit */
> +if (s->awacs[7] & 1) {
> +return true;
> +} else {
> +return false;
> +}
> +}
> +
> +static uint32_t get_codec_status_reg(ScreamerState *s)
> +{
> +uint32_t return_value;
> +
> +/* if in readback mode - return AWACS register value */
> +if (readback_enabled(s)) {
> +int awacs_register = (s->awacs[7] & 0xe) >> 1;
> +s->awacs[7] = s->awacs[7] & 0xfffe; /* turn off readback mode
> */
> + 

[PATCH v3 2/4] target/arm: Fix select for aa64_va_parameters_both

2020-02-16 Thread Richard Henderson
Select should always be 0 for a regime with one range.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 46 +++--
 1 file changed, 24 insertions(+), 22 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 366dbcf460..b09a501284 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10241,13 +10241,8 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState 
*env, uint64_t va,
 bool tbi, tbid, epd, hpd, using16k, using64k;
 int select, tsz;
 
-/*
- * Bit 55 is always between the two regions, and is canonical for
- * determining if address tagging is enabled.
- */
-select = extract64(va, 55, 1);
-
 if (!regime_has_2_ranges(mmu_idx)) {
+select = 0;
 tsz = extract32(tcr, 0, 6);
 using64k = extract32(tcr, 14, 1);
 using16k = extract32(tcr, 15, 1);
@@ -10260,23 +10255,30 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState 
*env, uint64_t va,
 tbid = extract32(tcr, 29, 1);
 }
 epd = false;
-} else if (!select) {
-tsz = extract32(tcr, 0, 6);
-epd = extract32(tcr, 7, 1);
-using64k = extract32(tcr, 14, 1);
-using16k = extract32(tcr, 15, 1);
-tbi = extract64(tcr, 37, 1);
-hpd = extract64(tcr, 41, 1);
-tbid = extract64(tcr, 51, 1);
 } else {
-int tg = extract32(tcr, 30, 2);
-using16k = tg == 1;
-using64k = tg == 3;
-tsz = extract32(tcr, 16, 6);
-epd = extract32(tcr, 23, 1);
-tbi = extract64(tcr, 38, 1);
-hpd = extract64(tcr, 42, 1);
-tbid = extract64(tcr, 52, 1);
+/*
+ * Bit 55 is always between the two regions, and is canonical for
+ * determining if address tagging is enabled.
+ */
+select = extract64(va, 55, 1);
+if (!select) {
+tsz = extract32(tcr, 0, 6);
+epd = extract32(tcr, 7, 1);
+using64k = extract32(tcr, 14, 1);
+using16k = extract32(tcr, 15, 1);
+tbi = extract64(tcr, 37, 1);
+hpd = extract64(tcr, 41, 1);
+tbid = extract64(tcr, 51, 1);
+} else {
+int tg = extract32(tcr, 30, 2);
+using16k = tg == 1;
+using64k = tg == 3;
+tsz = extract32(tcr, 16, 6);
+epd = extract32(tcr, 23, 1);
+tbi = extract64(tcr, 38, 1);
+hpd = extract64(tcr, 42, 1);
+tbid = extract64(tcr, 52, 1);
+}
 }
 tsz = MIN(tsz, 39);  /* TODO: ARMv8.4-TTST */
 tsz = MAX(tsz, 16);  /* TODO: ARMv8.2-LVA  */
-- 
2.20.1




[PATCH v3 3/4] target/arm: Remove ttbr1_valid check from get_phys_addr_lpae

2020-02-16 Thread Richard Henderson
Now that aa64_va_parameters_both sets select based on the number
of ranges in the regime, the ttbr1_valid check is redundant.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index b09a501284..eec7b01ab3 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10390,7 +10390,6 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
target_ulong address,
 TCR *tcr = regime_tcr(env, mmu_idx);
 int ap, ns, xn, pxn;
 uint32_t el = regime_el(env, mmu_idx);
-bool ttbr1_valid;
 uint64_t descaddrmask;
 bool aarch64 = arm_el_is_aa64(env, el);
 bool guarded = false;
@@ -10405,14 +10404,11 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
target_ulong address,
 param = aa64_va_parameters(env, address, mmu_idx,
access_type != MMU_INST_FETCH);
 level = 0;
-ttbr1_valid = regime_has_2_ranges(mmu_idx);
 addrsize = 64 - 8 * param.tbi;
 inputsize = 64 - param.tsz;
 } else {
 param = aa32_va_parameters(env, address, mmu_idx);
 level = 1;
-/* There is no TTBR1 for EL2 */
-ttbr1_valid = (el != 2);
 addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
 inputsize = addrsize - param.tsz;
 }
@@ -10429,7 +10425,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
target_ulong address,
 if (inputsize < addrsize) {
 target_ulong top_bits = sextract64(address, inputsize,
addrsize - inputsize);
-if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
+if (-top_bits != param.select) {
 /* The gap between the two regions is a Translation fault */
 fault_type = ARMFault_Translation;
 goto do_fault;
-- 
2.20.1




[PATCH v3 0/4] target/arm: Reduce aa64_va_parameter overhead

2020-02-16 Thread Richard Henderson
Something I noticed while developing and testing VHE.

For v2, fix select as a separate patch.
For v3, adjust pauth to use bit 55 explicitly, and remove a
now duplicate test within get_phys_addr_lpae.


r~


Richard Henderson (4):
  target/arm: Use bit 55 explicitly for pauth
  target/arm: Fix select for aa64_va_parameters_both
  target/arm: Remove ttbr1_valid check from get_phys_addr_lpae
  target/arm: Split out aa64_va_parameter_tbi, aa64_va_parameter_tbid

 target/arm/internals.h|   3 -
 target/arm/helper.c   | 144 --
 target/arm/pauth_helper.c |   3 +-
 3 files changed, 76 insertions(+), 74 deletions(-)

-- 
2.20.1




[PATCH v3 4/4] target/arm: Split out aa64_va_parameter_tbi, aa64_va_parameter_tbid

2020-02-16 Thread Richard Henderson
For the purpose of rebuild_hflags_a64, we do not need to compute
all of the va parameters, only tbi.  Moreover, we can compute them
in a form that is more useful to storing in hflags.

This eliminates the need for aa64_va_parameter_both, so fold that
in to aa64_va_parameter.  The remaining calls to aa64_va_parameter
are in get_phys_addr_lpae and in pauth_helper.c.

This reduces the total cpu consumption of aa64_va_parameter in a
kernel boot plus a kvm guest kernel boot from 3% to 0.5%.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/internals.h |  3 --
 target/arm/helper.c| 68 +++---
 2 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 58c4d707c5..14328e3f7d 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1127,15 +1127,12 @@ typedef struct ARMVAParameters {
 unsigned tsz: 8;
 unsigned select : 1;
 bool tbi: 1;
-bool tbid   : 1;
 bool epd: 1;
 bool hpd: 1;
 bool using16k   : 1;
 bool using64k   : 1;
 } ARMVAParameters;
 
-ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
-ARMMMUIdx mmu_idx);
 ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
ARMMMUIdx mmu_idx, bool data);
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index eec7b01ab3..8d0f6eca27 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10234,12 +10234,34 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, 
uint8_t s2attrs)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
-ARMMMUIdx mmu_idx)
+static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
+{
+if (regime_has_2_ranges(mmu_idx)) {
+return extract64(tcr, 37, 2);
+} else if (mmu_idx == ARMMMUIdx_Stage2) {
+return 0; /* VTCR_EL2 */
+} else {
+return extract32(tcr, 20, 1);
+}
+}
+
+static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
+{
+if (regime_has_2_ranges(mmu_idx)) {
+return extract64(tcr, 51, 2);
+} else if (mmu_idx == ARMMMUIdx_Stage2) {
+return 0; /* VTCR_EL2 */
+} else {
+return extract32(tcr, 29, 1);
+}
+}
+
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
+   ARMMMUIdx mmu_idx, bool data)
 {
 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
-bool tbi, tbid, epd, hpd, using16k, using64k;
-int select, tsz;
+bool epd, hpd, using16k, using64k;
+int select, tsz, tbi;
 
 if (!regime_has_2_ranges(mmu_idx)) {
 select = 0;
@@ -10248,11 +10270,9 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState 
*env, uint64_t va,
 using16k = extract32(tcr, 15, 1);
 if (mmu_idx == ARMMMUIdx_Stage2) {
 /* VTCR_EL2 */
-tbi = tbid = hpd = false;
+hpd = false;
 } else {
-tbi = extract32(tcr, 20, 1);
 hpd = extract32(tcr, 24, 1);
-tbid = extract32(tcr, 29, 1);
 }
 epd = false;
 } else {
@@ -10266,28 +10286,30 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState 
*env, uint64_t va,
 epd = extract32(tcr, 7, 1);
 using64k = extract32(tcr, 14, 1);
 using16k = extract32(tcr, 15, 1);
-tbi = extract64(tcr, 37, 1);
 hpd = extract64(tcr, 41, 1);
-tbid = extract64(tcr, 51, 1);
 } else {
 int tg = extract32(tcr, 30, 2);
 using16k = tg == 1;
 using64k = tg == 3;
 tsz = extract32(tcr, 16, 6);
 epd = extract32(tcr, 23, 1);
-tbi = extract64(tcr, 38, 1);
 hpd = extract64(tcr, 42, 1);
-tbid = extract64(tcr, 52, 1);
 }
 }
 tsz = MIN(tsz, 39);  /* TODO: ARMv8.4-TTST */
 tsz = MAX(tsz, 16);  /* TODO: ARMv8.2-LVA  */
 
+/* Present TBI as a composite with TBID.  */
+tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
+if (!data) {
+tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
+}
+tbi = (tbi >> select) & 1;
+
 return (ARMVAParameters) {
 .tsz = tsz,
 .select = select,
 .tbi = tbi,
-.tbid = tbid,
 .epd = epd,
 .hpd = hpd,
 .using16k = using16k,
@@ -10295,16 +10317,6 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState 
*env, uint64_t va,
 };
 }
 
-ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
-   ARMMMUIdx mmu_idx, bool data)
-{
-ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
-
-/* Present TBI as a composite with TBID.  */
-ret.tbi &= (data || !ret.tbid);
-return ret;
-}
-
 #ifndef CONFIG_USER_ONLY
 static 

[PATCH v3 1/4] target/arm: Use bit 55 explicitly for pauth

2020-02-16 Thread Richard Henderson
The psuedocode in aarch64/functions/pac/auth/Auth and
aarch64/functions/pac/strip/Strip always uses bit 55 for
extfield and do not consider if the current regime has 2 ranges.

Suggested-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/pauth_helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
index 9746e32bf8..b909630317 100644
--- a/target/arm/pauth_helper.c
+++ b/target/arm/pauth_helper.c
@@ -320,7 +320,8 @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t 
ptr, uint64_t modifier,
 
 static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
 {
-uint64_t extfield = -param.select;
+/* Note that bit 55 is used whether or not the regime has 2 ranges. */
+uint64_t extfield = sextract64(ptr, 55, 1);
 int bot_pac_bit = 64 - param.tsz;
 int top_pac_bit = 64 - 8 * param.tbi;
 
-- 
2.20.1




Re: [PATCH 1/2] hw/ipmi/bmc: Delay timer_new_ns() from init to realize to avoid memleaks

2020-02-16 Thread Corey Minyard
On Sat, Feb 15, 2020 at 04:47:05PM +0100, Philippe Mathieu-Daudé wrote:
> In commit f3a508eb4e the Euler Robot reported calling timer_new()
> in instance_init() can leak heap memory. The easier fix is to
> delay the timer creation at instance realize(). Similarly move
> timer_del() into a new instance unrealize() method.
> 
> This case was found with the following coccinelle script:
> 
> @ match @
> identifier instance_init;
> typedef Object;
> identifier obj;
> expression val, scale;
> identifier clock_type, callback, opaque;
> position pos;
> @@
> static void instance_init(Object *obj)
> {
>   <...
> (
>   val = timer_new@pos(clock_type, scale, callback, opaque);
> |
>   val = timer_new_ns@pos(clock_type, callback, opaque);
> |
>   val = timer_new_us@pos(clock_type, callback, opaque);
> |
>   val = timer_new_ms@pos(clock_type, callback, opaque);
> )
>   ...>
> }
> 
> @ script:python @
> f << match.instance_init;
> p << match.pos;
> @@
> print "check %s:%s:%s in %s()" % (p[0].file, p[0].line, p[0].column, f)
> 
> Signed-off-by: Philippe Mathieu-Daudé 

This looks ok to me:

Acked-by: Corey Minyard 

I can take it into my tree, if you like.

-corey

> ---
> Cc: Pan Nengyuan 
> ---
>  hw/ipmi/ipmi_bmc_extern.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
> index f9a13e0a44..9144ac6c38 100644
> --- a/hw/ipmi/ipmi_bmc_extern.c
> +++ b/hw/ipmi/ipmi_bmc_extern.c
> @@ -463,6 +463,15 @@ static void ipmi_bmc_extern_realize(DeviceState *dev, 
> Error **errp)
>  
>  qemu_chr_fe_set_handlers(>chr, can_receive, receive,
>   chr_event, NULL, ibe, NULL, true);
> +
> +ibe->extern_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, extern_timeout, 
> ibe);
> +}
> +
> +static void ipmi_bmc_extern_unrealize(DeviceState *dev, Error **errp)
> +{
> +IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);
> +
> +timer_del(ibe->extern_timer);
>  }
>  
>  static int ipmi_bmc_extern_post_migrate(void *opaque, int version_id)
> @@ -502,7 +511,6 @@ static void ipmi_bmc_extern_init(Object *obj)
>  {
>  IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);
>  
> -ibe->extern_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, extern_timeout, 
> ibe);
>  vmstate_register(NULL, 0, _ipmi_bmc_extern, ibe);
>  }
>  
> @@ -510,7 +518,6 @@ static void ipmi_bmc_extern_finalize(Object *obj)
>  {
>  IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);
>  
> -timer_del(ibe->extern_timer);
>  timer_free(ibe->extern_timer);
>  }
>  
> @@ -528,6 +535,7 @@ static void ipmi_bmc_extern_class_init(ObjectClass *oc, 
> void *data)
>  bk->handle_reset = ipmi_bmc_extern_handle_reset;
>  dc->hotpluggable = false;
>  dc->realize = ipmi_bmc_extern_realize;
> +dc->unrealize = ipmi_bmc_extern_unrealize;
>  device_class_set_props(dc, ipmi_bmc_extern_properties);
>  }
>  
> -- 
> 2.21.1
> 



[Bug 1863508] [NEW] qemu-system-arm stops with SIGSEGV in helper_gvec_eq16

2020-02-16 Thread Helmut
Public bug reported:

Segmentation fault when trying to start FreeBSD-arm system with qemu-
system-arm (version 4.1.1 on Fedora 31)

Commandline:
gdb -q --args /bin/qemu-system-arm \
 -name FreeBSD12,debug-threads=on \
 -m 1536 -machine virt -smp 2 \
 -M virt,highmem=off -serial mon:stdio -monitor telnet::45452,server,nowait \
 -machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2 \
 -overcommit mem-lock=off -no-reboot -device virtio-rng-device \
 -bios u-boot-qemu.bin \
 -drive 
file=FreeBSD-12.1-RELEASE-arm-armv7-CUBIEBOARD2.img,if=none,id=drive0,format=raw
 \
 -device ich9-ahci,id=ahci -device ide-drive,drive=drive0,bus=ahci.0 

Results:

Mounting local filesystems:.

Thread 4 "CPU 1/TCG" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffcedfe700 (LWP 53608)]
0x558d9332 in helper_gvec_eq16 (d=0x566748d8, a=0x566748e0, 
b=0x566748d0, desc=0) at 
/usr/src/debug/qemu-4.1.1-1.fc31.x86_64/accel/tcg/tcg-runtime-gvec.c:948
948 DO_CMP2(16)

Tested different versions of qemu. qemu-3.0.1 worked, but qemu-3.1.1
failed with the same error.

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  qemu-system-arm stops with SIGSEGV in helper_gvec_eq16

Status in QEMU:
  New

Bug description:
  Segmentation fault when trying to start FreeBSD-arm system with qemu-
  system-arm (version 4.1.1 on Fedora 31)

  Commandline:
  gdb -q --args /bin/qemu-system-arm \
   -name FreeBSD12,debug-threads=on \
   -m 1536 -machine virt -smp 2 \
   -M virt,highmem=off -serial mon:stdio -monitor telnet::45452,server,nowait \
   -machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2 \
   -overcommit mem-lock=off -no-reboot -device virtio-rng-device \
   -bios u-boot-qemu.bin \
   -drive 
file=FreeBSD-12.1-RELEASE-arm-armv7-CUBIEBOARD2.img,if=none,id=drive0,format=raw
 \
   -device ich9-ahci,id=ahci -device ide-drive,drive=drive0,bus=ahci.0 

  Results:
  
  Mounting local filesystems:.

  Thread 4 "CPU 1/TCG" received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0x7fffcedfe700 (LWP 53608)]
  0x558d9332 in helper_gvec_eq16 (d=0x566748d8, a=0x566748e0, 
b=0x566748d0, desc=0) at 
/usr/src/debug/qemu-4.1.1-1.fc31.x86_64/accel/tcg/tcg-runtime-gvec.c:948
  948 DO_CMP2(16)

  Tested different versions of qemu. qemu-3.0.1 worked, but qemu-3.1.1
  failed with the same error.

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



  1   2   >