Re: [PATCH v3 5/7] qapi: Introduce QAPI_LIST_APPEND

2020-12-23 Thread Vladimir Sementsov-Ogievskiy

24.12.2020 01:11, Eric Blake wrote:

Similar to the existing QAPI_LIST_PREPEND, but designed for use where
we want to preserve insertion order.  Callers will be added in
upcoming patches.  Note the difference in signature: PREPEND takes
List*, APPEND takes List**.

Signed-off-by: Eric Blake 
---
  include/qapi/util.h | 13 +
  1 file changed, 13 insertions(+)

diff --git a/include/qapi/util.h b/include/qapi/util.h
index 6178e98e97a5..8b4967990c0d 100644
--- a/include/qapi/util.h
+++ b/include/qapi/util.h
@@ -37,4 +37,17 @@ int parse_qapi_name(const char *name, bool complete);
  (list) = _tmp; \
  } while (0)

+/*
+ * For any pointer to a GenericList @tail, insert @element at the back and
+ * update the tail.


Would be more obvious for me, if directly mention that tail is a pointer to 
'next' field in the last element of the list.


+ *
+ * Note that this macro evaluates @element exactly once, so it is safe
+ * to have side-effects with that argument.
+ */
+#define QAPI_LIST_APPEND(tail, element) do { \
+*(tail) = g_malloc0(sizeof(**(tail))); \
+(*(tail))->value = (element); \
+(tail) = &(*tail)->next; \
+} while (0)
+
  #endif



Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Guenter Roeck
On Thu, Dec 24, 2020 at 02:34:07AM +0100, BALATON Zoltan wrote:
[ ... ]
> 
> If we need legacy mode then we may be able to emulate that by setting BARs
> to legacy ports ignoring what values are written to them if legacy mode
> config is set (which may be what the real chip does) and we already have
> IRQs hard wired to legacy values so that would give us legacy and
> half-native mode which is enough for both fuloong2e and pegasos2 but I'm not
> sure how can we fix BARs in QEMU because that's also handled by generic PCI
> code which I also don't want to break.

The code below works for booting Linux while at the same time not affecting
any other emulation. I don't claim it to be a perfect fix, and overloading
the existing property is a bit hackish, but it does work.

Guenter

---
>From cf2d1d655f3fe4f88dc435a3ac4e1e6b6040d08b Mon Sep 17 00:00:00 2001
From: Guenter Roeck 
Date: Wed, 23 Dec 2020 09:12:37 -0800
Subject: [PATCH] via-ide: Fix fuloong2 support

Fuloong2 needs to use legacy mode for IDE support to work with Linux.
Add property to via-ide driver to make the mode configurable, and set
legacy mode for Fuloong2.

Signed-off-by: Guenter Roeck 
---
 hw/ide/via.c| 16 ++--
 hw/mips/fuloong2e.c |  4 +++-
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index be09912b33..9e55e717e8 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -26,6 +26,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "qemu/module.h"
 #include "sysemu/dma.h"
@@ -185,12 +186,17 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
   >bus[1], "via-ide1-cmd", 4);
 pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]);
 
-bmdma_setup_bar(d);
-pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar);
+if (!d->secondary) {
+bmdma_setup_bar(d);
+pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar);
+}
 
 qdev_init_gpio_in(ds, via_ide_set_irq, 2);
 for (i = 0; i < 2; i++) {
 ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2);
+if (d->secondary) {
+ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, i ? 0x376 : 
0x3f6);
+}
 ide_init2(>bus[i], qdev_get_gpio_in(ds, i));
 
 bmdma_init(>bus[i], >bmdma[i], d);
@@ -210,6 +216,11 @@ static void via_ide_exitfn(PCIDevice *dev)
 }
 }
 
+static Property via_ide_properties[] = {
+DEFINE_PROP_UINT32("legacy_mode", PCIIDEState, secondary, 0), /* hijacked 
*/
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void via_ide_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -223,6 +234,7 @@ static void via_ide_class_init(ObjectClass *klass, void 
*data)
 k->device_id = PCI_DEVICE_ID_VIA_IDE;
 k->revision = 0x06;
 k->class_id = PCI_CLASS_STORAGE_IDE;
+device_class_set_props(dc, via_ide_properties);
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 }
 
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 23c526c69d..d0398d6266 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -245,7 +245,9 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int 
slot, qemu_irq intc,
 /* Super I/O */
 isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO);
 
-dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide");
+dev = pci_new(PCI_DEVFN(slot, 1), "via-ide");
+qdev_prop_set_uint32(>qdev, "legacy_mode", 1);
+pci_realize_and_unref(dev, pci_bus, _fatal);
 pci_ide_create_devs(dev);
 
 pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci");
-- 
2.17.1




[PATCH v3 4/8] hw/pci-host/bonito: Fixup pci.lomem mapping

2020-12-23 Thread Jiaxun Yang
The original mapping had wrong base address.

Signed-off-by: Jiaxun Yang 
---
 hw/pci-host/bonito.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 3fad470fc6..737ee131e1 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -85,9 +85,8 @@
 #define BONITO_PCILO_BASE_VA0xb000
 #define BONITO_PCILO_SIZE   0x0c00
 #define BONITO_PCILO_TOP(BONITO_PCILO_BASE + BONITO_PCILO_SIZE - 1)
-#define BONITO_PCILO0_BASE  0x1000
-#define BONITO_PCILO1_BASE  0x1400
-#define BONITO_PCILO2_BASE  0x1800
+#define BONITO_PCILOx_BASE(x)   (BONITO_PCILO_BASE + BONITO_PCILOx_SIZE * x)
+#define BONITO_PCILOx_SIZE  0x0400
 #define BONITO_PCIHI_BASE   0x2000
 #define BONITO_PCIHI_SIZE   0x6000
 #define BONITO_PCIHI_TOP(BONITO_PCIHI_BASE + BONITO_PCIHI_SIZE - 1)
@@ -610,7 +609,7 @@ static void bonito_pcihost_realize(DeviceState *dev, Error 
**errp)
 {
 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
 BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev);
-MemoryRegion *pcimem_lo_alias = g_new(MemoryRegion, 3);
+MemoryRegion *pcimem_lo_alias = g_new(MemoryRegion, 1);
 
 memory_region_init(>pci_mem, OBJECT(dev), "pci.mem", 
BONITO_PCIHI_SIZE);
 phb->bus = pci_register_root_bus(dev, "pci",
@@ -622,9 +621,10 @@ static void bonito_pcihost_realize(DeviceState *dev, Error 
**errp)
 char *name = g_strdup_printf("pci.lomem%zu", i);
 
 memory_region_init_alias(_lo_alias[i], NULL, name,
- >pci_mem, i * 64 * MiB, 64 * MiB);
+ >pci_mem, BONITO_PCILOx_BASE(i),
+ BONITO_PCILOx_SIZE);
 memory_region_add_subregion(get_system_memory(),
-BONITO_PCILO_BASE + i * 64 * MiB,
+BONITO_PCILOx_BASE(i),
 _lo_alias[i]);
 g_free(name);
 }
-- 
2.29.2




[PATCH v3 7/8] hw/mips/fuloong2e: Add highmem support

2020-12-23 Thread Jiaxun Yang
highmem starts at 0x2000.
Now we can have up to 2G RAM.

Signed-off-by: Jiaxun Yang 
---
v2: Handle SPD for dual DIMM correctly.
v3: Typo corrections
---
 hw/mips/fuloong2e.c | 61 -
 1 file changed, 49 insertions(+), 12 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 2744b211fd..9c468974db 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -56,6 +56,7 @@
 /* Fuloong 2e has a 512k flash: Winbond W39L040AP70Z */
 #define BIOS_SIZE   (512 * KiB)
 #define MAX_IDE_BUS 2
+#define HIGHMEM_START   0x2000
 
 /*
  * PMON is not part of qemu and released with BSD license, anyone
@@ -71,7 +72,8 @@
 #define FULOONG2E_RTL8139_SLOT7
 
 static struct _loaderparams {
-int ram_size;
+int ram_low_size;
+int ram_high_size;
 const char *kernel_filename;
 const char *kernel_cmdline;
 const char *initrd_filename;
@@ -128,14 +130,14 @@ static uint64_t load_kernel(MIPSCPU *cpu)
 initrd_size = get_image_size(loaderparams.initrd_filename);
 if (initrd_size > 0) {
 initrd_offset = ROUND_UP(kernel_high, INITRD_PAGE_SIZE);
-if (initrd_offset + initrd_size > loaderparams.ram_size) {
+if (initrd_offset + initrd_size > loaderparams.ram_low_size) {
 error_report("memory too small for initial ram disk '%s'",
  loaderparams.initrd_filename);
 exit(1);
 }
 initrd_size = load_image_targphys(loaderparams.initrd_filename,
   initrd_offset,
-  loaderparams.ram_size - 
initrd_offset);
+  loaderparams.ram_low_size - 
initrd_offset);
 }
 if (initrd_size == (target_ulong) -1) {
 error_report("could not load initial ram disk '%s'",
@@ -160,7 +162,11 @@ static uint64_t load_kernel(MIPSCPU *cpu)
 
 /* Setup minimum environment variables */
 prom_set(prom_buf, index++, "cpuclock=%u", clock_get_hz(cpu->clock));
-prom_set(prom_buf, index++, "memsize=%"PRIi64, loaderparams.ram_size / 
MiB);
+prom_set(prom_buf, index++, "memsize=%"PRIi64, loaderparams.ram_low_size / 
MiB);
+if (loaderparams.ram_high_size > 0) {
+prom_set(prom_buf, index++, "highmemsize=%"PRIi64,
+loaderparams.ram_high_size / MiB);
+}
 prom_set(prom_buf, index++, NULL);
 
 rom_add_blob_fixed("prom", prom_buf, prom_size, ENVP_PADDR);
@@ -186,7 +192,7 @@ static void write_bootloader(CPUMIPSState *env, uint8_t 
*base,
 p = (uint32_t *)(base + 0x040);
 
 bl_gen_jump_kernel(, ENVP_VADDR - 64, 2, ENVP_VADDR,
-   ENVP_VADDR + 8, loaderparams.ram_size,
+   ENVP_VADDR + 8, loaderparams.ram_low_size,
kernel_addr);
 }
 
@@ -258,8 +264,11 @@ static void mips_fuloong2e_init(MachineState *machine)
 const char *kernel_filename = machine->kernel_filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
 const char *initrd_filename = machine->initrd_filename;
+ram_addr_t ram_low_size, ram_high_size = 0;
 char *filename;
 MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram_low_alias = g_new(MemoryRegion, 1);
+MemoryRegion *ram_high_alias;
 MemoryRegion *bios = g_new(MemoryRegion, 1);
 long bios_size;
 uint8_t *spd_data;
@@ -282,12 +291,31 @@ static void mips_fuloong2e_init(MachineState *machine)
 
 qemu_register_reset(main_cpu_reset, cpu);
 
-/* TODO: support more than 256M RAM as highmem */
-if (machine->ram_size != 256 * MiB) {
-error_report("Invalid RAM size, should be 256MB");
+if (machine->ram_size > 2 * GiB) {
+error_report("Too much memory for this machine: %" PRId64 "MB,"
+ " maximum 2048MB", machine->ram_size / MiB);
 exit(EXIT_FAILURE);
 }
-memory_region_add_subregion(address_space_mem, 0, machine->ram);
+
+ram_low_size = MIN(machine->ram_size, 256 * MiB);
+
+memory_region_init_alias(ram_low_alias, NULL,
+"ram_low_alias",
+machine->ram, 0,
+ram_low_size);
+memory_region_add_subregion(address_space_mem, 0,
+ram_low_alias);
+
+if (machine->ram_size > 256 * MiB) {
+ram_high_alias = g_new(MemoryRegion, 1);
+ram_high_size = machine->ram_size - ram_low_size;
+memory_region_init_alias(ram_high_alias, NULL,
+"ram_high_alias",
+machine->ram, ram_low_size,
+ram_high_size);
+memory_region_add_subregion(address_space_mem, HIGHMEM_START,
+ram_high_alias);
+}
 
 /* Boot ROM */
 

[PATCH v3 3/8] hw/pci-host/bonito: Fixup IRQ mapping

2020-12-23 Thread Jiaxun Yang
Accroading to arch/mips/pci/fixup-fuloong2e.c in kernel,
despites south bridge IRQs needs special care, all other
IRQ pins are mapped by 'LOONGSON_IRQ_BASE + 25 + pin'.

As south bridge IRQs are all handled by ISA bus, we can
make a simple direct mapping.

Signed-off-by: Jiaxun Yang 
---
v3: Define BONITO_PCI_IRQ_BASE for readability (f4bug)
---
 hw/pci-host/bonito.c | 30 +++---
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index a99eced065..3fad470fc6 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -62,6 +62,9 @@
 #define DPRINTF(fmt, ...)
 #endif
 
+/* PCI slots IRQ pins start position */
+#define BONITO_PCI_IRQ_BASE 25
+
 /* from linux soure code. include/asm-mips/mips-boards/bonito64.h*/
 #define BONITO_BOOT_BASE0x1fc0
 #define BONITO_BOOT_SIZE0x0010
@@ -546,19 +549,16 @@ static const MemoryRegionOps bonito_spciconf_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-#define BONITO_IRQ_BASE 32
-
 static void pci_bonito_set_irq(void *opaque, int irq_num, int level)
 {
 BonitoState *s = opaque;
 qemu_irq *pic = s->pic;
 PCIBonitoState *bonito_state = s->pci_dev;
-int internal_irq = irq_num - BONITO_IRQ_BASE;
 
-if (bonito_state->regs[BONITO_INTEDGE] & (1 << internal_irq)) {
+if (bonito_state->regs[BONITO_INTEDGE] & (1 << irq_num)) {
 qemu_irq_pulse(*pic);
 } else {   /* level triggered */
-if (bonito_state->regs[BONITO_INTPOL] & (1 << internal_irq)) {
+if (bonito_state->regs[BONITO_INTPOL] & (1 << irq_num)) {
 qemu_irq_raise(*pic);
 } else {
 qemu_irq_lower(*pic);
@@ -566,25 +566,9 @@ static void pci_bonito_set_irq(void *opaque, int irq_num, 
int level)
 }
 }
 
-/* map the original irq (0~3) to bonito irq (16~47, but 16~31 are unused) */
-static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num)
+static int pci_bonito_map_irq(PCIDevice *pci_dev, int pin)
 {
-int slot;
-
-slot = (pci_dev->devfn >> 3);
-
-switch (slot) {
-case 5:   /* FULOONG2E_VIA_SLOT, SouthBridge, IDE, USB, ACPI, AC97, MC97 */
-return irq_num % 4 + BONITO_IRQ_BASE;
-case 6:   /* FULOONG2E_ATI_SLOT, VGA */
-return 4 + BONITO_IRQ_BASE;
-case 7:   /* FULOONG2E_RTL_SLOT, RTL8139 */
-return 5 + BONITO_IRQ_BASE;
-case 8 ... 12: /* PCI slot 1 to 4 */
-return (slot - 8 + irq_num) + 6 + BONITO_IRQ_BASE;
-default:  /* Unknown device, don't do any translation */
-return irq_num;
-}
+return BONITO_PCI_IRQ_BASE + pin;
 }
 
 static void bonito_reset(void *opaque)
-- 
2.29.2




[PATCH v3 5/8] hw/mips/fuloong2e: Remove unused env entry

2020-12-23 Thread Jiaxun Yang
modetty is not handled by kernel and the parameter
here seems unreasonable.

Signed-off-by: Jiaxun Yang 
---
v3: Bring busclock back
---
 hw/mips/fuloong2e.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index d846ef7b00..c4843dd15e 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -159,10 +159,8 @@ static uint64_t load_kernel(CPUMIPSState *env)
 }
 
 /* Setup minimum environment variables */
-prom_set(prom_buf, index++, "busclock=3300");
 prom_set(prom_buf, index++, "cpuclock=1");
 prom_set(prom_buf, index++, "memsize=%"PRIi64, loaderparams.ram_size / 
MiB);
-prom_set(prom_buf, index++, "modetty0=38400n8r");
 prom_set(prom_buf, index++, NULL);
 
 rom_add_blob_fixed("prom", prom_buf, prom_size, ENVP_PADDR);
-- 
2.29.2




[PATCH v3 8/8] tests/acceptance: Test boot_linux_console for fuloong2e

2020-12-23 Thread Jiaxun Yang
The kernel comes from debian archive so it's trusted.

Signed-off-by: Jiaxun Yang 
Reviewed-by: Wainer dos Santos Moschetta 
Reviewed-by: Willian Rampazzo 
Reviewed-by: Huacai Chen 
---
 tests/acceptance/boot_linux_console.py | 21 +
 1 file changed, 21 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index cc6ec0f8c1..fb41bb7144 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -170,6 +170,27 @@ class BootLinuxConsole(LinuxKernelTest):
 console_pattern = 'Kernel command line: %s' % kernel_command_line
 self.wait_for_console_pattern(console_pattern)
 
+def test_mips64el_fuloong2e(self):
+"""
+:avocado: tags=arch:mips64el
+:avocado: tags=machine:fuloong2e
+:avocado: tags=endian:little
+"""
+deb_url = ('http://archive.debian.org/debian/pool/main/l/linux/'
+   
'linux-image-3.16.0-6-loongson-2e_3.16.56-1+deb8u1_mipsel.deb')
+deb_hash = 'd04d446045deecf7b755ef576551de0c4184dd44'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+
'/boot/vmlinux-3.16.0-6-loongson-2e')
+
+self.vm.set_console()
+kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
+self.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line)
+self.vm.launch()
+console_pattern = 'Kernel command line: %s' % kernel_command_line
+self.wait_for_console_pattern(console_pattern)
+
 def test_mips_malta_cpio(self):
 """
 :avocado: tags=arch:mips
-- 
2.29.2




[PATCH v3 6/8] hw/mips/fuloong2e: Correct cpuclock env

2020-12-23 Thread Jiaxun Yang
It was missed in 3ca7639ff00 ("hw/mips/fuloong2e:
Set CPU frequency to 533 MHz"), we need to tell kernel
correct clocks.

Fixes: 3ca7639ff00 ("hw/mips/fuloong2e: Set CPU frequency to 533 MHz").
Signed-off-by: Jiaxun Yang 
Reviewed-by: Huacai Chen 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/mips/fuloong2e.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index c4843dd15e..2744b211fd 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -100,7 +100,7 @@ static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t *prom_buf, 
int index,
 va_end(ap);
 }
 
-static uint64_t load_kernel(CPUMIPSState *env)
+static uint64_t load_kernel(MIPSCPU *cpu)
 {
 uint64_t kernel_entry, kernel_high, initrd_size;
 int index = 0;
@@ -159,7 +159,7 @@ static uint64_t load_kernel(CPUMIPSState *env)
 }
 
 /* Setup minimum environment variables */
-prom_set(prom_buf, index++, "cpuclock=1");
+prom_set(prom_buf, index++, "cpuclock=%u", clock_get_hz(cpu->clock));
 prom_set(prom_buf, index++, "memsize=%"PRIi64, loaderparams.ram_size / 
MiB);
 prom_set(prom_buf, index++, NULL);
 
@@ -304,7 +304,7 @@ static void mips_fuloong2e_init(MachineState *machine)
 loaderparams.kernel_filename = kernel_filename;
 loaderparams.kernel_cmdline = kernel_cmdline;
 loaderparams.initrd_filename = initrd_filename;
-kernel_entry = load_kernel(env);
+kernel_entry = load_kernel(cpu);
 write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
 } else {
 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
-- 
2.29.2




[PATCH v3 2/8] hw/mips/fuloong2e: Relpace fault links

2020-12-23 Thread Jiaxun Yang
Websites are downing, but GitHub may last forever.
Loongson even doesn't recogonize 2E as their products nowadays..

Signed-off-by: Jiaxun Yang 
Reviewed-by: Huacai Chen 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
---
 hw/mips/fuloong2e.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 055b99e378..d846ef7b00 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -14,8 +14,8 @@
  * Fuloong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 
800MHz)
  * https://www.linux-mips.org/wiki/Fuloong_2E
  *
- * Loongson 2e user manual:
- * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
+ * Loongson 2e manuals:
+ * https://github.com/loongson-community/docs/tree/master/2E
  */
 
 #include "qemu/osdep.h"
@@ -61,14 +61,7 @@
  * PMON is not part of qemu and released with BSD license, anyone
  * who want to build a pmon binary please first git-clone the source
  * from the git repository at:
- * http://www.loongson.cn/support/git/pmon
- * Then follow the "Compile Guide" available at:
- * http://dev.lemote.com/code/pmon
- *
- * Notes:
- * 1, don't use the source at http://dev.lemote.com/http_git/pmon.git
- * 2, use "Bonito2edev" to replace "dir_corresponding_to_your_target_hardware"
- * in the "Compile Guide".
+ * https://github.com/loongson-community/pmon
  */
 #define FULOONG_BIOSNAME "pmon_2e.bin"
 
-- 
2.29.2




[PATCH v3 1/8] hw/mips/fuloong2e: Remove define DEBUG_FULOONG2E_INIT

2020-12-23 Thread Jiaxun Yang
Seems useless

Fixes: 051c190bce5 ("MIPS: Initial support of fulong mini pc (machine 
construction)")
Signed-off-by: Jiaxun Yang 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Huacai Chen 
---
 hw/mips/fuloong2e.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 9b0eb8a314..055b99e378 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -48,8 +48,6 @@
 #include "sysemu/reset.h"
 #include "qemu/error-report.h"
 
-#define DEBUG_FULOONG2E_INIT
-
 #define ENVP_PADDR  0x2000
 #define ENVP_VADDR  cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR)
 #define ENVP_NB_ENTRIES 16
-- 
2.29.2




[PATCH v3 0/8] hw/mips/fuloong2e fixes

2020-12-23 Thread Jiaxun Yang
It can now boot Debian installer[1] as well as a custom PMON bootloader
distribution[2].

Note that it can't boot PMON shipped with actual machine as our ATI vgabios
is using some x86 hack that can't be handled by x86emu in original PMON. 


Tree avilable at: https://gitlab.com/FlyGoat/qemu/-/tree/fuloong_fixes_v2

v2:
 - Collect review tags.
 - Get CPU clock via elegant method. (philmd)
 - Add boot_linux_console scceptance test

v3:
 - Collect review tags
 - Typo corrections
 - Rewrite PCI Lomem

Jiaxun Yang (8):
  hw/mips/fuloong2e: Remove define DEBUG_FULOONG2E_INIT
  hw/mips/fuloong2e: Relpace fault links
  hw/pci-host/bonito: Fixup IRQ mapping
  hw/pci-host/bonito: Fixup pci.lomem mapping
  hw/mips/fuloong2e: Remove unused env entry
  hw/mips/fuloong2e: Correct cpuclock env
  hw/mips/fuloong2e: Add highmem support
  tests/acceptance: Test boot_linux_console for fuloong2e

 hw/mips/fuloong2e.c| 84 +-
 hw/pci-host/bonito.c   | 42 -
 tests/acceptance/boot_linux_console.py | 21 +++
 3 files changed, 89 insertions(+), 58 deletions(-)

-- 
2.29.2




Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Jiaxun Yang

在 2020/12/24 上午9:34, BALATON Zoltan 写道:

On Thu, 24 Dec 2020, BALATON Zoltan wrote:

On Wed, 23 Dec 2020, Guenter Roeck wrote:

v3.1:

pci :00:05.1: [Firmware Bug]: reg 0x10: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x14: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x18: invalid BAR (can't size)
pci :00:05.1: reg 0x1c: [mem 0x10370-0x1037f 64bit]
...
pata_via :00:05.1: BMDMA: BAR4 is zero, falling back to PIO
ata1: PATA max PIO4 cmd 0x1f0 ctl 0x3f6 irq 14
ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15
ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
...


This is the previous state only emulating legacy mode and since none 
of the native mode BARs are there Linux fails to enable native mode 
and falls back to legacy so it ends up working but probably not how 
this should work on real machine.





v5.2:

pci :00:05.1: reg 0x10: [io  0x-0x0007]
pci :00:05.1: reg 0x14: [io  0x-0x0003]
pci :00:05.1: reg 0x18: [io  0x-0x0007]
pci :00:05.1: reg 0x1c: [io  0x-0x0003]
pci :00:05.1: reg 0x20: [io  0x-0x000f]
pci :00:05.1: BAR 4: assigned [io  0x4440-0x444f]
...
ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x4440 irq 14
ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x4448 irq 15
[and nothing else]


Now we emulate native mode and Linux seems to program the BARs 
(although I'm not sure all these should be starting at 0) but then 
still tries to access the device in legacy mode as shown by ports and 
IRQs.


If someone has logs from original machine it would be interesting to 
see how IDE ports are detected there. I'll try with the kernel from 
debian and see what that does but maybe it tries to use legacy mode 
too then it won't work.


With the original image I used for testing described here:
https://lists.nongnu.org/archive/html/qemu-devel/2020-03/msg04086.html
I now get:

$ qemu-system-mips64el -M fuloong2e -serial stdio -net none -vga none 
-kernel gentoo-loongson-2.6.22.6-20070902 -cdrom 
debian-8.11.0-mipsel-netinst.iso



scsi0 : pata_via
scsi1 : pata_via
ata1: PATA max UDMA/100 cmd 0xbfd001f0 ctl 0xbfd003f6 
bmdma 0xbfd04040 irq 14
ata2: PATA max UDMA/100 cmd 0xbfd00170 ctl 0xbfd00376 
bmdma 0xbfd04048 irq 15


2. The Linux driver you use wants to use legacy mode of the IDE that 
we don't emulate. The linux/arch/mips/pci/fixup-fuloong2e.c does 
mention legacy mode but I think I've found previously that if we hard 
code native mode, Linux would detect it and use it anyway. I think 
this worked with my original series but may have been broken during 
the rework. I'd have to dig up those


Here's my original series from March 10:
http://patchwork.ozlabs.org/project/qemu-devel/list/?series=163521
this applies on a checkout from that time such as 7f368aed672117
and with that it works with the gentoo kernel above:

Linux version 2.6.22.6-mipsgit-20070902-lm2e-liveusb (stuartl@zhenghe) 
(gcc version 4.1.2 (Gentoo 4.1.2 p1.0.1)) #5 Fri Jan 25 11:19:12 EST 2008

[...]
SCSI subsystem initialized
via686b fix: ISA bridge
via686b fix: ISA bridge done
via686b fix: IDE
via686b fix: IDE done
PCI quirk: region eee0-eeef claimed by vt82c686 SMB
ac97 interrupt = 9
[...]
scsi0 : pata_via
scsi1 : pata_via
ata1: PATA max UDMA/100 cmd 0xbfd04050 ctl 0xbfd04062 
bmdma 0xbfd04040 irq 14
ata2: PATA max UDMA/100 cmd 0xbfd04058 ctl 0xbfd04066 
bmdma 0xbfd04048 irq 14

ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100
ata2.00: limited to UDMA/33 due to 40-wire cable
ata2.00: configured for UDMA/33
scsi 1:0:0:0: CD-ROM    QEMU QEMU DVD-ROM 2.5+ PQ: 0 
ANSI: 5


Note that both channels using irq 14 which means fully native mode but 
that would not work for pegasos2 where we need half-native mode (PCI 
BARs with IRQ 14/15) hence we need the property and flag to enable 
that mode for pegasos2. Without that flag we now only really emulate 
half-native mode which is fine for pegasos2 but seems Linux on 
fuloong2e does not like that. The gentoo kernel seems to like either 
legacy or full native mode, however with the debian kernel from 
Philippe even full native mode fails:


[    0.00] Linux version 3.16.0-6-loongson-2e 
(debian-ker...@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1) ) 
#1 Debian 3.16.56-1+deb8u1 (2018-05-08)

[...]
[    0.196000] SCSI subsystem initialized
[    0.20] PCI host bridge to bus :00
[    0.20] pci_bus :00: root bus resource [mem 
0x1400-0x1c00]

[    0.20] pci_bus :00: root bus resource [io 0x4000-0x]
[    0.20] pci_bus :00: No busn resource found for root bus, 
will use [bus 00-ff]

[    0.208000] via686b fix: ISA bridge
[    0.208000] via686b fix: ISA bridge done
[    0.208000] via686b fix: IDE
[    0.208000] via686b fix: IDE done
[    0.208000] pci :00:05.4: quirk: [io  0xeee0-0xeeef] claimed by 
vt82c686 SMB

[    0.212000] 

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread BALATON Zoltan via

On Thu, 24 Dec 2020, BALATON Zoltan wrote:

On Wed, 23 Dec 2020, Guenter Roeck wrote:

v3.1:

pci :00:05.1: [Firmware Bug]: reg 0x10: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x14: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x18: invalid BAR (can't size)
pci :00:05.1: reg 0x1c: [mem 0x10370-0x1037f 64bit]
...
pata_via :00:05.1: BMDMA: BAR4 is zero, falling back to PIO
ata1: PATA max PIO4 cmd 0x1f0 ctl 0x3f6 irq 14
ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15
ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
...


This is the previous state only emulating legacy mode and since none of the 
native mode BARs are there Linux fails to enable native mode and falls back 
to legacy so it ends up working but probably not how this should work on real 
machine.





v5.2:

pci :00:05.1: reg 0x10: [io  0x-0x0007]
pci :00:05.1: reg 0x14: [io  0x-0x0003]
pci :00:05.1: reg 0x18: [io  0x-0x0007]
pci :00:05.1: reg 0x1c: [io  0x-0x0003]
pci :00:05.1: reg 0x20: [io  0x-0x000f]
pci :00:05.1: BAR 4: assigned [io  0x4440-0x444f]
...
ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x4440 irq 14
ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x4448 irq 15
[and nothing else]


Now we emulate native mode and Linux seems to program the BARs (although I'm 
not sure all these should be starting at 0) but then still tries to access 
the device in legacy mode as shown by ports and IRQs.


If someone has logs from original machine it would be interesting to see how 
IDE ports are detected there. I'll try with the kernel from debian and see 
what that does but maybe it tries to use legacy mode too then it won't work.


With the original image I used for testing described here:
https://lists.nongnu.org/archive/html/qemu-devel/2020-03/msg04086.html
I now get:

$ qemu-system-mips64el -M fuloong2e -serial stdio -net none -vga none -kernel 
gentoo-loongson-2.6.22.6-20070902 -cdrom debian-8.11.0-mipsel-netinst.iso



scsi0 : pata_via
scsi1 : pata_via
ata1: PATA max UDMA/100 cmd 0xbfd001f0 ctl 0xbfd003f6 bmdma 
0xbfd04040 irq 14
ata2: PATA max UDMA/100 cmd 0xbfd00170 ctl 0xbfd00376 bmdma 
0xbfd04048 irq 15


2. The Linux driver you use wants to use legacy mode of the IDE that we don't 
emulate. The linux/arch/mips/pci/fixup-fuloong2e.c does mention legacy mode 
but I think I've found previously that if we hard code native mode, Linux 
would detect it and use it anyway. I think this worked with my original 
series but may have been broken during the rework. I'd have to dig up those


Here's my original series from March 10:
http://patchwork.ozlabs.org/project/qemu-devel/list/?series=163521
this applies on a checkout from that time such as 7f368aed672117
and with that it works with the gentoo kernel above:

Linux version 2.6.22.6-mipsgit-20070902-lm2e-liveusb (stuartl@zhenghe) (gcc 
version 4.1.2 (Gentoo 4.1.2 p1.0.1)) #5 Fri Jan 25 11:19:12 EST 2008
[...]
SCSI subsystem initialized
via686b fix: ISA bridge
via686b fix: ISA bridge done
via686b fix: IDE
via686b fix: IDE done
PCI quirk: region eee0-eeef claimed by vt82c686 SMB
ac97 interrupt = 9
[...]
scsi0 : pata_via
scsi1 : pata_via
ata1: PATA max UDMA/100 cmd 0xbfd04050 ctl 0xbfd04062 bmdma 
0xbfd04040 irq 14
ata2: PATA max UDMA/100 cmd 0xbfd04058 ctl 0xbfd04066 bmdma 
0xbfd04048 irq 14
ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100
ata2.00: limited to UDMA/33 due to 40-wire cable
ata2.00: configured for UDMA/33
scsi 1:0:0:0: CD-ROMQEMU QEMU DVD-ROM 2.5+ PQ: 0 ANSI: 5

Note that both channels using irq 14 which means fully native mode but 
that would not work for pegasos2 where we need half-native mode (PCI BARs 
with IRQ 14/15) hence we need the property and flag to enable that mode 
for pegasos2. Without that flag we now only really emulate half-native 
mode which is fine for pegasos2 but seems Linux on fuloong2e does not like 
that. The gentoo kernel seems to like either legacy or full native mode, 
however with the debian kernel from Philippe even full native mode fails:


[0.00] Linux version 3.16.0-6-loongson-2e 
(debian-ker...@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1) ) #1 
Debian 3.16.56-1+deb8u1 (2018-05-08)
[...]
[0.196000] SCSI subsystem initialized
[0.20] PCI host bridge to bus :00
[0.20] pci_bus :00: root bus resource [mem 0x1400-0x1c00]
[0.20] pci_bus :00: root bus resource [io  0x4000-0x]
[0.20] pci_bus :00: No busn resource found for root bus, will use 
[bus 00-ff]
[0.208000] via686b fix: ISA bridge
[0.208000] via686b fix: ISA bridge done
[0.208000] via686b fix: IDE
[0.208000] via686b fix: IDE done
[0.208000] pci :00:05.4: quirk: [io  0xeee0-0xeeef] claimed by vt82c686 
SMB
[0.212000] pci :00:05.2: BAR 4: assigned [io  0x4000-0x401f]
[ 

Re: [RFC PATCH 1/3] mm: support hugetlb free page reporting

2020-12-23 Thread Liang Li
> >>> +static int
> >>> +hugepage_reporting_cycle(struct page_reporting_dev_info *prdev,
> >>> +  struct hstate *h, unsigned int nid,
> >>> +  struct scatterlist *sgl, unsigned int *offset)
> >>> +{
> >>> + struct list_head *list = >hugepage_freelists[nid];
> >>> + unsigned int page_len = PAGE_SIZE << h->order;
> >>> + struct page *page, *next;
> >>> + long budget;
> >>> + int ret = 0, scan_cnt = 0;
> >>> +
> >>> + /*
> >>> +  * Perform early check, if free area is empty there is
> >>> +  * nothing to process so we can skip this free_list.
> >>> +  */
> >>> + if (list_empty(list))
> >>> + return ret;
> >>
> >> Do note that not all entries on the hugetlb free lists are free.  Reserved
> >> entries are also on the free list.  The actual number of free entries is
> >> 'h->free_huge_pages - h->resv_huge_pages'.
> >> Is the intention to process reserved pages as well as free pages?
> >
> > Yes, Reserved pages was treated as 'free pages'
>
> If that is true, then this code breaks hugetlb.  hugetlb code assumes that
> h->free_huge_pages is ALWAYS >= h->resv_huge_pages.  This code would break
> that assumption.  If you really want to add support for hugetlb pages, then
> you will need to take reserved pages into account.

I didn't know that. thanks!

> P.S. There might be some confusion about 'reservations' based on the
> commit message.  My comments are directed at hugetlb reservations described
> in Documentation/vm/hugetlbfs_reserv.rst.
>
> >>> + /* Attempt to pull page from list and place in scatterlist 
> >>> */
> >>> + if (*offset) {
> >>> + isolate_free_huge_page(page, h, nid);
> >>
> >> Once a hugetlb page is isolated, it can not be used and applications that
> >> depend on hugetlb pages can start to fail.
> >> I assume that is acceptable/expected behavior.  Correct?
> >> On some systems, hugetlb pages are a precious resource and the sysadmin
> >> carefully configures the number needed by applications.  Removing a hugetlb
> >> page (even for a very short period of time) could cause serious application
> >> failure.
> >
> > That' true, especially for 1G pages. Any suggestions?
> > Let the hugepage allocator be aware of this situation and retry ?
>
> I would hate to add that complexity to the allocator.
>
> This question is likely based on my lack of understanding of virtio-balloon
> usage and this reporting mechanism.  But, why do the hugetlb pages have to
> be 'temporarily' allocated for reporting purposes?

The link here will give your more detail about how page reporting
works, https://www.kernel.org/doc/html/latest//vm/free_page_reporting.html
the virtio-balloon driver is based on this framework and will report the
free pages information to QEMU, host can unmap the memory
region corresponding to reported free pages and reclaim the memory
for other use, it's useful for memory overcommit.
Allocated the pages 'temporarily' before reporting is necessary, it make
sure guests will not use the page when the host side unmap the region.
or it will break the guest.

Now I realized we should solve this issue first, it seems adding a lock
will help.

Thanks



[PATCH 2/3] hmp-commands: Add new HMP command for COLO passthrough

2020-12-23 Thread Zhang Chen
From: Zhang Chen 

Add hmp_colo_passthrough_add and hmp_colo_passthrough_del make user
can maintain COLO network passthrough list in human monitor.

Signed-off-by: Zhang Chen 
---
 hmp-commands.hx   | 26 ++
 include/monitor/hmp.h |  2 ++
 monitor/hmp-cmds.c| 20 
 3 files changed, 48 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 470a420c2d..f5790782d6 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1341,6 +1341,32 @@ SRST
   Remove host network device.
 ERST
 
+{
+.name   = "colo_passthrough_add",
+.args_type  = "protocol:s,port:i",
+.params = "protocol port",
+.help   = "Add network stream to colo passthrough list",
+.cmd= hmp_colo_passthrough_add,
+},
+
+SRST
+``colo_passthrough_add``
+  Add network stream to colo passthrough list.
+ERST
+
+{
+.name   = "colo_passthrough_del",
+.args_type  = "protocol:s,port:i",
+.params = "protocol port",
+.help   = "Delete network stream from colo passthrough list",
+.cmd= hmp_colo_passthrough_del,
+},
+
+SRST
+``colo_passthrough_del``
+  Delete network stream from colo passthrough list.
+ERST
+
 {
 .name   = "object_add",
 .args_type  = "object:O",
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index ed2913fd18..3c4943b09f 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -81,6 +81,8 @@ void hmp_device_del(Monitor *mon, const QDict *qdict);
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
 void hmp_netdev_add(Monitor *mon, const QDict *qdict);
 void hmp_netdev_del(Monitor *mon, const QDict *qdict);
+void hmp_colo_passthrough_add(Monitor *mon, const QDict *qdict);
+void hmp_colo_passthrough_del(Monitor *mon, const QDict *qdict);
 void hmp_getfd(Monitor *mon, const QDict *qdict);
 void hmp_closefd(Monitor *mon, const QDict *qdict);
 void hmp_sendkey(Monitor *mon, const QDict *qdict);
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 65d8ff4849..ab98a6b77d 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1661,6 +1661,26 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
 hmp_handle_error(mon, err);
 }
 
+void hmp_colo_passthrough_add(Monitor *mon, const QDict *qdict)
+{
+const char *prot = qdict_get_str(qdict, "protocol");
+uint32_t port = qdict_get_int(qdict, "port");
+Error *err = NULL;
+
+qmp_colo_passthrough_add(prot, port, );
+hmp_handle_error(mon, err);
+}
+
+void hmp_colo_passthrough_del(Monitor *mon, const QDict *qdict)
+{
+const char *prot = qdict_get_str(qdict, "protocol");
+uint32_t port = qdict_get_int(qdict, "port");
+Error *err = NULL;
+
+qmp_colo_passthrough_del(prot, port, );
+hmp_handle_error(mon, err);
+}
+
 void hmp_object_add(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
-- 
2.17.1




[PATCH 3/3] net/colo-compare: Add handler for passthrough connection

2020-12-23 Thread Zhang Chen
From: Zhang Chen 

Currently, we just use guest's TCP/UDP source port as the key
to bypass certain network traffic.

Signed-off-by: Zhang Chen 
---
 net/colo-compare.c | 49 ++
 net/colo-compare.h |  2 ++
 net/net.c  | 27 +
 3 files changed, 78 insertions(+)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 337025b44f..11a32caa9b 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -46,6 +46,9 @@ static QTAILQ_HEAD(, CompareState) net_compares =
 static NotifierList colo_compare_notifiers =
 NOTIFIER_LIST_INITIALIZER(colo_compare_notifiers);
 
+static QLIST_HEAD(, PassthroughEntry) passthroughlist =
+QLIST_HEAD_INITIALIZER(passthroughlist);
+
 #define COMPARE_READ_LEN_MAX NET_BUFSIZE
 #define MAX_QUEUE_SIZE 1024
 
@@ -103,6 +106,12 @@ typedef struct SendEntry {
 uint8_t *buf;
 } SendEntry;
 
+typedef struct PassthroughEntry {
+bool is_tcp;
+uint16_t port;
+QLIST_ENTRY(PassthroughEntry) node;
+} PassthroughEntry;
+
 struct CompareState {
 Object parent;
 
@@ -247,6 +256,7 @@ static int packet_enqueue(CompareState *s, int mode, 
Connection **con)
 ConnectionKey key;
 Packet *pkt = NULL;
 Connection *conn;
+PassthroughEntry *bypass, *next;
 int ret;
 
 if (mode == PRIMARY_IN) {
@@ -264,8 +274,23 @@ static int packet_enqueue(CompareState *s, int mode, 
Connection **con)
 pkt = NULL;
 return -1;
 }
+
 fill_connection_key(pkt, );
 
+/* Check COLO passthrough connenction */
+if (!QLIST_EMPTY()) {
+QLIST_FOREACH_SAFE(bypass, , node, next) {
+if (((key.ip_proto == IPPROTO_TCP) && bypass->is_tcp) ||
+((key.ip_proto == IPPROTO_UDP) && !bypass->is_tcp)) {
+if (bypass->port == key.src_port) {
+packet_destroy(pkt, NULL);
+pkt = NULL;
+return -1;
+}
+}
+}
+}
+
 conn = connection_get(s->connection_track_table,
   ,
   >conn_list);
@@ -1373,6 +1398,30 @@ static void colo_flush_packets(void *opaque, void 
*user_data)
 }
 }
 
+void colo_compare_passthrough_add(bool is_tcp, const uint16_t port)
+{
+PassthroughEntry *bypass = NULL;
+
+bypass = g_new0(PassthroughEntry, 1);
+bypass->is_tcp = is_tcp;
+bypass->port = port;
+QLIST_INSERT_HEAD(, bypass, node);
+}
+
+void colo_compare_passthrough_del(bool is_tcp, const uint16_t port)
+{
+PassthroughEntry *bypass = NULL, *next = NULL;
+
+if (!QLIST_EMPTY()) {
+QLIST_FOREACH_SAFE(bypass, , node, next) {
+if ((bypass->is_tcp == is_tcp) && (bypass->port == port)) {
+QLIST_REMOVE(bypass, node);
+g_free(bypass);
+}
+}
+}
+}
+
 static void colo_compare_class_init(ObjectClass *oc, void *data)
 {
 UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
diff --git a/net/colo-compare.h b/net/colo-compare.h
index 22ddd512e2..1fa026c85e 100644
--- a/net/colo-compare.h
+++ b/net/colo-compare.h
@@ -20,5 +20,7 @@
 void colo_notify_compares_event(void *opaque, int event, Error **errp);
 void colo_compare_register_notifier(Notifier *notify);
 void colo_compare_unregister_notifier(Notifier *notify);
+void colo_compare_passthrough_add(bool is_tcp, const uint16_t port);
+void colo_compare_passthrough_del(bool is_tcp, const uint16_t port);
 
 #endif /* QEMU_COLO_COMPARE_H */
diff --git a/net/net.c b/net/net.c
index eac7a92618..1f303e8309 100644
--- a/net/net.c
+++ b/net/net.c
@@ -55,6 +55,7 @@
 #include "sysemu/sysemu.h"
 #include "net/filter.h"
 #include "qapi/string-output-visitor.h"
+#include "net/colo-compare.h"
 
 /* Net bridge is currently not supported for W32. */
 #if !defined(_WIN32)
@@ -1155,12 +1156,38 @@ void qmp_colo_passthrough_add(const char *prot, const 
uint32_t port,
   Error **errp)
 {
 /* Setup passthrough connection */
+if (port > 65536) {
+error_setg(errp, "COLO pass through get wrong port");
+return;
+}
+
+if (!strcmp(prot, "tcp") || !strcmp(prot, "TCP")) {
+colo_compare_passthrough_add(true, (uint16_t)port);
+} else if (!strcmp(prot, "udp") || !strcmp(prot, "UDP")) {
+colo_compare_passthrough_add(false, (uint16_t)port);
+} else {
+error_setg(errp, "COLO pass through just support tcp or udp protocol");
+return;
+}
 }
 
 void qmp_colo_passthrough_del(const char *prot, const uint32_t port,
   Error **errp)
 {
 /* Delete passthrough connection */
+if (port > 65536) {
+error_setg(errp, "COLO pass through get wrong port");
+return;
+}
+
+if (!strcmp(prot, "tcp") || !strcmp(prot, "TCP")) {
+colo_compare_passthrough_del(true, (uint16_t)port);
+} else if (!strcmp(prot, "udp") || !strcmp(prot, "UDP")) {
+

[PATCH 0/3] Bypass specific network traffic in COLO

2020-12-23 Thread Zhang Chen
From: Zhang Chen 

Since the real user scenario does not need to monitor all traffic.
This series give user ability to bypass kinds of network stream.

Zhang Chen (3):
  qapi/net: Add new QMP command for COLO passthrough
  hmp-commands: Add new HMP command for COLO passthrough
  net/colo-compare: Add handler for passthrough connection

 hmp-commands.hx   | 26 +++
 include/monitor/hmp.h |  2 ++
 monitor/hmp-cmds.c| 20 ++
 net/colo-compare.c| 49 +++
 net/colo-compare.h|  2 ++
 net/net.c | 39 ++
 qapi/net.json | 46 
 7 files changed, 184 insertions(+)

-- 
2.17.1




[PATCH 1/3] qapi/net: Add new QMP command for COLO passthrough

2020-12-23 Thread Zhang Chen
From: Zhang Chen 

Since the real user scenario does not need to monitor all traffic.
Add colo-passthrough-add and colo-passthrough-del to maintain
a COLO network passthrough list.

Signed-off-by: Zhang Chen 
---
 net/net.c | 12 
 qapi/net.json | 46 ++
 2 files changed, 58 insertions(+)

diff --git a/net/net.c b/net/net.c
index e1035f21d1..eac7a92618 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1151,6 +1151,18 @@ void qmp_netdev_del(const char *id, Error **errp)
 qemu_del_net_client(nc);
 }
 
+void qmp_colo_passthrough_add(const char *prot, const uint32_t port,
+  Error **errp)
+{
+/* Setup passthrough connection */
+}
+
+void qmp_colo_passthrough_del(const char *prot, const uint32_t port,
+  Error **errp)
+{
+/* Delete passthrough connection */
+}
+
 static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
 {
 char *str;
diff --git a/qapi/net.json b/qapi/net.json
index c31748c87f..466c29714e 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -714,3 +714,49 @@
 ##
 { 'event': 'FAILOVER_NEGOTIATED',
   'data': {'device-id': 'str'} }
+
+##
+# @colo-passthrough-add:
+#
+# Add passthrough entry according to customer's needs in COLO-compare.
+#
+# @protocol: COLO passthrough just support TCP and UDP.
+#
+# @port: TCP or UDP port number.
+#
+# Returns: Nothing on success
+#
+# Since: 5.3
+#
+# Example:
+#
+# -> { "execute": "colo-passthrough-add",
+#  "arguments": { "protocol": "tcp", "port": 3389 } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'colo-passthrough-add',
+ 'data': {'protocol': 'str', 'port': 'uint32'} }
+
+##
+# @colo-passthrough-del:
+#
+# Delete passthrough entry according to customer's needs in COLO-compare.
+#
+# @protocol: COLO passthrough just support TCP and UDP.
+#
+# @port: TCP or UDP port number.
+#
+# Returns: Nothing on success
+#
+# Since: 5.3
+#
+# Example:
+#
+# -> { "execute": "colo-passthrough-del",
+#  "arguments": { "protocol": "tcp", "port": 3389 } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'colo-passthrough-del',
+ 'data': {'protocol': 'str', 'port': 'uint32'} }
-- 
2.17.1




Re: [RFC PATCH 1/3] mm: support hugetlb free page reporting

2020-12-23 Thread Liang Li
> > > > +   spin_lock_irq(_lock);
> > > > +
> > > > +   if (huge_page_order(h) > MAX_ORDER)
> > > > +   budget = HUGEPAGE_REPORTING_CAPACITY;
> > > > +   else
> > > > +   budget = HUGEPAGE_REPORTING_CAPACITY * 32;
> > >
> > > Wouldn't huge_page_order always be more than MAX_ORDER? Seems like we
> > > don't even really need budget since this should probably be pulling
> > > out no more than one hugepage at a time.
> >
> > I want to disting a 2M page and 1GB page here. The order of 1GB page is 
> > greater
> > than MAX_ORDER while 2M page's order is less than MAX_ORDER.
>
> The budget here is broken. When I put the budget in page reporting it
> was so that we wouldn't try to report all of the memory in a given
> region. It is meant to hold us to no more than one pass through 1/16
> of the free memory. So essentially we will be slowly processing all of
> memory and it will take 16 calls (32 seconds) for us to process a
> system that is sitting completely idle. It is meant to pace us so we
> don't spend a ton of time doing work that will be undone, not to
> prevent us from burying a CPU which is what seems to be implied here.
>
> Using HUGEPAGE_REPORTING_CAPACITY makes no sense here. I was using it
> in the original definition because it was how many pages we could
> scoop out at a time and then I was aiming for a 16th of that. Here you
> are arbitrarily squaring HUGEPAGE_REPORTING_CAPACITY in terms of the
> amount of work you will doo since you are using it as a multiple
> instead of a divisor.
>
> > >
> > > > +   /* loop through free list adding unreported pages to sg list */
> > > > +   list_for_each_entry_safe(page, next, list, lru) {
> > > > +   /* We are going to skip over the reported pages. */
> > > > +   if (PageReported(page)) {
> > > > +   if (++scan_cnt >= MAX_SCAN_NUM) {
> > > > +   ret = scan_cnt;
> > > > +   break;
> > > > +   }
> > > > +   continue;
> > > > +   }
> > > > +
> > >
> > > It would probably have been better to place this set before your new
> > > set. I don't see your new set necessarily being the best use for page
> > > reporting.
> >
> > I haven't really latched on to what you mean, could you explain it again?
>
> It would be better for you to spend time understanding how this patch
> set works before you go about expanding it to do other things.
> Mistakes like the budget one above kind of point out the fact that you
> don't understand how this code was supposed to work and just kind of
> shoehorned you page zeroing code onto it.
>
> It would be better to look at trying to understand this code first
> before you extend it to support your zeroing use case. So adding huge
> pages first might make more sense than trying to zero and push the
> order down. The fact is the page reporting extension should be minimal
> for huge pages since they are just passed as a scatterlist so you
> should only need to add a small bit to page_reporting.c to extend it
> to support this use case.
>
> > >
> > > > +   /*
> > > > +* If we fully consumed our budget then update our
> > > > +* state to indicate that we are requesting additional
> > > > +* processing and exit this list.
> > > > +*/
> > > > +   if (budget < 0) {
> > > > +   atomic_set(>state, 
> > > > PAGE_REPORTING_REQUESTED);
> > > > +   next = page;
> > > > +   break;
> > > > +   }
> > > > +
> > >
> > > If budget is only ever going to be 1 then we probably could just look
> > > at making this the default case for any time we find a non-reported
> > > page.
> >
> > and here again.
>
> It comes down to the fact that the changes you made have a significant
> impact on how this is supposed to function. Reducing the scatterlist
> to a size of one makes the whole point of doing batching kind of
> pointless. Basically the code should be rewritten with the assumption
> that if you find a page you report it.
>
> The old code would batch things up because there is significant
> overhead to be addressed when going to the hypervisor to report said
> memory. Your code doesn't seem to really take anything like that into
> account and instead is using an arbitrary budget value based on the
> page size.
>
> > > > +   /* Attempt to pull page from list and place in 
> > > > scatterlist */
> > > > +   if (*offset) {
> > > > +   isolate_free_huge_page(page, h, nid);
> > > > +   /* Add page to scatter list */
> > > > +   --(*offset);
> > > > +   sg_set_page([*offset], page, page_len, 0);
> > > > +
> > > > +   continue;
> > > > +   }
> > > > +
> > >
> > > There is no point in the 

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread BALATON Zoltan via

On Wed, 23 Dec 2020, Guenter Roeck wrote:

On 12/23/20 12:20 PM, BALATON Zoltan wrote:

On Wed, 23 Dec 2020, Guenter Roeck wrote:

On 12/23/20 8:09 AM, Mark Cave-Ayland wrote:

On 23/12/2020 15:21, Philippe Mathieu-Daudé wrote:

FWIW bisecting Fuloong2E starts failing here:

4ea98d317eb442c738f898f16cfdd47a18b7ca49 is the first bad commit
commit 4ea98d317eb442c738f898f16cfdd47a18b7ca49
Author: BALATON Zoltan 
Date:   Fri Jan 25 14:52:12 2019 -0500

 ide/via: Implement and use native PCI IDE mode

 This device only implemented ISA compatibility mode and native PCI IDE
 mode was missing but no clients actually need ISA mode but to the
 contrary, they usually want to switch to and use device in native
 PCI IDE mode. Therefore implement native PCI mode and switch default
 to that.

 Signed-off-by: BALATON Zoltan 
 Message-id:
c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.bala...@eik.bme.hu
 Signed-off-by: John Snow 

  hw/ide/via.c | 52 ++--
  1 file changed, 38 insertions(+), 14 deletions(-)


I think the original version of the patch broke fuloong2e, however that should 
have been fixed by my patchset here: 
https://lists.gnu.org/archive/html/qemu-devel/2020-03/msg03936.html. It might 
be that there are multiple regressions located during a full bisect :/



Not really. The following patch on top of qemu 5.2 results in the ide drive
being detected and working.

diff --git a/hw/ide/via.c b/hw/ide/via.c
index be09912b33..1bfdc422ee 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -186,11 +186,14 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]);

    bmdma_setup_bar(d);
+#if 0
    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar);
+#endif

    qdev_init_gpio_in(ds, via_ide_set_irq, 2);
    for (i = 0; i < 2; i++) {
    ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2);
+    ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, i ? 0x376 : 
0x3f6);
    ide_init2(>bus[i], qdev_get_gpio_in(ds, i));

    bmdma_init(>bus[i], >bmdma[i], d);

With the added ide_init_ioport(), the drive is detected. With the #if 0,


This breaks MorphOS on pegasos2 so it's not acceptable for me as a fix. 
(Actually this just reverts my commit in a cryptic way.)


it actually starts working. So there are two problems: 1) The qemu ide
subsystem isn't informed about the io addresses, and 2) bmdma isn't working.


The problem rather seems to be that whatever you're trying to run can only 
handle legacy mode and does not correctly detect or work with native mode of 
this IDE controller. The real chip can switch between these modes and starts in 
legacy mode but most OSes with a better driver will switch to native mode 
during boot (in some cases the firmware will switch already). But we can't 
emulate that in QEMU easily because of how the IDE emulation is implemented: we 
either set up legacy ioports or use PCI BMDMA, I don't see a way to deregister 
legacy ports and irqs once the config reg is flipped to native mode. Therefore 
I've chosen to only emulate native mode which is what most guests want to use 
and some only work with that and I've tested this with the previously mentioned 
Linux version that it still detected and worked with the IDE ports. During 
testing I've found that Linux will use either native or legacy modes if the 
appropriate config bits are set but for some boards there may
be work arounds for specific quirks such as the case for pegasos2 with IRQs 
hardwired to legacy interrupts even in native mode where we need to follow what 
hardware does otherwise one or the other guest breaks. Maybe there's a similar 
quirk for the fuloong2e?

What guest OS are you running and did you confirm that it runs on the real 
machine? If you run recent Linux kernels and don't know if those still work 
with real hardware could this be a bug in the guest driver and not in QEMU? We 
know that we don't fully emulate this controller but there should be a way to 
set things up in a way that satisfies all guests and I've tried to do that when 
touching this part but possibly I did not have the right Linux version for the 
real machine as it was hard to find one distro that worked with it. Maybe 
Jiaxun has a known working Linux distro or kernel that we can use to check 
emulation with or knows more about how the VIA IDE port IRQs are wired on this 
board. (I've added Jiaxun again but the list seems to strip his addess.)



I don't have a real machine, and therefore did not test it on one.

I tried with Linux mainline (v5.10-12913-g614cb5894306), v3.16.85, v4.4.248,
and v4.14.212. I can't test older version because my cross compiler is too
new. Each of those kernel versions shows exactly the same behavior.


I think the original author of this device was Huacai so adding him to the 
thread too in case he remembers anything relevant, but code 

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Philippe Mathieu-Daudé
On Wed, Dec 23, 2020 at 11:47 PM Guenter Roeck  wrote:
>
> On Wed, Dec 23, 2020 at 10:05:12PM +, Mark Cave-Ayland wrote:
> > On 23/12/2020 21:01, Guenter Roeck wrote:
> >
> > > I don't have a real machine, and therefore did not test it on one.
> > >
> > > I tried with Linux mainline (v5.10-12913-g614cb5894306), v3.16.85, 
> > > v4.4.248,
> > > and v4.14.212. I can't test older version because my cross compiler is too
> > > new. Each of those kernel versions shows exactly the same behavior.
> >
> > Is it possible for you to provide links to your drive image and kernel so
> > that we can reproduce the same environment to investigate?
> >
>
> The root file system is available from
> https://github.com/groeck/linux-build-test/blob/master/rootfs/mipsel64/rootfs.mipsel.ext3.gz
>
> The script used to build the kernel is in available in
> the same directory, though building fuloong2e_defconfig
> should do it, possibly with CONFIG_DEVTMPFS=y added.

I directly used the prebuilt Debian kernel Jiaxun recently shared in:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg768711.html

vmlinux-3.16.0-6-loongson-2e from
http://archive.debian.org/debian/pool/main/l/linux/linux-image-3.16.0-6-loongson-2e_3.16.56-1+deb8u1_mipsel.deb



Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Guenter Roeck
On Wed, Dec 23, 2020 at 10:05:12PM +, Mark Cave-Ayland wrote:
> On 23/12/2020 21:01, Guenter Roeck wrote:
> 
> > I don't have a real machine, and therefore did not test it on one.
> > 
> > I tried with Linux mainline (v5.10-12913-g614cb5894306), v3.16.85, v4.4.248,
> > and v4.14.212. I can't test older version because my cross compiler is too
> > new. Each of those kernel versions shows exactly the same behavior.
> 
> Is it possible for you to provide links to your drive image and kernel so
> that we can reproduce the same environment to investigate?
> 

The root file system is available from
https://github.com/groeck/linux-build-test/blob/master/rootfs/mipsel64/rootfs.mipsel.ext3.gz

The script used to build the kernel is in available in
the same directory, though building fuloong2e_defconfig
should do it, possibly with CONFIG_DEVTMPFS=y added.

Guenter



Re: [PATCH v1 1/1] chardev: enable guest socket status/crontrol via DTR and DCD

2020-12-23 Thread Eric Blake
On 12/16/20 4:06 PM, Darrin M. Gorski wrote:
> This patch adds a 'modemctl' option to "-chardev socket" to enable control
> of the socket via the guest serial port.
> The default state of the option is disabled.
> 
> 1. disconnect a connected socket when DTR transitions to low, also reject
> new connections while DTR is low.
> 2. provide socket connection status through the carrier detect line (CD or
> DCD) on the guest serial port
> 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1213196
> 
> Signed-off-by: Darrin M. Gorski 
> 
> 
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c

Hmm - your workflow did not produce the usual --- marker and a diffstat
of which files were in the patch; this makes it easier for reviewers to
see at a glance what the rest of the email will contain.  It's not
essential, but it does help.


> +++ b/qapi/char.json
> @@ -271,6 +271,9 @@
>  # then attempt a reconnect after the given number of seconds.
>  # Setting this to zero disables this function. (default: 0)
>  # (Since: 2.2)
> +# @modemctl: allow guest to use modem control signals to control/monitor
> +#the socket state (CD follows is_connected, DTR influences
> +#connect/accept) (default: false) (Since: 5.2)

The next release will by 6.0, not 5.2.

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




[PATCH v3 4/7] qapi: Use QAPI_LIST_PREPEND() where possible

2020-12-23 Thread Eric Blake
Anywhere we create a list of just one item or by prepending items
(typically because order doesn't matter), we can use the
QAPI_LIST_PREPEND macro.  But places where we must keep the list in
order by appending remain open-coded until later patches.

Note that as a side effect, this also performs a cleanup of two minor
issues in qga/commands-posix.c: the old code was performing
 new = g_malloc0(sizeof(*ret));
which 1) is confusing because you have to verify whether 'new' and
'ret' are variables with the same type, and 2) would conflict with C++
compilation (not an actual problem for this file, but makes
copy-and-paste harder).

Signed-off-by: Eric Blake 
Reviewed-by: Markus Armbruster 
Acked-by: Stefan Hajnoczi 
---
 docs/devel/writing-qmp-commands.txt |  12 +--
 block/gluster.c |   4 +-
 block/qapi.c|   7 +-
 chardev/char.c  |  20 ++---
 hw/core/machine-qmp-cmds.c  |  38 +++---
 hw/core/machine.c   |  11 +--
 hw/net/rocker/rocker_of_dpa.c   |  20 ++---
 hw/net/virtio-net.c |  21 ++
 migration/migration.c   |   7 +-
 migration/postcopy-ram.c|   7 +-
 monitor/hmp-cmds.c  |  13 ++--
 monitor/misc.c  |  25 +++---
 monitor/qmp-cmds-control.c  |  10 +--
 qemu-img.c  |   5 +-
 qga/commands-posix-ssh.c|   7 +-
 qga/commands-posix.c|  47 +++-
 qga/commands-win32.c|  32 ++--
 qga/commands.c  |   6 +-
 qom/qom-qmp-cmds.c  |  29 ++-
 target/arm/helper.c |   6 +-
 target/arm/monitor.c|  13 +---
 target/i386/cpu.c   |   6 +-
 target/mips/cpu.c   |   6 +-
 target/s390x/cpu_models.c   |  12 +--
 tests/test-clone-visitor.c  |   7 +-
 tests/test-qobject-output-visitor.c |  42 +--
 tests/test-visitor-serialization.c  | 113 
 trace/qmp.c |  22 +++---
 ui/input.c  |  16 ++--
 ui/vnc.c|  21 ++
 util/qemu-config.c  |  14 +---
 target/ppc/translate_init.c.inc |  12 +--
 32 files changed, 169 insertions(+), 442 deletions(-)

diff --git a/docs/devel/writing-qmp-commands.txt 
b/docs/devel/writing-qmp-commands.txt
index 28984686c970..258e63bff5ee 100644
--- a/docs/devel/writing-qmp-commands.txt
+++ b/docs/devel/writing-qmp-commands.txt
@@ -531,15 +531,11 @@ TimerAlarmMethodList *qmp_query_alarm_methods(Error 
**errp)
 bool current = true;

 for (p = alarm_timers; p->name; p++) {
-TimerAlarmMethodList *info = g_malloc0(sizeof(*info));
-info->value = g_malloc0(sizeof(*info->value));
-info->value->method_name = g_strdup(p->name);
-info->value->current = current;
-
+TimerAlarmMethod *value = g_malloc0(*value);
+value->method_name = g_strdup(p->name);
+value->current = current;
+QAPI_LIST_PREPEND(method_list, value);
 current = false;
-
-info->next = method_list;
-method_list = info;
 }

 return method_list;
diff --git a/block/gluster.c b/block/gluster.c
index 4f1448e2bc88..1f8699b93835 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -359,8 +359,8 @@ static int qemu_gluster_parse_uri(BlockdevOptionsGluster 
*gconf,
 return -EINVAL;
 }

-gconf->server = g_new0(SocketAddressList, 1);
-gconf->server->value = gsconf = g_new0(SocketAddress, 1);
+gsconf = g_new0(SocketAddress, 1);
+QAPI_LIST_PREPEND(gconf->server, gsconf);

 /* transport */
 if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
diff --git a/block/qapi.c b/block/qapi.c
index 036da085eea6..0ca206f559fe 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -486,12 +486,7 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, 
BlockBackend *blk)
 ds->account_failed = stats->account_failed;

 while ((ts = block_acct_interval_next(stats, ts))) {
-BlockDeviceTimedStatsList *timed_stats =
-g_malloc0(sizeof(*timed_stats));
 BlockDeviceTimedStats *dev_stats = g_malloc0(sizeof(*dev_stats));
-timed_stats->next = ds->timed_stats;
-timed_stats->value = dev_stats;
-ds->timed_stats = timed_stats;

 TimedAverage *rd = >latency[BLOCK_ACCT_READ];
 TimedAverage *wr = >latency[BLOCK_ACCT_WRITE];
@@ -515,6 +510,8 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, 
BlockBackend *blk)
 block_acct_queue_depth(ts, BLOCK_ACCT_READ);
 dev_stats->avg_wr_queue_depth =
 block_acct_queue_depth(ts, BLOCK_ACCT_WRITE);
+
+QAPI_LIST_PREPEND(ds->timed_stats, dev_stats);
 }

 bdrv_latency_histogram_stats(>latency_histogram[BLOCK_ACCT_READ],
diff --git a/chardev/char.c b/chardev/char.c
index a9b8c5a9aac6..288efebd1257 100644
--- 

[PATCH v3 6/7] qapi: Use QAPI_LIST_APPEND in trivial cases

2020-12-23 Thread Eric Blake
The easiest spots to use QAPI_LIST_APPEND are where we already have an
obvious pointer to the tail of a list.  While at it, consistently use
the variable name 'tail' for that purpose.

Signed-off-by: Eric Blake 
---
 backends/hostmem.c  | 10 ++--
 block/dirty-bitmap.c|  8 ++-
 block/export/export.c   |  7 +--
 block/qapi.c| 23 ++--
 block/qcow2-bitmap.c| 15 ++
 block/vmdk.c|  9 ++--
 blockdev.c  | 13 ++---
 crypto/block-luks.c |  9 ++--
 hw/acpi/cpu.c   |  8 +--
 hw/acpi/memory_hotplug.c|  9 ++--
 iothread.c  | 12 ++---
 job-qmp.c   | 13 ++---
 monitor/hmp-cmds.c  | 10 ++--
 monitor/qmp-cmds-control.c  |  9 ++--
 qemu-img.c  |  8 +--
 qga/commands-posix.c| 31 ---
 qga/commands-win32.c| 11 ++--
 scsi/pr-manager.c   | 10 +---
 target/i386/cpu.c   | 23 +++-
 tests/test-qobject-output-visitor.c | 84 +
 tests/test-string-output-visitor.c  |  6 +--
 21 files changed, 99 insertions(+), 229 deletions(-)

diff --git a/backends/hostmem.c b/backends/hostmem.c
index 4bde00e8e74d..b4c83c1cfa29 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -80,7 +80,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, 
const char *name,
 {
 HostMemoryBackend *backend = MEMORY_BACKEND(obj);
 uint16List *host_nodes = NULL;
-uint16List **node = _nodes;
+uint16List **tail = _nodes;
 unsigned long value;

 value = find_first_bit(backend->host_nodes, MAX_NODES);
@@ -88,9 +88,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, 
const char *name,
 goto ret;
 }

-*node = g_malloc0(sizeof(**node));
-(*node)->value = value;
-node = &(*node)->next;
+QAPI_LIST_APPEND(tail, value);

 do {
 value = find_next_bit(backend->host_nodes, MAX_NODES, value + 1);
@@ -98,9 +96,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, 
const char *name,
 break;
 }

-*node = g_malloc0(sizeof(**node));
-(*node)->value = value;
-node = &(*node)->next;
+QAPI_LIST_APPEND(tail, value);
 } while (true);

 ret:
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index c01319b188c3..9b9cd712386c 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -572,12 +572,12 @@ BlockDirtyInfoList 
*bdrv_query_dirty_bitmaps(BlockDriverState *bs)
 {
 BdrvDirtyBitmap *bm;
 BlockDirtyInfoList *list = NULL;
-BlockDirtyInfoList **plist = 
+BlockDirtyInfoList **tail = 

 bdrv_dirty_bitmaps_lock(bs);
 QLIST_FOREACH(bm, >dirty_bitmaps, list) {
 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
-BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
+
 info->count = bdrv_get_dirty_count(bm);
 info->granularity = bdrv_dirty_bitmap_granularity(bm);
 info->has_name = !!bm->name;
@@ -588,9 +588,7 @@ BlockDirtyInfoList 
*bdrv_query_dirty_bitmaps(BlockDriverState *bs)
 info->persistent = bm->persistent;
 info->has_inconsistent = bm->inconsistent;
 info->inconsistent = bm->inconsistent;
-entry->value = info;
-*plist = entry;
-plist = >next;
+QAPI_LIST_APPEND(tail, info);
 }
 bdrv_dirty_bitmaps_unlock(bs);

diff --git a/block/export/export.c b/block/export/export.c
index b716c1522c5d..fec7d9f73820 100644
--- a/block/export/export.c
+++ b/block/export/export.c
@@ -342,11 +342,10 @@ void qmp_block_export_del(const char *id,

 BlockExportInfoList *qmp_query_block_exports(Error **errp)
 {
-BlockExportInfoList *head = NULL, **p_next = 
+BlockExportInfoList *head = NULL, **tail = 
 BlockExport *exp;

 QLIST_FOREACH(exp, _exports, next) {
-BlockExportInfoList *entry = g_new0(BlockExportInfoList, 1);
 BlockExportInfo *info = g_new(BlockExportInfo, 1);
 *info = (BlockExportInfo) {
 .id = g_strdup(exp->id),
@@ -355,9 +354,7 @@ BlockExportInfoList *qmp_query_block_exports(Error **errp)
 .shutting_down  = !exp->user_owned,
 };

-entry->value = info;
-*p_next = entry;
-p_next = >next;
+QAPI_LIST_APPEND(tail, info);
 }

 return head;
diff --git a/block/qapi.c b/block/qapi.c
index 0ca206f559fe..3a1186fdccf5 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -418,17 +418,12 @@ static uint64List *uint64_list(uint64_t *list, int size)
 {
 int i;
 uint64List *out_list = NULL;
-uint64List **pout_list = _list;
+uint64List **tail = _list;

 for (i = 0; i < size; i++) {
-uint64List *entry = g_new(uint64List, 1);
-entry->value = list[i];
-*pout_list = entry;
-

[PATCH v3 5/7] qapi: Introduce QAPI_LIST_APPEND

2020-12-23 Thread Eric Blake
Similar to the existing QAPI_LIST_PREPEND, but designed for use where
we want to preserve insertion order.  Callers will be added in
upcoming patches.  Note the difference in signature: PREPEND takes
List*, APPEND takes List**.

Signed-off-by: Eric Blake 
---
 include/qapi/util.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/include/qapi/util.h b/include/qapi/util.h
index 6178e98e97a5..8b4967990c0d 100644
--- a/include/qapi/util.h
+++ b/include/qapi/util.h
@@ -37,4 +37,17 @@ int parse_qapi_name(const char *name, bool complete);
 (list) = _tmp; \
 } while (0)

+/*
+ * For any pointer to a GenericList @tail, insert @element at the back and
+ * update the tail.
+ *
+ * Note that this macro evaluates @element exactly once, so it is safe
+ * to have side-effects with that argument.
+ */
+#define QAPI_LIST_APPEND(tail, element) do { \
+*(tail) = g_malloc0(sizeof(**(tail))); \
+(*(tail))->value = (element); \
+(tail) = &(*tail)->next; \
+} while (0)
+
 #endif
-- 
2.29.2




[PATCH v3 1/7] net: Clarify early exit condition

2020-12-23 Thread Eric Blake
On first glance, the loop in qmp_query_rx_filter() has early return
paths that could leak any allocation of filter_list from a previous
iteration.  But on closer inspection, it is obvious that all of the
early exits are guarded by has_name, and that the bulk of the loop
body can be executed at most once if the user is filtering by name,
thus, any early exit coincides with an empty list.  Add asserts to
make this obvious.

Signed-off-by: Eric Blake 
---
 net/net.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/net.c b/net/net.c
index e1035f21d183..e581c8a26868 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1211,6 +1211,7 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, 
const char *name,
 if (nc->info->type != NET_CLIENT_DRIVER_NIC) {
 if (has_name) {
 error_setg(errp, "net client(%s) isn't a NIC", name);
+assert(!filter_list);
 return NULL;
 }
 continue;
@@ -1236,6 +1237,7 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, 
const char *name,
 } else if (has_name) {
 error_setg(errp, "net client(%s) doesn't support"
" rx-filter querying", name);
+assert(!filter_list);
 return NULL;
 }

-- 
2.29.2




[PATCH v3 7/7] qapi: More complex uses of QAPI_LIST_APPEND

2020-12-23 Thread Eric Blake
These cases require a bit more thought to review; in each case, the
code was appending to a list, but not with a FOOList **tail variable.

Signed-off-by: Eric Blake 
---
 block/gluster.c| 13 ++
 block/qapi.c   | 14 +-
 dump/dump.c| 22 +++--
 hw/core/machine-qmp-cmds.c | 93 -
 hw/mem/memory-device.c | 12 +
 hw/pci/pci.c   | 60 
 migration/migration.c  | 20 +++-
 monitor/hmp-cmds.c | 25 --
 net/net.c  | 13 +-
 qga/commands-posix.c   | 94 ++
 qga/commands-win32.c   | 88 ---
 softmmu/tpm.c  | 38 +++
 ui/spice-core.c| 27 ---
 13 files changed, 170 insertions(+), 349 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 1f8699b93835..e8ee14c8e9bf 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -514,7 +514,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 {
 QemuOpts *opts;
 SocketAddress *gsconf = NULL;
-SocketAddressList *curr = NULL;
+SocketAddressList **tail;
 QDict *backing_options = NULL;
 Error *local_err = NULL;
 char *str = NULL;
@@ -547,6 +547,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 }
 gconf->path = g_strdup(ptr);
 qemu_opts_del(opts);
+tail = >server;

 for (i = 0; i < num_servers; i++) {
 str = g_strdup_printf(GLUSTER_OPT_SERVER_PATTERN"%d.", i);
@@ -655,15 +656,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 qemu_opts_del(opts);
 }

-if (gconf->server == NULL) {
-gconf->server = g_new0(SocketAddressList, 1);
-gconf->server->value = gsconf;
-curr = gconf->server;
-} else {
-curr->next = g_new0(SocketAddressList, 1);
-curr->next->value = gsconf;
-curr = curr->next;
-}
+QAPI_LIST_APPEND(tail, gsconf);
 gsconf = NULL;

 qobject_unref(backing_options);
diff --git a/block/qapi.c b/block/qapi.c
index 3a1186fdccf5..0a96099e36e2 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -198,7 +198,7 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
 {
 int i, sn_count;
 QEMUSnapshotInfo *sn_tab = NULL;
-SnapshotInfoList *info_list, *cur_item = NULL, *head = NULL;
+SnapshotInfoList *head = NULL, **tail = 
 SnapshotInfo *info;

 sn_count = bdrv_snapshot_list(bs, _tab);
@@ -233,17 +233,7 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
 info->icount= sn_tab[i].icount;
 info->has_icount= sn_tab[i].icount != -1ULL;

-info_list = g_new0(SnapshotInfoList, 1);
-info_list->value = info;
-
-/* XXX: waiting for the qapi to support qemu-queue.h types */
-if (!cur_item) {
-head = cur_item = info_list;
-} else {
-cur_item->next = info_list;
-cur_item = info_list;
-}
-
+QAPI_LIST_APPEND(tail, info);
 }

 g_free(sn_tab);
diff --git a/dump/dump.c b/dump/dump.c
index dec32468d98c..929138e91d08 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -2030,39 +2030,29 @@ void qmp_dump_guest_memory(bool paging, const char 
*file,

 DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
 {
-DumpGuestMemoryFormatList *item;
 DumpGuestMemoryCapability *cap =
   g_malloc0(sizeof(DumpGuestMemoryCapability));
+DumpGuestMemoryFormatList **tail = >formats;

 /* elf is always available */
-item = g_malloc0(sizeof(DumpGuestMemoryFormatList));
-cap->formats = item;
-item->value = DUMP_GUEST_MEMORY_FORMAT_ELF;
+QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_ELF);

 /* kdump-zlib is always available */
-item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
-item = item->next;
-item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
+QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB);

 /* add new item if kdump-lzo is available */
 #ifdef CONFIG_LZO
-item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
-item = item->next;
-item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
+QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO);
 #endif

 /* add new item if kdump-snappy is available */
 #ifdef CONFIG_SNAPPY
-item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
-item = item->next;
-item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
+QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY);
 #endif

 /* Windows dump is available only if target is x86_64 */
 #ifdef TARGET_X86_64
-item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
-item = item->next;
-item->value = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP;
+

[PATCH v3 3/7] migration: Refactor migrate_cap_add

2020-12-23 Thread Eric Blake
Instead of taking a list parameter and returning a new head at a
distance, just return the new item for the caller to insert into a
list via QAPI_LIST_PREPEND.  Update some variable names to avoid long
lines, and drop a useless comment.

Signed-off-by: Eric Blake 
Reviewed-by: Markus Armbruster 
---
 migration/migration.c | 29 +
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index e0dbde4091c9..bba6e5148138 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1654,29 +1654,27 @@ void migrate_set_state(int *state, int old_state, int 
new_state)
 }
 }

-static MigrationCapabilityStatusList *migrate_cap_add(
-MigrationCapabilityStatusList *list,
-MigrationCapability index,
-bool state)
+static MigrationCapabilityStatus *migrate_cap_add(MigrationCapability index,
+  bool state)
 {
-MigrationCapabilityStatusList *cap;
+MigrationCapabilityStatus *cap;

-cap = g_new0(MigrationCapabilityStatusList, 1);
-cap->value = g_new0(MigrationCapabilityStatus, 1);
-cap->value->capability = index;
-cap->value->state = state;
-cap->next = list;
+cap = g_new0(MigrationCapabilityStatus, 1);
+cap->capability = index;
+cap->state = state;

 return cap;
 }

 void migrate_set_block_enabled(bool value, Error **errp)
 {
-MigrationCapabilityStatusList *cap;
+MigrationCapabilityStatusList *caps = NULL;
+MigrationCapabilityStatus *cap;

-cap = migrate_cap_add(NULL, MIGRATION_CAPABILITY_BLOCK, value);
-qmp_migrate_set_capabilities(cap, errp);
-qapi_free_MigrationCapabilityStatusList(cap);
+cap = migrate_cap_add(MIGRATION_CAPABILITY_BLOCK, value);
+QAPI_LIST_PREPEND(caps, cap);
+qmp_migrate_set_capabilities(caps, errp);
+qapi_free_MigrationCapabilityStatusList(caps);
 }

 static void migrate_set_block_incremental(MigrationState *s, bool value)
@@ -3863,13 +3861,12 @@ static bool migration_object_check(MigrationState *ms, 
Error **errp)

 for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
 if (ms->enabled_capabilities[i]) {
-head = migrate_cap_add(head, i, true);
+QAPI_LIST_PREPEND(head, migrate_cap_add(i, true));
 }
 }

 ret = migrate_caps_check(cap_list, head, errp);

-/* It works with head == NULL */
 qapi_free_MigrationCapabilityStatusList(head);

 return ret;
-- 
2.29.2




[PATCH v3 0/7] Common macros for QAPI list growth

2020-12-23 Thread Eric Blake
I worked on rebasing this while not checking my emails, and now that
I'm writing it up, I see that Markus already has incorporated earlier
patches in the v2 series into his tree.  So I may have to rebase yet
again, but it's at least time for me to get this on list again.

v2 was here:
https://lists.gnu.org/archive/html/qemu-devel/2020-11/msg03457.html

Since then: address review comments, use the name 'tail' in more
places, rebase to master

Eric Blake (7):
  net: Clarify early exit condition
  rocker: Revamp fp_port_get_info
  migration: Refactor migrate_cap_add
  qapi: Use QAPI_LIST_PREPEND() where possible
  qapi: Introduce QAPI_LIST_APPEND
  qapi: Use QAPI_LIST_APPEND in trivial cases
  qapi: More complex uses of QAPI_LIST_APPEND

 docs/devel/writing-qmp-commands.txt |  12 +-
 hw/net/rocker/rocker_fp.h   |   2 +-
 include/qapi/util.h |  13 +++
 backends/hostmem.c  |  10 +-
 block/dirty-bitmap.c|   8 +-
 block/export/export.c   |   7 +-
 block/gluster.c |  17 +--
 block/qapi.c|  44 ++-
 block/qcow2-bitmap.c|  15 +--
 block/vmdk.c|   9 +-
 blockdev.c  |  13 +--
 chardev/char.c  |  20 ++--
 crypto/block-luks.c |   9 +-
 dump/dump.c |  22 +---
 hw/acpi/cpu.c   |   8 +-
 hw/acpi/memory_hotplug.c|   9 +-
 hw/core/machine-qmp-cmds.c  | 131 +
 hw/core/machine.c   |  11 +-
 hw/mem/memory-device.c  |  12 +-
 hw/net/rocker/rocker.c  |   8 +-
 hw/net/rocker/rocker_fp.c   |  17 +--
 hw/net/rocker/rocker_of_dpa.c   |  20 +---
 hw/net/virtio-net.c |  21 ++--
 hw/pci/pci.c|  60 +++---
 iothread.c  |  12 +-
 job-qmp.c   |  13 +--
 migration/migration.c   |  56 -
 migration/postcopy-ram.c|   7 +-
 monitor/hmp-cmds.c  |  48 
 monitor/misc.c  |  25 ++--
 monitor/qmp-cmds-control.c  |  19 ++-
 net/net.c   |  15 +--
 qemu-img.c  |  13 +--
 qga/commands-posix-ssh.c|   7 +-
 qga/commands-posix.c| 172 +---
 qga/commands-win32.c| 131 +++--
 qga/commands.c  |   6 +-
 qom/qom-qmp-cmds.c  |  29 ++---
 scsi/pr-manager.c   |  10 +-
 softmmu/tpm.c   |  38 +-
 target/arm/helper.c |   6 +-
 target/arm/monitor.c|  13 +--
 target/i386/cpu.c   |  29 ++---
 target/mips/cpu.c   |   6 +-
 target/s390x/cpu_models.c   |  12 +-
 tests/test-clone-visitor.c  |   7 +-
 tests/test-qobject-output-visitor.c | 126 +++-
 tests/test-string-output-visitor.c  |   6 +-
 tests/test-visitor-serialization.c  | 113 +++---
 trace/qmp.c |  22 ++--
 ui/input.c  |  16 ++-
 ui/spice-core.c |  27 ++---
 ui/vnc.c|  21 +---
 util/qemu-config.c  |  14 +--
 target/ppc/translate_init.c.inc |  12 +-
 55 files changed, 478 insertions(+), 1051 deletions(-)

-- 
2.29.2




[PATCH v3 2/7] rocker: Revamp fp_port_get_info

2020-12-23 Thread Eric Blake
Instead of modifying the value member of a list element passed as a
parameter, and open-coding the manipulation of that list, it's nicer
to just return a freshly allocated value to be prepended to a list
using QAPI_LIST_PREPEND.

Signed-off-by: Eric Blake 
Reviewed-by: Markus Armbruster 
---
 hw/net/rocker/rocker_fp.h |  2 +-
 hw/net/rocker/rocker.c|  8 +---
 hw/net/rocker/rocker_fp.c | 17 ++---
 3 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/net/rocker/rocker_fp.h b/hw/net/rocker/rocker_fp.h
index dbe1dd329a4b..7ff57aac0180 100644
--- a/hw/net/rocker/rocker_fp.h
+++ b/hw/net/rocker/rocker_fp.h
@@ -28,7 +28,7 @@ int fp_port_eg(FpPort *port, const struct iovec *iov, int 
iovcnt);

 char *fp_port_get_name(FpPort *port);
 bool fp_port_get_link_up(FpPort *port);
-void fp_port_get_info(FpPort *port, RockerPortList *info);
+RockerPort *fp_port_get_info(FpPort *port);
 void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr);
 void fp_port_set_macaddr(FpPort *port, MACAddr *macaddr);
 uint8_t fp_port_get_learning(FpPort *port);
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index 1af1e6fa2f9b..c53a02315e54 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -127,13 +127,7 @@ RockerPortList *qmp_query_rocker_ports(const char *name, 
Error **errp)
 }

 for (i = r->fp_ports - 1; i >= 0; i--) {
-RockerPortList *info = g_malloc0(sizeof(*info));
-info->value = g_malloc0(sizeof(*info->value));
-struct fp_port *port = r->fp_port[i];
-
-fp_port_get_info(port, info);
-info->next = list;
-list = info;
+QAPI_LIST_PREPEND(list, fp_port_get_info(r->fp_port[i]));
 }

 return list;
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index 4aa7da79b81d..cbeed65bd5ec 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -51,14 +51,17 @@ bool fp_port_get_link_up(FpPort *port)
 return !qemu_get_queue(port->nic)->link_down;
 }

-void fp_port_get_info(FpPort *port, RockerPortList *info)
+RockerPort *fp_port_get_info(FpPort *port)
 {
-info->value->name = g_strdup(port->name);
-info->value->enabled = port->enabled;
-info->value->link_up = fp_port_get_link_up(port);
-info->value->speed = port->speed;
-info->value->duplex = port->duplex;
-info->value->autoneg = port->autoneg;
+RockerPort *value = g_malloc0(sizeof(*value));
+
+value->name = g_strdup(port->name);
+value->enabled = port->enabled;
+value->link_up = fp_port_get_link_up(port);
+value->speed = port->speed;
+value->duplex = port->duplex;
+value->autoneg = port->autoneg;
+return value;
 }

 void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr)
-- 
2.29.2




Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Mark Cave-Ayland

On 23/12/2020 21:01, Guenter Roeck wrote:


I don't have a real machine, and therefore did not test it on one.

I tried with Linux mainline (v5.10-12913-g614cb5894306), v3.16.85, v4.4.248,
and v4.14.212. I can't test older version because my cross compiler is too
new. Each of those kernel versions shows exactly the same behavior.


Is it possible for you to provide links to your drive image and kernel so that we can 
reproduce the same environment to investigate?



ATB,

Mark.



Re: [PATCH v15 08/20] multi-process: add qio channel read function

2020-12-23 Thread Jag Raman



> On Dec 23, 2020, at 6:24 AM, Marc-André Lureau  
> wrote:
> 
> Hi
> 
> On Wed, Dec 23, 2020 at 10:17 AM  wrote:
> From: Elena Ufimtseva 
> 
> Adds qio_channel_readv_full_all() to read both data and FDs.
> Refactors existing code to use this function.
> 
> Signed-off-by: Elena Ufimtseva 
> Signed-off-by: John G Johnson 
> Signed-off-by: Jagannathan Raman 
> ---
>  include/io/channel.h | 25 +
>  io/channel.c | 85 +++-
>  2 files changed, 85 insertions(+), 25 deletions(-)
> 
> diff --git a/include/io/channel.h b/include/io/channel.h
> index 2378567d4b..429ece9a05 100644
> --- a/include/io/channel.h
> +++ b/include/io/channel.h
> @@ -774,6 +774,31 @@ void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
>  IOHandler *io_write,
>  void *opaque);
> 
> +/**
> + * qio_channel_readv_full_all:
> + * @ioc: the channel object
> + * @iov: the array of memory regions to read data to
> + * @niov: the length of the @iov array
> + * @fds: an array of file handles to read
> + * @nfds: number of file handles in @fds
> + * @errp: pointer to a NULL-initialized error object
> + *
> + *
> + * Behaves like qio_channel_readv_full but will attempt
> + * to read all data specified (file handles and memory regions).
> + * The function will wait for all requested data
> + * to be read, yielding from the current coroutine
> + * if required.
> + *
> + * Returns: 0 if all bytes were read, or -1 on error
> 
> It may also returns -ECANCEL. I am not sure it's a good idea. 
> 
> + */
> +
> +int qio_channel_readv_full_all(QIOChannel *ioc,
> +const struct iovec *iov,
> +size_t niov,
> +int **fds, size_t *nfds,
> +Error **errp);
> +
>  /**
>   * qio_channel_writev_full_all:
>   * @ioc: the channel object
> diff --git a/io/channel.c b/io/channel.c
> index bde1f6d0f4..5edaea1fac 100644
> --- a/io/channel.c
> +++ b/io/channel.c
> @@ -91,11 +91,49 @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
>const struct iovec *iov,
>size_t niov,
>Error **errp)
> +{
> +int ret = qio_channel_readv_full_all(ioc, iov, niov, NULL, NULL, errp);
> +
> +if (ret == -ECANCELED) {
> 
>  No io/ functions use -errno return values so far.
> 
> Maybe the simplest is to use the same return values as read_all_eof:
>  * Returns: 1 if all bytes were read, 0 if end-of-file occurs
>  *  without data, or -1 on error

Hi Marc-Andre,

qio_channel_readv_all_eof() also sets the Error variable when the channel
is closed in the middle of reading (partial read).

qio_channel_readv_full_all() needs to return a special value to
qio_channel_readv_all_eof() in the case of partial reads, aside
from '-1' for all other error scenarios. qio_channel_readv_full_all()
returns '-ECANCEL' to identify partial reads.

qio_channel_readv_full_all() could directly set this error variable for partial
read scenarios, but then there wouldn't be any difference between the
_full_all() version and _all_eof() version. Is that alright?

Thank you!
—
Jag


> 
> +error_prepend(errp,
> +  "Unexpected end-of-file before all bytes were read: ");
> +ret = -1;
> +}
> +
> +return ret;
> +}
> +
> +int qio_channel_readv_all(QIOChannel *ioc,
> +  const struct iovec *iov,
> +  size_t niov,
> +  Error **errp)
> +{
> +int ret = qio_channel_readv_all_eof(ioc, iov, niov, errp); 
> +
> 
> It looks like it would make more sense to call readv_full_all directly 
> instead now.
> 
> +if (ret == 0) {
> +error_setg(errp,
> +   "Unexpected end-of-file before all bytes were read");
> +return -1;
> +}
> +if (ret == 1) {
> +return 0;
> +}
> +
> +return ret;
> +}
> +
> +int qio_channel_readv_full_all(QIOChannel *ioc,
> +const struct iovec *iov,
> +size_t niov,
> +int **fds, size_t *nfds,
> +Error **errp)
>  {
>  int ret = -1;
>  struct iovec *local_iov = g_new(struct iovec, niov);
>  struct iovec *local_iov_head = local_iov;
>  unsigned int nlocal_iov = niov;
> +int **local_fds = fds;
> +size_t *local_nfds = nfds;
>  bool partial = false;
> 
>  nlocal_iov = iov_copy(local_iov, nlocal_iov,
> @@ -104,7 +142,8 @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
> 
>  while (nlocal_iov > 0) {
>  ssize_t len;
> -len = qio_channel_readv(ioc, local_iov, nlocal_iov, errp);
> +len = qio_channel_readv_full(ioc, local_iov, nlocal_iov, local_fds,
> + local_nfds, errp);
>  if (len 

Re: [PATCH v2] acpi: Permit OEM ID and OEM table ID fields to be changed

2020-12-23 Thread Marian Posteuca


Thanks for the thorough review.

Igor Mammedov  writes:
> On Tue, 22 Dec 2020 13:33:53 +0200
> Marian Posteuca  wrote:
>
> I see defaults are now initialized in pcmc->oem_[table_]id fields,
> and sometimes used from there, so question is why
> do we need use_sig_oem and keeping old code
>
> if (oem_id) { 
>
> strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id); 
>
> } else {  
>
> memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
>
> } 
>
>   
>
> if ()) {  
> strncpy((char *)h->oem_table_id, oem_table_id, 
> sizeof(h->oem_table_id)); 
> } else {  
>
> memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);  
>
> memcpy(h->oem_table_id + 4, sig, 4);  
>
> }  
> I'd rather drop 'else' branches altogether and simplify to something like this
>
> g_assert(oem_id);
> strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
> g_assert(oem_table_id)
> strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
> + padding
>
> and make sure ids are properly propagated everywhere.
>

I'm not sure if I understood this point correctly. You want to remove the 
appending
of the sig part to the oem_table_id field, and just use whatever is
passed by the caller for oem_table_id?





[PATCH] gdbstub.c uses incorrect check for active gdb in use_gdb_syscalls

2020-12-23 Thread Keith Packard via
When checking whether there is a live gdb connection, code shouldn't
use 'gdbserver_state.init' as that value is set when the
gdbserver_state structure is initialized in init_gdbserver_state, not
when the gdb socket has a valid connection.

The 'handle_detach' function appears to use 'gdbserver_state.c_cpu' as
an indication of whether there is a connection, so I've used the same
in use_gdb_syscalls.

This avoids a segfault when qemu is run with the '-s' flag (create a
gdb protocol socket), but without the '-S' flag (delay until 'c'
command is received).

I would like this patch to inform a discussion on whether the numerous
other places using gdbserver_state.init are also incorrect (most of
them appear to be using it in the same way use_gdb_syscalls does), and
also whether use_gdb_syscalls should cache the result of this check or
whether it should check each time it is called to see if a gdb
connection is currently acive. For the second question, I don't have a
clear idea; mixing gdb and native calls seems problematic for stateful
operations like file open/close.

Signed-off-by: Keith Packard 
---
 gdbstub.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdbstub.c b/gdbstub.c
index d99bc0bf2e..4e709d16fd 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -460,7 +460,7 @@ int use_gdb_syscalls(void)
 /* -semihosting-config target=auto */
 /* On the first call check if gdb is connected and remember. */
 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
-gdb_syscall_mode = gdbserver_state.init ?
+gdb_syscall_mode = gdbserver_state.c_cpu != NULL ?
 GDB_SYS_ENABLED : GDB_SYS_DISABLED;
 }
 return gdb_syscall_mode == GDB_SYS_ENABLED;
-- 
2.29.2




[PULL 10/15] qdev: Make PropertyInfo.create return ObjectProperty*

2020-12-23 Thread Eduardo Habkost
Returning ObjectProperty* will be useful for new property
registration code that will add additional callbacks
to ObjectProperty after registering it.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-25-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties.c| 12 ++--
 include/hw/qdev-properties.h |  3 ++-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 92f48ecbf2..3bb05e7d0d 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -821,13 +821,13 @@ const PropertyInfo qdev_prop_size = {
 
 /* --- object link property --- */
 
-static void create_link_property(ObjectClass *oc, const char *name,
- Property *prop)
+static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
+Property *prop)
 {
-object_class_property_add_link(oc, name, prop->link_type,
-   prop->offset,
-   qdev_prop_allow_set_link_before_realize,
-   OBJ_PROP_LINK_STRONG);
+return object_class_property_add_link(oc, name, prop->link_type,
+  prop->offset,
+  
qdev_prop_allow_set_link_before_realize,
+  OBJ_PROP_LINK_STRONG);
 }
 
 const PropertyInfo qdev_prop_link = {
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index ab9c538ba4..aae882317a 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -34,7 +34,8 @@ struct PropertyInfo {
 const QEnumLookup *enum_table;
 int (*print)(Object *obj, Property *prop, char *dest, size_t len);
 void (*set_default_value)(ObjectProperty *op, const Property *prop);
-void (*create)(ObjectClass *oc, const char *name, Property *prop);
+ObjectProperty *(*create)(ObjectClass *oc, const char *name,
+  Property *prop);
 ObjectPropertyAccessor *get;
 ObjectPropertyAccessor *set;
 ObjectPropertyRelease *release;
-- 
2.28.0




[PULL 14/15] qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen()

2020-12-23 Thread Eduardo Habkost
We're just doing pointer math with the device pointer, we can
simply use obj instead.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-32-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index f3bbf05465..50f40949f5 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -559,10 +559,9 @@ static void set_prop_arraylen(Object *obj, Visitor *v, 
const char *name,
  * array-length field in the device struct, we have to create the
  * array itself and dynamically add the corresponding properties.
  */
-DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
 uint32_t *alenptr = object_field_prop_ptr(obj, prop);
-void **arrayptr = (void *)dev + prop->arrayoffset;
+void **arrayptr = (void *)obj + prop->arrayoffset;
 void *eltptr;
 const char *arrayname;
 int i;
@@ -602,7 +601,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, 
const char *name,
  * they get the right answer despite the array element not actually
  * being inside the device struct.
  */
-arrayprop->prop.offset = eltptr - (void *)dev;
+arrayprop->prop.offset = eltptr - (void *)obj;
 assert(object_field_prop_ptr(obj, >prop) == eltptr);
 object_property_add(obj, propname,
 arrayprop->prop.info->name,
-- 
2.28.0




[PULL 15/15] bugfix: hostmem: Free host_nodes list right after visited

2020-12-23 Thread Eduardo Habkost
From: Keqian Zhu 

In host_memory_backend_get_host_nodes, we build host_nodes
list and output it to v (a StringOutputVisitor) but forget
to free the list. This fixes the memory leak.

The memory leak stack:

 Direct leak of 32 byte(s) in 2 object(s) allocated from:
#0 0xfffda30b3393 in __interceptor_calloc (/usr/lib64/libasan.so.4+0xd3393)
#1 0xfffda1d28b9b in g_malloc0 (/usr/lib64/libglib-2.0.so.0+0x58b9b)
#2 0xaaab05ca6e43 in host_memory_backend_get_host_nodes 
backends/hostmem.c:94
#3 0xaaab061ddf83 in object_property_get_uint16List qom/object.c:1478
#4 0xaaab05866513 in query_memdev hw/core/machine-qmp-cmds.c:312
#5 0xaaab061d980b in do_object_child_foreach qom/object.c:1001
#6 0xaaab0586779b in qmp_query_memdev hw/core/machine-qmp-cmds.c:328
#7 0xaaab0615ed3f in qmp_marshal_query_memdev 
qapi/qapi-commands-machine.c:327
#8 0xaaab0632d647 in do_qmp_dispatch qapi/qmp-dispatch.c:147
#9 0xaaab0632d647 in qmp_dispatch qapi/qmp-dispatch.c:190
#10 0xaaab0610f74b in monitor_qmp_dispatch monitor/qmp.c:120
#11 0xaaab0611074b in monitor_qmp_bh_dispatcher monitor/qmp.c:209
#12 0xaaab063caefb in aio_bh_poll util/async.c:117
#13 0xaaab063d30fb in aio_dispatch util/aio-posix.c:459
#14 0xaaab063cac8f in aio_ctx_dispatch util/async.c:268
#15 0xfffda1d22a6b in g_main_context_dispatch 
(/usr/lib64/libglib-2.0.so.0+0x52a6b)
#16 0xaaab063d0e97 in glib_pollfds_poll util/main-loop.c:218
#17 0xaaab063d0e97 in os_host_main_loop_wait util/main-loop.c:241
#18 0xaaab063d0e97 in main_loop_wait util/main-loop.c:517
#19 0xaaab05c8bfa7 in main_loop /root/rpmbuild/BUILD/qemu-4.1.0/vl.c:1791
#20 0xaaab05713bc3 in main /root/rpmbuild/BUILD/qemu-4.1.0/vl.c:4473
#21 0xfffda0a83ebf in __libc_start_main (/usr/lib64/libc.so.6+0x23ebf)
#22 0xaaab0571ed5f  (aarch64-softmmu/qemu-system-aarch64+0x88ed5f)
 SUMMARY: AddressSanitizer: 32 byte(s) leaked in 2 allocation(s).

Fixes: 4cf1b76bf1e2 (hostmem: add properties for NUMA memory policy)
Reported-by: Euler Robot 
Signed-off-by: Keqian Zhu 
Tested-by: Chen Qun 
Reviewed-by: Igor Mammedov 
Message-Id: <20201210075226.20196-1-zhukeqi...@huawei.com>
Signed-off-by: Eduardo Habkost 
---
 backends/hostmem.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/backends/hostmem.c b/backends/hostmem.c
index 4bde00e8e7..9f9ac95edd 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -105,6 +105,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, 
const char *name,
 
 ret:
 visit_type_uint16List(v, name, _nodes, errp);
+qapi_free_uint16List(host_nodes);
 }
 
 static void
-- 
2.28.0




[PULL 09/15] qdev: Move dev->realized check to qdev_property_set()

2020-12-23 Thread Eduardo Habkost
Every single qdev property setter function manually checks
dev->realized.  We can just check dev->realized inside
qdev_property_set() instead.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Stefan Berger 
Reviewed-by: Cornelia Huck 
Reviewed-by: Igor Mammedov 
Acked-by: Paul Durrant 
Message-Id: <20201211220529.2290218-24-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties-system.c |  70 --
 hw/core/qdev-properties.c| 100 ++-
 backends/tpm/tpm_util.c  |   6 --
 hw/block/xen-block.c |   6 --
 hw/s390x/css.c   |   6 --
 hw/s390x/s390-pci-bus.c  |   6 --
 hw/vfio/pci-quirks.c |   6 --
 target/sparc/cpu.c   |   6 --
 8 files changed, 18 insertions(+), 188 deletions(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 42529c3b65..f31aea3de1 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -94,11 +94,6 @@ static void set_drive_helper(Object *obj, Visitor *v, const 
char *name,
 bool blk_created = false;
 int ret;
 
-if (dev->realized) {
-qdev_prop_set_after_realize(dev, name, errp);
-return;
-}
-
 if (!visit_type_str(v, name, , errp)) {
 return;
 }
@@ -230,17 +225,11 @@ static void get_chr(Object *obj, Visitor *v, const char 
*name, void *opaque,
 static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 Error **errp)
 {
-DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
 CharBackend *be = qdev_get_prop_ptr(obj, prop);
 Chardev *s;
 char *str;
 
-if (dev->realized) {
-qdev_prop_set_after_realize(dev, name, errp);
-return;
-}
-
 if (!visit_type_str(v, name, , errp)) {
 return;
 }
@@ -311,18 +300,12 @@ static void get_mac(Object *obj, Visitor *v, const char 
*name, void *opaque,
 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 Error **errp)
 {
-DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
 MACAddr *mac = qdev_get_prop_ptr(obj, prop);
 int i, pos;
 char *str;
 const char *p;
 
-if (dev->realized) {
-qdev_prop_set_after_realize(dev, name, errp);
-return;
-}
-
 if (!visit_type_str(v, name, , errp)) {
 return;
 }
@@ -390,7 +373,6 @@ static void get_netdev(Object *obj, Visitor *v, const char 
*name,
 static void set_netdev(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
 {
-DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
 NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
 NetClientState **ncs = peers_ptr->ncs;
@@ -398,11 +380,6 @@ static void set_netdev(Object *obj, Visitor *v, const char 
*name,
 int queues, err = 0, i = 0;
 char *str;
 
-if (dev->realized) {
-qdev_prop_set_after_realize(dev, name, errp);
-return;
-}
-
 if (!visit_type_str(v, name, , errp)) {
 return;
 }
@@ -469,18 +446,12 @@ static void get_audiodev(Object *obj, Visitor *v, const 
char* name,
 static void set_audiodev(Object *obj, Visitor *v, const char* name,
  void *opaque, Error **errp)
 {
-DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
 QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
 AudioState *state;
 int err = 0;
 char *str;
 
-if (dev->realized) {
-qdev_prop_set_after_realize(dev, name, errp);
-return;
-}
-
 if (!visit_type_str(v, name, , errp)) {
 return;
 }
@@ -582,11 +553,6 @@ static void set_blocksize(Object *obj, Visitor *v, const 
char *name,
 uint64_t value;
 Error *local_err = NULL;
 
-if (dev->realized) {
-qdev_prop_set_after_realize(dev, name, errp);
-return;
-}
-
 if (!visit_type_size(v, name, , errp)) {
 return;
 }
@@ -686,7 +652,6 @@ static void get_reserved_region(Object *obj, Visitor *v, 
const char *name,
 static void set_reserved_region(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp)
 {
-DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
 ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
 Error *local_err = NULL;
@@ -694,11 +659,6 @@ static void set_reserved_region(Object *obj, Visitor *v, 
const char *name,
 char *str;
 int ret;
 
-if (dev->realized) {
-qdev_prop_set_after_realize(dev, name, errp);
-return;
-}
-
 visit_type_str(v, name, , _err);
 if (local_err) {
 error_propagate(errp, local_err);
@@ -754,17 +714,11 @@ const PropertyInfo qdev_prop_reserved_region = {
 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
   void *opaque, Error **errp)
 {
-DeviceState *dev = 

[PULL 04/15] qdev: Get just property name at error_set_from_qdev_prop_error()

2020-12-23 Thread Eduardo Habkost
Replace `Property *prop` parameter with `char *name`, to reduce
dependency of getter and setter functions on the Property struct
(which will be changed in following patches).

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Reviewed-by: Cornelia Huck 
Message-Id: <20201211220529.2290218-19-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties-system.c | 12 ++--
 hw/core/qdev-properties.c|  8 
 include/hw/qdev-properties.h |  2 +-
 hw/s390x/css.c   |  2 +-
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index e2d523b27a..9cf9bcb39d 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -354,7 +354,7 @@ static void set_mac(Object *obj, Visitor *v, const char 
*name, void *opaque,
 return;
 
 inval:
-error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
 g_free(str);
 }
 
@@ -442,7 +442,7 @@ static void set_netdev(Object *obj, Visitor *v, const char 
*name,
 peers_ptr->queues = queues;
 
 out:
-error_set_from_qdev_prop_error(errp, err, obj, prop, str);
+error_set_from_qdev_prop_error(errp, err, obj, name, str);
 g_free(str);
 }
 
@@ -494,7 +494,7 @@ static void set_audiodev(Object *obj, Visitor *v, const 
char* name,
 card->state = state;
 
 out:
-error_set_from_qdev_prop_error(errp, err, obj, prop, str);
+error_set_from_qdev_prop_error(errp, err, obj, name, str);
 g_free(str);
 }
 
@@ -792,7 +792,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const 
char *name,
 return;
 
 invalid:
-error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
 g_free(str);
 }
 
@@ -916,7 +916,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, 
const char *name,
 return;
 
 inval:
-error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
 g_free(str);
 }
 
@@ -1146,7 +1146,7 @@ static void set_uuid(Object *obj, Visitor *v, const char 
*name, void *opaque,
 if (!strcmp(str, UUID_VALUE_AUTO)) {
 qemu_uuid_generate(uuid);
 } else if (qemu_uuid_parse(str, uuid) < 0) {
-error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
 }
 g_free(str);
 }
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index a2eaa43831..7495798a66 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -679,21 +679,21 @@ static Property *qdev_prop_find(DeviceState *dev, const 
char *name)
 }
 
 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
-Property *prop, const char *value)
+const char *name, const char *value)
 {
 switch (ret) {
 case -EEXIST:
 error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
-  object_get_typename(obj), prop->name, value);
+  object_get_typename(obj), name, value);
 break;
 default:
 case -EINVAL:
 error_setg(errp, QERR_PROPERTY_VALUE_BAD,
-   object_get_typename(obj), prop->name, value);
+   object_get_typename(obj), name, value);
 break;
 case -ENOENT:
 error_setg(errp, "Property '%s.%s' can't find value '%s'",
-  object_get_typename(obj), prop->name, value);
+  object_get_typename(obj), name, value);
 break;
 case 0:
 break;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 1b58e4f922..476737b9da 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -201,7 +201,7 @@ const GlobalProperty *qdev_find_global_prop(Object *obj,
 int qdev_prop_check_globals(void);
 void qdev_prop_set_globals(DeviceState *dev);
 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
-Property *prop, const char *value);
+const char *name, const char *value);
 
 /**
  * qdev_property_add_static:
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 38fd46b9a9..7a44320d12 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2390,7 +2390,7 @@ static void set_css_devid(Object *obj, Visitor *v, const 
char *name,
 
 num = sscanf(str, "%2x.%1x%n.%4x%n", , , , , );
 if (num != 3 || (n2 - n1) != 5 || strlen(str) != n2) {
-error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
 goto out;
 }
 if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
-- 
2.28.0




[PULL 13/15] qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr()

2020-12-23 Thread Eduardo Habkost
The function will be moved to common QOM code, as it is not
specific to TYPE_DEVICE anymore.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Stefan Berger 
Reviewed-by: Cornelia Huck 
Reviewed-by: Igor Mammedov 
Acked-by: Paul Durrant 
Message-Id: <20201211220529.2290218-31-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties-system.c | 50 +-
 hw/core/qdev-properties.c| 60 
 include/hw/qdev-properties.h |  2 +-
 backends/tpm/tpm_util.c  |  6 ++--
 hw/block/xen-block.c |  4 +--
 hw/s390x/css.c   |  4 +--
 hw/s390x/s390-pci-bus.c  |  4 +--
 hw/vfio/pci-quirks.c |  4 +--
 8 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index f31aea3de1..2760c21f11 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -62,7 +62,7 @@ static void get_drive(Object *obj, Visitor *v, const char 
*name, void *opaque,
   Error **errp)
 {
 Property *prop = opaque;
-void **ptr = qdev_get_prop_ptr(obj, prop);
+void **ptr = object_field_prop_ptr(obj, prop);
 const char *value;
 char *p;
 
@@ -88,7 +88,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const 
char *name,
 {
 DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
-void **ptr = qdev_get_prop_ptr(obj, prop);
+void **ptr = object_field_prop_ptr(obj, prop);
 char *str;
 BlockBackend *blk;
 bool blk_created = false;
@@ -181,7 +181,7 @@ static void release_drive(Object *obj, const char *name, 
void *opaque)
 {
 DeviceState *dev = DEVICE(obj);
 Property *prop = opaque;
-BlockBackend **ptr = qdev_get_prop_ptr(obj, prop);
+BlockBackend **ptr = object_field_prop_ptr(obj, prop);
 
 if (*ptr) {
 AioContext *ctx = blk_get_aio_context(*ptr);
@@ -214,7 +214,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
 static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 Error **errp)
 {
-CharBackend *be = qdev_get_prop_ptr(obj, opaque);
+CharBackend *be = object_field_prop_ptr(obj, opaque);
 char *p;
 
 p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -226,7 +226,7 @@ static void set_chr(Object *obj, Visitor *v, const char 
*name, void *opaque,
 Error **errp)
 {
 Property *prop = opaque;
-CharBackend *be = qdev_get_prop_ptr(obj, prop);
+CharBackend *be = object_field_prop_ptr(obj, prop);
 Chardev *s;
 char *str;
 
@@ -262,7 +262,7 @@ static void set_chr(Object *obj, Visitor *v, const char 
*name, void *opaque,
 static void release_chr(Object *obj, const char *name, void *opaque)
 {
 Property *prop = opaque;
-CharBackend *be = qdev_get_prop_ptr(obj, prop);
+CharBackend *be = object_field_prop_ptr(obj, prop);
 
 qemu_chr_fe_deinit(be, false);
 }
@@ -286,7 +286,7 @@ static void get_mac(Object *obj, Visitor *v, const char 
*name, void *opaque,
 Error **errp)
 {
 Property *prop = opaque;
-MACAddr *mac = qdev_get_prop_ptr(obj, prop);
+MACAddr *mac = object_field_prop_ptr(obj, prop);
 char buffer[2 * 6 + 5 + 1];
 char *p = buffer;
 
@@ -301,7 +301,7 @@ static void set_mac(Object *obj, Visitor *v, const char 
*name, void *opaque,
 Error **errp)
 {
 Property *prop = opaque;
-MACAddr *mac = qdev_get_prop_ptr(obj, prop);
+MACAddr *mac = object_field_prop_ptr(obj, prop);
 int i, pos;
 char *str;
 const char *p;
@@ -363,7 +363,7 @@ static void get_netdev(Object *obj, Visitor *v, const char 
*name,
void *opaque, Error **errp)
 {
 Property *prop = opaque;
-NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
+NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
 char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
 visit_type_str(v, name, , errp);
@@ -374,7 +374,7 @@ static void set_netdev(Object *obj, Visitor *v, const char 
*name,
void *opaque, Error **errp)
 {
 Property *prop = opaque;
-NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
+NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
 NetClientState **ncs = peers_ptr->ncs;
 NetClientState *peers[MAX_QUEUE_NUM];
 int queues, err = 0, i = 0;
@@ -436,7 +436,7 @@ static void get_audiodev(Object *obj, Visitor *v, const 
char* name,
  void *opaque, Error **errp)
 {
 Property *prop = opaque;
-QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
+QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
 char *p = g_strdup(audio_get_id(card));
 
 visit_type_str(v, name, , errp);
@@ -447,7 +447,7 @@ static void set_audiodev(Object *obj, Visitor *v, const 
char* name,
  void *opaque, Error **errp)
 

[PULL 08/15] qdev: Wrap getters and setters in separate helpers

2020-12-23 Thread Eduardo Habkost
We'll add extra code to the qdev property getters and setters, so
add wrapper functions where additional actions can be performed.

The new functions have a "field_prop_" prefix instead of "qdev_"
because the code will eventually be moved outside
qdev-properties.c, to common QOM code.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-23-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties.c | 44 +++
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index c68a20695d..b924f13d58 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -44,6 +44,40 @@ void *qdev_get_prop_ptr(Object *obj, Property *prop)
 return ptr;
 }
 
+static void field_prop_get(Object *obj, Visitor *v, const char *name,
+   void *opaque, Error **errp)
+{
+Property *prop = opaque;
+return prop->info->get(obj, v, name, opaque, errp);
+}
+
+/**
+ * field_prop_getter: Return getter function to be used for property
+ *
+ * Return value can be NULL if @info has no getter function.
+ */
+static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
+{
+return info->get ? field_prop_get : NULL;
+}
+
+static void field_prop_set(Object *obj, Visitor *v, const char *name,
+   void *opaque, Error **errp)
+{
+Property *prop = opaque;
+return prop->info->set(obj, v, name, opaque, errp);
+}
+
+/**
+ * field_prop_setter: Return setter function to be used for property
+ *
+ * Return value can be NULL if @info has not setter function.
+ */
+static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
+{
+return info->set ? field_prop_set : NULL;
+}
+
 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp)
 {
@@ -630,8 +664,8 @@ static void set_prop_arraylen(Object *obj, Visitor *v, 
const char *name,
 assert(qdev_get_prop_ptr(obj, >prop) == eltptr);
 object_property_add(obj, propname,
 arrayprop->prop.info->name,
-arrayprop->prop.info->get,
-arrayprop->prop.info->set,
+field_prop_getter(arrayprop->prop.info),
+field_prop_setter(arrayprop->prop.info),
 array_element_release,
 arrayprop);
 }
@@ -873,7 +907,8 @@ void qdev_property_add_static(DeviceState *dev, Property 
*prop)
 assert(!prop->info->create);
 
 op = object_property_add(obj, prop->name, prop->info->name,
- prop->info->get, prop->info->set,
+ field_prop_getter(prop->info),
+ field_prop_setter(prop->info),
  prop->info->release,
  prop);
 
@@ -900,7 +935,8 @@ static void qdev_class_add_property(DeviceClass *klass, 
const char *name,
 
 op = object_class_property_add(oc,
name, prop->info->name,
-   prop->info->get, prop->info->set,
+   field_prop_getter(prop->info),
+   field_prop_setter(prop->info),
prop->info->release,
prop);
 if (prop->set_default) {
-- 
2.28.0




[PULL 07/15] qdev: Add name argument to PropertyInfo.create method

2020-12-23 Thread Eduardo Habkost
This will make it easier to remove the Property.name field in the
future.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-22-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties.c| 7 ---
 include/hw/qdev-properties.h | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 457c7fe4ba..c68a20695d 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -851,9 +851,10 @@ const PropertyInfo qdev_prop_size = {
 
 /* --- object link property --- */
 
-static void create_link_property(ObjectClass *oc, Property *prop)
+static void create_link_property(ObjectClass *oc, const char *name,
+ Property *prop)
 {
-object_class_property_add_link(oc, prop->name, prop->link_type,
+object_class_property_add_link(oc, name, prop->link_type,
prop->offset,
qdev_prop_allow_set_link_before_realize,
OBJ_PROP_LINK_STRONG);
@@ -893,7 +894,7 @@ static void qdev_class_add_property(DeviceClass *klass, 
const char *name,
 ObjectClass *oc = OBJECT_CLASS(klass);
 
 if (prop->info->create) {
-prop->info->create(oc, prop);
+prop->info->create(oc, name, prop);
 } else {
 ObjectProperty *op;
 
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 476737b9da..ab9c538ba4 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -34,7 +34,7 @@ struct PropertyInfo {
 const QEnumLookup *enum_table;
 int (*print)(Object *obj, Property *prop, char *dest, size_t len);
 void (*set_default_value)(ObjectProperty *op, const Property *prop);
-void (*create)(ObjectClass *oc, Property *prop);
+void (*create)(ObjectClass *oc, const char *name, Property *prop);
 ObjectPropertyAccessor *get;
 ObjectPropertyAccessor *set;
 ObjectPropertyRelease *release;
-- 
2.28.0




[PULL 02/15] qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros

2020-12-23 Thread Eduardo Habkost
Instead of duplicating the code that sets name, info, offset,
and does type checking, make DEFINE_PROP accept a variable number
of arguments and reuse it in all DEFINE_PROP_* macros.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-17-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 include/hw/qdev-properties-system.h |  19 ++---
 include/hw/qdev-properties.h| 114 ++--
 2 files changed, 46 insertions(+), 87 deletions(-)

diff --git a/include/hw/qdev-properties-system.h 
b/include/hw/qdev-properties-system.h
index 29529dc999..0ac327ae60 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -63,22 +63,15 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
 DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \
 PCIExpLinkWidth)
 
-#define DEFINE_PROP_UUID(_name, _state, _field) {  \
-.name  = (_name),  \
-.info  = _prop_uuid,  \
-.offset= offsetof(_state, _field)  \
-+ type_check(QemuUUID, typeof_field(_state, _field)),  \
-.set_default = true,   \
-}
+#define DEFINE_PROP_UUID(_name, _state, _field) \
+DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID, \
+.set_default = true)
+
 #define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
 
-#define DEFINE_PROP_UUID_NODEFAULT(_name, _state, _field) {\
-.name  = (_name),  \
-.info  = _prop_uuid,  \
-.offset= offsetof(_state, _field)  \
-+ type_check(QemuUUID, typeof_field(_state, _field)),  \
-}
+#define DEFINE_PROP_UUID_NODEFAULT(_name, _state, _field) \
+DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID)
 
 
 #endif
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index d35d4aae84..1b58e4f922 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -61,73 +61,46 @@ extern const PropertyInfo qdev_prop_size32;
 extern const PropertyInfo qdev_prop_arraylen;
 extern const PropertyInfo qdev_prop_link;
 
-#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
+#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
 .name  = (_name),\
 .info  = &(_prop),   \
 .offset= offsetof(_state, _field)\
 + type_check(_type, typeof_field(_state, _field)),   \
+__VA_ARGS__  \
 }
 
-#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) { \
-.name  = (_name),   \
-.info  = &(_prop),  \
-.offset= offsetof(_state, _field)   \
-+ type_check(_type,typeof_field(_state, _field)),   \
-.set_default = true,\
-.defval.i  = (_type)_defval,\
-}
+#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
+DEFINE_PROP(_name, _state, _field, _prop, _type, \
+.set_default = true, \
+.defval.i= (_type)_defval)
 
-#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) { \
-.name  = (_name),   \
-.info  = &(_prop),  \
-.offset= offsetof(_state, _field)   \
-+ type_check(_type, typeof_field(_state, _field)),  \
-}
+#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
+DEFINE_PROP(_name, _state, _field, _prop, _type)
 
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
-.name  = (_name),\
-.info  = &(qdev_prop_bit),   \
-.bitnr= (_bit),  \
-.offset= offsetof(_state, _field)\
-+ type_check(uint32_t,typeof_field(_state, _field)), \
-.set_default = true, \
-.defval.u  = (bool)_defval,  \
-}
+#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
+DEFINE_PROP(_name, _state, _field, qdev_prop_bit, uint32_t, \
+.bitnr   = (_bit),   

[PULL 06/15] qdev: Add name parameter to qdev_class_add_property()

2020-12-23 Thread Eduardo Habkost
This will make it easier to remove Property.name in the future.

Signed-off-by: Eduardo Habkost 
Message-Id: <20201211220529.2290218-21-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 50734a1cd4..457c7fe4ba 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -887,7 +887,8 @@ void qdev_property_add_static(DeviceState *dev, Property 
*prop)
 }
 }
 
-static void qdev_class_add_property(DeviceClass *klass, Property *prop)
+static void qdev_class_add_property(DeviceClass *klass, const char *name,
+Property *prop)
 {
 ObjectClass *oc = OBJECT_CLASS(klass);
 
@@ -897,7 +898,7 @@ static void qdev_class_add_property(DeviceClass *klass, 
Property *prop)
 ObjectProperty *op;
 
 op = object_class_property_add(oc,
-   prop->name, prop->info->name,
+   name, prop->info->name,
prop->info->get, prop->info->set,
prop->info->release,
prop);
@@ -905,7 +906,7 @@ static void qdev_class_add_property(DeviceClass *klass, 
Property *prop)
 prop->info->set_default_value(op, prop);
 }
 }
-object_class_property_set_description(oc, prop->name,
+object_class_property_set_description(oc, name,
   prop->info->description);
 }
 
@@ -962,7 +963,7 @@ void device_class_set_props(DeviceClass *dc, Property 
*props)
 dc->props_ = props;
 for (prop = props; prop && prop->name; prop++) {
 qdev_class_add_legacy_property(dc, prop);
-qdev_class_add_property(dc, prop);
+qdev_class_add_property(dc, prop->name, prop);
 }
 }
 
-- 
2.28.0




[PULL 12/15] qdev: Move qdev_prop_tpm declaration to tpm_prop.h

2020-12-23 Thread Eduardo Habkost
Move the variable declaration close to the macro that uses it.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Stefan Berger 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-29-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/tpm/tpm_prop.h| 2 ++
 include/hw/qdev-properties.h | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/tpm/tpm_prop.h b/hw/tpm/tpm_prop.h
index d19e40c112..bbd4225d66 100644
--- a/hw/tpm/tpm_prop.h
+++ b/hw/tpm/tpm_prop.h
@@ -25,6 +25,8 @@
 #include "sysemu/tpm_backend.h"
 #include "hw/qdev-properties.h"
 
+extern const PropertyInfo qdev_prop_tpm;
+
 #define DEFINE_PROP_TPMBE(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_tpm, TPMBackend *)
 
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index aae882317a..68e544708b 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -56,7 +56,6 @@ extern const PropertyInfo qdev_prop_uint64;
 extern const PropertyInfo qdev_prop_int64;
 extern const PropertyInfo qdev_prop_size;
 extern const PropertyInfo qdev_prop_string;
-extern const PropertyInfo qdev_prop_tpm;
 extern const PropertyInfo qdev_prop_on_off_auto;
 extern const PropertyInfo qdev_prop_size32;
 extern const PropertyInfo qdev_prop_arraylen;
-- 
2.28.0




[PULL 05/15] qdev: Avoid using prop->name unnecessarily

2020-12-23 Thread Eduardo Habkost
We already get the property name as argument to the property
getter and setters, we don't need to use prop->name.  This will
make it easier to remove the Property.name field in the future.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Stefan Berger 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-20-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties-system.c | 14 +++---
 hw/core/qdev-properties.c|  4 ++--
 backends/tpm/tpm_util.c  |  2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 9cf9bcb39d..42529c3b65 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -141,7 +141,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const 
char *name,
 }
 if (!blk) {
 error_setg(errp, "Property '%s.%s' can't find value '%s'",
-   object_get_typename(OBJECT(dev)), prop->name, str);
+   object_get_typename(OBJECT(dev)), name, str);
 goto fail;
 }
 if (blk_attach_dev(blk, dev) < 0) {
@@ -262,10 +262,10 @@ static void set_chr(Object *obj, Visitor *v, const char 
*name, void *opaque,
 s = qemu_chr_find(str);
 if (s == NULL) {
 error_setg(errp, "Property '%s.%s' can't find value '%s'",
-   object_get_typename(obj), prop->name, str);
+   object_get_typename(obj), name, str);
 } else if (!qemu_chr_fe_init(be, s, errp)) {
 error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
-  object_get_typename(obj), prop->name, str);
+  object_get_typename(obj), name, str);
 }
 g_free(str);
 }
@@ -966,7 +966,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, 
const char *name,
 abort();
 }
 
-visit_type_enum(v, prop->name, , prop->info->enum_table, errp);
+visit_type_enum(v, name, , prop->info->enum_table, errp);
 }
 
 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
@@ -982,7 +982,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
-if (!visit_type_enum(v, prop->name, , prop->info->enum_table,
+if (!visit_type_enum(v, name, , prop->info->enum_table,
  errp)) {
 return;
 }
@@ -1051,7 +1051,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor 
*v, const char *name,
 abort();
 }
 
-visit_type_enum(v, prop->name, , prop->info->enum_table, errp);
+visit_type_enum(v, name, , prop->info->enum_table, errp);
 }
 
 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
@@ -1067,7 +1067,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor 
*v, const char *name,
 return;
 }
 
-if (!visit_type_enum(v, prop->name, , prop->info->enum_table,
+if (!visit_type_enum(v, name, , prop->info->enum_table,
  errp)) {
 return;
 }
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 7495798a66..50734a1cd4 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -50,7 +50,7 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const 
char *name,
 Property *prop = opaque;
 int *ptr = qdev_get_prop_ptr(obj, prop);
 
-visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
+visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
 
 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
@@ -65,7 +65,7 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const 
char *name,
 return;
 }
 
-visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
+visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
 
 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index 3973105658..a5d997e7dc 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -63,7 +63,7 @@ static void set_tpm(Object *obj, Visitor *v, const char 
*name, void *opaque,
 s = qemu_find_tpm_be(str);
 if (s == NULL) {
 error_setg(errp, "Property '%s.%s' can't find value '%s'",
-   object_get_typename(obj), prop->name, str);
+   object_get_typename(obj), name, str);
 } else if (tpm_backend_init(s, TPM_IF(obj), errp) == 0) {
 *be = s; /* weak reference, avoid cyclic ref */
 }
-- 
2.28.0




[PULL 11/15] qdev: Make qdev_class_add_property() more flexible

2020-12-23 Thread Eduardo Habkost
Support Property.set_default and PropertyInfo.description even if
PropertyInfo.create is set.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-26-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3bb05e7d0d..2946cdf56d 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -863,24 +863,22 @@ static void qdev_class_add_property(DeviceClass *klass, 
const char *name,
 Property *prop)
 {
 ObjectClass *oc = OBJECT_CLASS(klass);
+ObjectProperty *op;
 
 if (prop->info->create) {
-prop->info->create(oc, name, prop);
+op = prop->info->create(oc, name, prop);
 } else {
-ObjectProperty *op;
-
 op = object_class_property_add(oc,
name, prop->info->name,
field_prop_getter(prop->info),
field_prop_setter(prop->info),
prop->info->release,
prop);
-if (prop->set_default) {
-prop->info->set_default_value(op, prop);
-}
 }
-object_class_property_set_description(oc, name,
-  prop->info->description);
+if (prop->set_default) {
+prop->info->set_default_value(op, prop);
+}
+object_class_property_set_description(oc, name, prop->info->description);
 }
 
 /**
-- 
2.28.0




[PULL 01/15] qdev: Move softmmu properties to qdev-properties-system.h

2020-12-23 Thread Eduardo Habkost
Move the property types and property macros implemented in
qdev-properties-system.c to a new qdev-properties-system.h
header.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Message-Id: <20201211220529.2290218-16-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties-system.c|  1 +
 audio/audio.h   |  1 +
 include/hw/block/block.h|  1 +
 include/hw/qdev-properties-system.h | 84 +
 include/hw/qdev-properties.h| 75 --
 include/net/net.h   |  1 +
 hw/acpi/vmgenid.c   |  1 +
 hw/arm/pxa2xx.c |  1 +
 hw/arm/strongarm.c  |  1 +
 hw/block/fdc.c  |  1 +
 hw/block/m25p80.c   |  1 +
 hw/block/nand.c |  1 +
 hw/block/onenand.c  |  1 +
 hw/block/pflash_cfi01.c |  1 +
 hw/block/pflash_cfi02.c |  1 +
 hw/block/vhost-user-blk.c   |  1 +
 hw/char/avr_usart.c |  1 +
 hw/char/bcm2835_aux.c   |  1 +
 hw/char/cadence_uart.c  |  1 +
 hw/char/cmsdk-apb-uart.c|  1 +
 hw/char/debugcon.c  |  1 +
 hw/char/digic-uart.c|  1 +
 hw/char/escc.c  |  1 +
 hw/char/etraxfs_ser.c   |  1 +
 hw/char/exynos4210_uart.c   |  1 +
 hw/char/grlib_apbuart.c |  1 +
 hw/char/ibex_uart.c |  1 +
 hw/char/imx_serial.c|  1 +
 hw/char/ipoctal232.c|  1 +
 hw/char/lm32_juart.c|  1 +
 hw/char/lm32_uart.c |  1 +
 hw/char/mcf_uart.c  |  1 +
 hw/char/milkymist-uart.c|  1 +
 hw/char/nrf51_uart.c|  1 +
 hw/char/parallel.c  |  1 +
 hw/char/pl011.c |  1 +
 hw/char/renesas_sci.c   |  1 +
 hw/char/sclpconsole-lm.c|  1 +
 hw/char/sclpconsole.c   |  1 +
 hw/char/serial-pci-multi.c  |  1 +
 hw/char/serial.c|  1 +
 hw/char/spapr_vty.c |  1 +
 hw/char/stm32f2xx_usart.c   |  1 +
 hw/char/terminal3270.c  |  1 +
 hw/char/virtio-console.c|  1 +
 hw/char/xilinx_uartlite.c   |  1 +
 hw/hyperv/vmbus.c   |  1 +
 hw/i386/kvm/i8254.c |  1 +
 hw/ide/qdev.c   |  1 +
 hw/ipmi/ipmi_bmc_extern.c   |  1 +
 hw/ipmi/ipmi_bmc_sim.c  |  1 +
 hw/misc/allwinner-sid.c |  1 +
 hw/misc/ivshmem.c   |  1 +
 hw/misc/mac_via.c   |  1 +
 hw/misc/sifive_u_otp.c  |  1 +
 hw/net/rocker/rocker.c  |  1 +
 hw/nvram/eeprom_at24c.c |  1 +
 hw/nvram/spapr_nvram.c  |  1 +
 hw/pci-bridge/gen_pcie_root_port.c  |  1 +
 hw/pci/pci.c|  1 +
 hw/ppc/pnv_pnor.c   |  1 +
 hw/rdma/vmw/pvrdma_main.c   |  1 +
 hw/rtc/mc146818rtc.c|  1 +
 hw/scsi/scsi-disk.c |  1 +
 hw/scsi/scsi-generic.c  |  1 +
 hw/scsi/vhost-user-scsi.c   |  1 +
 hw/sd/sd.c  |  1 +
 hw/usb/ccid-card-passthru.c |  1 +
 hw/usb/dev-serial.c |  1 +
 hw/usb/redirect.c   |  1 +
 hw/vfio/pci.c   |  1 +
 hw/virtio/vhost-user-fs.c   |  1 +
 hw/virtio/vhost-user-vsock.c|  1 +
 hw/virtio/virtio-iommu-pci.c|  1 +
 hw/xen/xen_pt.c |  1 +
 migration/migration.c   |  1 +
 76 files changed, 158 insertions(+), 75 deletions(-)
 create mode 100644 include/hw/qdev-properties-system.h

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 7a9a1d6404..e2d523b27a 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -12,6 +12,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "qapi/qapi-types-block.h"
diff --git a/audio/audio.h b/audio/audio.h
index 41b3ef04ea..c8bde536b5 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -28,6 +28,7 @@
 #include "qemu/queue.h"
 #include "qapi/qapi-types-audio.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 
 typedef void (*audio_callback_fn) (void *opaque, int avail);
 
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 1e8b6253dd..c172cbe65f 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -13,6 +13,7 @@
 
 #include "exec/hwaddr.h"
 #include "qapi/qapi-types-block-core.h"
+#include "hw/qdev-properties-system.h"
 
 /* Configuration */
 
diff --git a/include/hw/qdev-properties-system.h 
b/include/hw/qdev-properties-system.h
new file mode 100644
index 00..29529dc999
--- /dev/null

[PULL 03/15] sparc: Use DEFINE_PROP for nwindows property

2020-12-23 Thread Eduardo Habkost
Use the DEFINE_PROP macro (which will set extra fields in the
struct) instead of initializing a Property struct manually.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Igor Mammedov 
Acked-by: Mark Cave-Ayland 
Message-Id: <20201211220529.2290218-18-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 target/sparc/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 6a3299041f..a1dc0f1be4 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -848,7 +848,8 @@ static Property sparc_cpu_properties[] = {
  qdev_prop_uint64, target_ulong),
 DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0),
 DEFINE_PROP_UINT32("mmu-version", SPARCCPU, env.def.mmu_version, 0),
-{ .name  = "nwindows", .info  = _prop_nwindows },
+DEFINE_PROP("nwindows", SPARCCPU, env.def.nwindows,
+qdev_prop_nwindows, uint32_t),
 DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.28.0




[PULL 00/15] Machine queue, 2020-12-23

2020-12-23 Thread Eduardo Habkost
The following changes since commit a05f8ecd88f15273d033b6f044b850a8af84a5b8:

  Merge remote-tracking branch 
'remotes/alistair/tags/pull-riscv-to-apply-20201217-1' into staging (2020-12-18 
11:12:35 +)

are available in the Git repository at:

  https://gitlab.com/ehabkost/qemu.git tags/machine-next-pull-request

for you to fetch changes up to bdd5ce050d086e9f63874f1f36e9e39fa27a976c:

  bugfix: hostmem: Free host_nodes list right after visited (2020-12-18 
15:20:23 -0500)


Machine queue, 2020-12-23

Cleanup:
* qdev code cleanup (Eduardo Habkost)

Bug fix:
* hostmem: Free host_nodes list right after visited (Keqian Zhu)



Eduardo Habkost (14):
  qdev: Move softmmu properties to qdev-properties-system.h
  qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros
  sparc: Use DEFINE_PROP for nwindows property
  qdev: Get just property name at error_set_from_qdev_prop_error()
  qdev: Avoid using prop->name unnecessarily
  qdev: Add name parameter to qdev_class_add_property()
  qdev: Add name argument to PropertyInfo.create method
  qdev: Wrap getters and setters in separate helpers
  qdev: Move dev->realized check to qdev_property_set()
  qdev: Make PropertyInfo.create return ObjectProperty*
  qdev: Make qdev_class_add_property() more flexible
  qdev: Move qdev_prop_tpm declaration to tpm_prop.h
  qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr()
  qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen()

Keqian Zhu (1):
  bugfix: hostmem: Free host_nodes list right after visited

 hw/core/qdev-properties-system.c| 147 +---
 hw/core/qdev-properties.c   | 253 
 audio/audio.h   |   1 +
 hw/tpm/tpm_prop.h   |   2 +
 include/hw/block/block.h|   1 +
 include/hw/qdev-properties-system.h |  77 +
 include/hw/qdev-properties.h| 197 +-
 include/net/net.h   |   1 +
 backends/hostmem.c  |   1 +
 backends/tpm/tpm_util.c |  14 +-
 hw/acpi/vmgenid.c   |   1 +
 hw/arm/pxa2xx.c |   1 +
 hw/arm/strongarm.c  |   1 +
 hw/block/fdc.c  |   1 +
 hw/block/m25p80.c   |   1 +
 hw/block/nand.c |   1 +
 hw/block/onenand.c  |   1 +
 hw/block/pflash_cfi01.c |   1 +
 hw/block/pflash_cfi02.c |   1 +
 hw/block/vhost-user-blk.c   |   1 +
 hw/block/xen-block.c|  10 +-
 hw/char/avr_usart.c |   1 +
 hw/char/bcm2835_aux.c   |   1 +
 hw/char/cadence_uart.c  |   1 +
 hw/char/cmsdk-apb-uart.c|   1 +
 hw/char/debugcon.c  |   1 +
 hw/char/digic-uart.c|   1 +
 hw/char/escc.c  |   1 +
 hw/char/etraxfs_ser.c   |   1 +
 hw/char/exynos4210_uart.c   |   1 +
 hw/char/grlib_apbuart.c |   1 +
 hw/char/ibex_uart.c |   1 +
 hw/char/imx_serial.c|   1 +
 hw/char/ipoctal232.c|   1 +
 hw/char/lm32_juart.c|   1 +
 hw/char/lm32_uart.c |   1 +
 hw/char/mcf_uart.c  |   1 +
 hw/char/milkymist-uart.c|   1 +
 hw/char/nrf51_uart.c|   1 +
 hw/char/parallel.c  |   1 +
 hw/char/pl011.c |   1 +
 hw/char/renesas_sci.c   |   1 +
 hw/char/sclpconsole-lm.c|   1 +
 hw/char/sclpconsole.c   |   1 +
 hw/char/serial-pci-multi.c  |   1 +
 hw/char/serial.c|   1 +
 hw/char/spapr_vty.c |   1 +
 hw/char/stm32f2xx_usart.c   |   1 +
 hw/char/terminal3270.c  |   1 +
 hw/char/virtio-console.c|   1 +
 hw/char/xilinx_uartlite.c   |   1 +
 hw/hyperv/vmbus.c   |   1 +
 hw/i386/kvm/i8254.c |   1 +
 hw/ide/qdev.c   |   1 +
 hw/ipmi/ipmi_bmc_extern.c   |   1 +
 hw/ipmi/ipmi_bmc_sim.c  |   1 +
 hw/misc/allwinner-sid.c |   1 +
 hw/misc/ivshmem.c   |   1 +
 hw/misc/mac_via.c   |   1 +
 hw/misc/sifive_u_otp.c  |   1 +
 hw/net/rocker/rocker.c  |   1 +
 hw/nvram/eeprom_at24c.c |   1 +
 hw/nvram/spapr_nvram.c  |   1 +
 hw/pci-bridge/gen_pcie_root_port.c  |   1 +
 hw/pci/pci.c|   1 +
 hw/ppc/pnv_pnor.c   |   1 +
 hw/rdma/vmw/pvrdma_main.c   |   1 +
 hw/rtc/mc146818rtc.c|   1 +
 hw/s390x/css.c  |  12 +-
 hw/s390x/s390-pci-bus.c |  10 +-
 hw/scsi/scsi-disk.c |   1 +
 hw/scsi/scsi-generic.c  |   1 +
 hw/scsi/vhost-user-scsi.c

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Guenter Roeck
On 12/23/20 12:20 PM, BALATON Zoltan wrote:
> On Wed, 23 Dec 2020, Guenter Roeck wrote:
>> On 12/23/20 8:09 AM, Mark Cave-Ayland wrote:
>>> On 23/12/2020 15:21, Philippe Mathieu-Daudé wrote:
>>>
 On 12/22/20 5:16 PM, Guenter Roeck wrote:
> Hi,
>
> commit 459ca8bfa41 ("pci: Assert irqnum is between 0 and bus->nirqs in
> pci_bus_change_irq_level") added sanity checks to the interrupt number 
> passed
> to pci_bus_change_irq_level(). That makes sense, given that bus->irq_count
> is indexed and sized by the number of interrupts.
>
> However, as it turns out, the interrupt number passed to this function
> is the _mapped_ interrupt number. The result in assertion failures for 
> various
> emulations.
>
> Examples (I don't know if there are others):
>
> - ppc4xx_pci_map_irq() maps the interrupt number to "slot - 1". Obviously
>    that isn't a good thing to do for slot 0, and indeed results in an
>    assertion as soon as slot 0 is initialized (presumably that is the root
>    bridge). Changing the mapping to "slot" doesn't help because valid 
> slots
>    are 0..4, and only four interrupts are allocated.
> - pci_bonito_map_irq() changes the mapping all over the place. Whatever
>    it does, it returns numbers starting with 32 for slots 5..12. With
>    a total number of 32 interrupts, this again results in an assertion
>    failure.
>
> ppc4xx_pci_map_irq() is definitely buggy. I just don't know what the
> correct mapping should be. slot  & 3, maybe ?
>
> I don't really have a good solution for pci_bonito_map_irq(). It may not
> matter much - I have not been able to boot fuloong_2e since qemu v4.0,
> and afaics that is the only platform using it. Maybe it is just completely
> broken ?

 FWIW bisecting Fuloong2E starts failing here:

 4ea98d317eb442c738f898f16cfdd47a18b7ca49 is the first bad commit
 commit 4ea98d317eb442c738f898f16cfdd47a18b7ca49
 Author: BALATON Zoltan 
 Date:   Fri Jan 25 14:52:12 2019 -0500

  ide/via: Implement and use native PCI IDE mode

  This device only implemented ISA compatibility mode and native PCI IDE
  mode was missing but no clients actually need ISA mode but to the
  contrary, they usually want to switch to and use device in native
  PCI IDE mode. Therefore implement native PCI mode and switch default
  to that.

  Signed-off-by: BALATON Zoltan 
  Message-id:
 c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.bala...@eik.bme.hu
  Signed-off-by: John Snow 

   hw/ide/via.c | 52 ++--
   1 file changed, 38 insertions(+), 14 deletions(-)
>>>
>>> I think the original version of the patch broke fuloong2e, however that 
>>> should have been fixed by my patchset here: 
>>> https://lists.gnu.org/archive/html/qemu-devel/2020-03/msg03936.html. It 
>>> might be that there are multiple regressions located during a full bisect :/
>>>
>>
>> Not really. The following patch on top of qemu 5.2 results in the ide drive
>> being detected and working.
>>
>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>> index be09912b33..1bfdc422ee 100644
>> --- a/hw/ide/via.c
>> +++ b/hw/ide/via.c
>> @@ -186,11 +186,14 @@ static void via_ide_realize(PCIDevice *dev, Error 
>> **errp)
>>     pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]);
>>
>>     bmdma_setup_bar(d);
>> +#if 0
>>     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar);
>> +#endif
>>
>>     qdev_init_gpio_in(ds, via_ide_set_irq, 2);
>>     for (i = 0; i < 2; i++) {
>>     ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2);
>> +    ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, i ? 0x376 : 
>> 0x3f6);
>>     ide_init2(>bus[i], qdev_get_gpio_in(ds, i));
>>
>>     bmdma_init(>bus[i], >bmdma[i], d);
>>
>> With the added ide_init_ioport(), the drive is detected. With the #if 0,
> 
> This breaks MorphOS on pegasos2 so it's not acceptable for me as a fix. 
> (Actually this just reverts my commit in a cryptic way.)
> 
>> it actually starts working. So there are two problems: 1) The qemu ide
>> subsystem isn't informed about the io addresses, and 2) bmdma isn't working.
> 
> The problem rather seems to be that whatever you're trying to run can only 
> handle legacy mode and does not correctly detect or work with native mode of 
> this IDE controller. The real chip can switch between these modes and starts 
> in legacy mode but most OSes with a better driver will switch to native mode 
> during boot (in some cases the firmware will switch already). But we can't 
> emulate that in QEMU easily because of how the IDE emulation is implemented: 
> we either set up legacy ioports or use PCI BMDMA, I don't see a way to 
> deregister legacy ports and irqs once the config reg is flipped to native 
> mode. 

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread BALATON Zoltan via

On Wed, 23 Dec 2020, Guenter Roeck wrote:

On 12/23/20 8:09 AM, Mark Cave-Ayland wrote:

On 23/12/2020 15:21, Philippe Mathieu-Daudé wrote:


On 12/22/20 5:16 PM, Guenter Roeck wrote:

Hi,

commit 459ca8bfa41 ("pci: Assert irqnum is between 0 and bus->nirqs in
pci_bus_change_irq_level") added sanity checks to the interrupt number passed
to pci_bus_change_irq_level(). That makes sense, given that bus->irq_count
is indexed and sized by the number of interrupts.

However, as it turns out, the interrupt number passed to this function
is the _mapped_ interrupt number. The result in assertion failures for various
emulations.

Examples (I don't know if there are others):

- ppc4xx_pci_map_irq() maps the interrupt number to "slot - 1". Obviously
   that isn't a good thing to do for slot 0, and indeed results in an
   assertion as soon as slot 0 is initialized (presumably that is the root
   bridge). Changing the mapping to "slot" doesn't help because valid slots
   are 0..4, and only four interrupts are allocated.
- pci_bonito_map_irq() changes the mapping all over the place. Whatever
   it does, it returns numbers starting with 32 for slots 5..12. With
   a total number of 32 interrupts, this again results in an assertion
   failure.

ppc4xx_pci_map_irq() is definitely buggy. I just don't know what the
correct mapping should be. slot  & 3, maybe ?

I don't really have a good solution for pci_bonito_map_irq(). It may not
matter much - I have not been able to boot fuloong_2e since qemu v4.0,
and afaics that is the only platform using it. Maybe it is just completely
broken ?


FWIW bisecting Fuloong2E starts failing here:

4ea98d317eb442c738f898f16cfdd47a18b7ca49 is the first bad commit
commit 4ea98d317eb442c738f898f16cfdd47a18b7ca49
Author: BALATON Zoltan 
Date:   Fri Jan 25 14:52:12 2019 -0500

 ide/via: Implement and use native PCI IDE mode

 This device only implemented ISA compatibility mode and native PCI IDE
 mode was missing but no clients actually need ISA mode but to the
 contrary, they usually want to switch to and use device in native
 PCI IDE mode. Therefore implement native PCI mode and switch default
 to that.

 Signed-off-by: BALATON Zoltan 
 Message-id:
c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.bala...@eik.bme.hu
 Signed-off-by: John Snow 

  hw/ide/via.c | 52 ++--
  1 file changed, 38 insertions(+), 14 deletions(-)


I think the original version of the patch broke fuloong2e, however that should 
have been fixed by my patchset here: 
https://lists.gnu.org/archive/html/qemu-devel/2020-03/msg03936.html. It might 
be that there are multiple regressions located during a full bisect :/



Not really. The following patch on top of qemu 5.2 results in the ide drive
being detected and working.

diff --git a/hw/ide/via.c b/hw/ide/via.c
index be09912b33..1bfdc422ee 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -186,11 +186,14 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]);

bmdma_setup_bar(d);
+#if 0
pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar);
+#endif

qdev_init_gpio_in(ds, via_ide_set_irq, 2);
for (i = 0; i < 2; i++) {
ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2);
+ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, i ? 0x376 : 
0x3f6);
ide_init2(>bus[i], qdev_get_gpio_in(ds, i));

bmdma_init(>bus[i], >bmdma[i], d);

With the added ide_init_ioport(), the drive is detected. With the #if 0,


This breaks MorphOS on pegasos2 so it's not acceptable for me as a fix. 
(Actually this just reverts my commit in a cryptic way.)



it actually starts working. So there are two problems: 1) The qemu ide
subsystem isn't informed about the io addresses, and 2) bmdma isn't working.


The problem rather seems to be that whatever you're trying to run can only 
handle legacy mode and does not correctly detect or work with native mode 
of this IDE controller. The real chip can switch between these modes and 
starts in legacy mode but most OSes with a better driver will switch to 
native mode during boot (in some cases the firmware will switch already). 
But we can't emulate that in QEMU easily because of how the IDE emulation 
is implemented: we either set up legacy ioports or use PCI BMDMA, I don't 
see a way to deregister legacy ports and irqs once the config reg is 
flipped to native mode. Therefore I've chosen to only emulate native mode 
which is what most guests want to use and some only work with that and 
I've tested this with the previously mentioned Linux version that it still 
detected and worked with the IDE ports. During testing I've found that 
Linux will use either native or legacy modes if the appropriate config 
bits are set but for some boards there may be work arounds for specific 
quirks such as the case for pegasos2 with IRQs hardwired to legacy 

Re: [PATCH] vhost-user: Check vhost features for CONFIGURE_MEM_SLOTS

2020-12-23 Thread Dylan Reid
>Agreed - VHOST_USER_PROTCOL_F_CONFIGURE_MEM_SLOTS is negotiated at the
>vhost-user, not virtio layer. The dev->protocol_features flags are taken
>from the VHOST_USER_GET_PROTOCOL_FEATURES message, which retrieves the
>supported vhost-user features from the backend. See libvhost-user for a
>simple reference implementation.
>
>The VHOST_USER_GET_FEATURES message retrieves the virtio protocol
>features, so checking features instead of dev->protocol_features would
>incorrectly check the supported virtio features instead of the vhost-user
>ones.
>
>Am I missing something here?

No, you're not missing anything, I am(so is the code I was working with).
I hade the message number and feature bit backwards.

Thanks for taking the time to read this, your explaination got me back on the 
right track, I'll go fix the library I was using.




Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread BALATON Zoltan via

On Wed, 23 Dec 2020, Philippe Mathieu-Daudé wrote:

On 12/22/20 5:16 PM, Guenter Roeck wrote:

Hi,

commit 459ca8bfa41 ("pci: Assert irqnum is between 0 and bus->nirqs in
pci_bus_change_irq_level") added sanity checks to the interrupt number passed
to pci_bus_change_irq_level(). That makes sense, given that bus->irq_count
is indexed and sized by the number of interrupts.

However, as it turns out, the interrupt number passed to this function
is the _mapped_ interrupt number. The result in assertion failures for various
emulations.

Examples (I don't know if there are others):

- ppc4xx_pci_map_irq() maps the interrupt number to "slot - 1". Obviously
  that isn't a good thing to do for slot 0, and indeed results in an
  assertion as soon as slot 0 is initialized (presumably that is the root
  bridge). Changing the mapping to "slot" doesn't help because valid slots
  are 0..4, and only four interrupts are allocated.
- pci_bonito_map_irq() changes the mapping all over the place. Whatever
  it does, it returns numbers starting with 32 for slots 5..12. With
  a total number of 32 interrupts, this again results in an assertion
  failure.

ppc4xx_pci_map_irq() is definitely buggy. I just don't know what the
correct mapping should be. slot  & 3, maybe ?

I don't really have a good solution for pci_bonito_map_irq(). It may not
matter much - I have not been able to boot fuloong_2e since qemu v4.0,
and afaics that is the only platform using it. Maybe it is just completely
broken ?


FWIW bisecting Fuloong2E starts failing here:

4ea98d317eb442c738f898f16cfdd47a18b7ca49 is the first bad commit
commit 4ea98d317eb442c738f898f16cfdd47a18b7ca49
Author: BALATON Zoltan 
Date:   Fri Jan 25 14:52:12 2019 -0500

   ide/via: Implement and use native PCI IDE mode

   This device only implemented ISA compatibility mode and native PCI IDE
   mode was missing but no clients actually need ISA mode but to the
   contrary, they usually want to switch to and use device in native
   PCI IDE mode. Therefore implement native PCI mode and switch default
   to that.

   Signed-off-by: BALATON Zoltan 
   Message-id:
c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.bala...@eik.bme.hu
   Signed-off-by: John Snow 

hw/ide/via.c | 52 ++--
1 file changed, 38 insertions(+), 14 deletions(-)


How did you test? What guest OS and version have you used?

Regards,
BALATON Zoltan

Re: [PATCH] target/riscv/pmp: Raise exception if no PMP entry is configured

2020-12-23 Thread Atish Patra
On Tue, 2020-12-22 at 18:49 -0800, Richard Henderson wrote:
> On 12/22/20 5:21 PM, Atish Patra wrote:
> > +++ b/target/riscv/pmp.c
> > @@ -74,7 +74,7 @@ static inline int pmp_is_locked(CPURISCVState
> > *env, uint32_t pmp_index)
> >  /*
> >   * Count the number of active rules.
> >   */
> > -static inline uint32_t pmp_get_num_rules(CPURISCVState *env)
> > +inline uint32_t pmp_get_num_rules(CPURISCVState *env)
> >  {
> >   return env->pmp_state.num_rules;
> >  }
> ...
> > --- a/target/riscv/pmp.h
> > +++ b/target/riscv/pmp.h
> > @@ -64,5 +64,6 @@ bool pmp_is_range_in_tlb(CPURISCVState *env,
> > hwaddr tlb_sa,
> >   target_ulong *tlb_size);
> >  void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
> >  void pmp_update_rule_nums(CPURISCVState *env);
> > +uint32_t pmp_get_num_rules(CPURISCVState *env);
> 
> You need to remove the inline as well.
> 

Of course. Fixed in v2. Thanks.

> 
> r~

-- 
Regards,
Atish


[PATCH v2 2/2] pnv: Fix reverse dependency on PCI express root ports

2020-12-23 Thread Greg Kurz
qemu-system-ppc64 built with --without-default-devices crashes:

Type 'pnv-phb4-root-port' is missing its parent 'pcie-root-port-base'
Aborted (core dumped)

Have POWERNV to select PCIE_PORT. This is done through a
new PCI_POWERNV config in hw/pci-host/Kconfig since POWERNV
doesn't have a direct dependency on PCI. For this reason,
PCI_EXPRESS and MSI_NONBROKEN are also moved under
PCI_POWERNV.

Signed-off-by: Greg Kurz 
---
 hw/pci-host/Kconfig |5 +
 hw/pci-host/meson.build |2 +-
 hw/ppc/Kconfig  |3 +--
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index 036a61877a73..eb03f0489d08 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -60,3 +60,8 @@ config PCI_BONITO
 select PCI
 select UNIMP
 bool
+
+config PCI_POWERNV
+select PCI_EXPRESS
+select MSI_NONBROKEN
+select PCIE_PORT
diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
index e6d1b896848c..da9d1a9964a8 100644
--- a/hw/pci-host/meson.build
+++ b/hw/pci-host/meson.build
@@ -23,7 +23,7 @@ pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: 
files('versatile.c'))
 
 softmmu_ss.add_all(when: 'CONFIG_PCI', if_true: pci_ss)
 
-specific_ss.add(when: 'CONFIG_POWERNV', if_true: files(
+specific_ss.add(when: 'CONFIG_PCI_POWERNV', if_true: files(
   'pnv_phb3.c',
   'pnv_phb3_msi.c',
   'pnv_phb3_pbcq.c',
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 064bd6edd83d..501b9868568e 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -29,8 +29,7 @@ config POWERNV
 select XICS
 select XIVE
 select FDT_PPC
-select PCI_EXPRESS
-select MSI_NONBROKEN
+select PCI_POWERNV
 
 config PPC405
 bool





[PATCH v2 1/2] ppc: Fix build with --without-default-devices

2020-12-23 Thread Greg Kurz
Linking of the qemu-system-ppc64 fails on a POWER9 host when
--without-default-devices is passed to configure:

$ ./configure --without-default-devices \
  --target-list=ppc64-softmmu && make

...

libqemu-ppc64-softmmu.fa.p/hw_ppc_e500.c.o: In function `ppce500_init_mpic_kvm':
/home/greg/Work/qemu/qemu-ppc/build/../hw/ppc/e500.c:777: undefined reference 
to `kvm_openpic_connect_vcpu'
libqemu-ppc64-softmmu.fa.p/hw_ppc_spapr_irq.c.o: In function `spapr_irq_check':
/home/greg/Work/qemu/qemu-ppc/build/../hw/ppc/spapr_irq.c:189: undefined 
reference to `xics_kvm_has_broken_disconnect'
libqemu-ppc64-softmmu.fa.p/hw_intc_spapr_xive.c.o: In function 
`spapr_xive_post_load':
/home/greg/Work/qemu/qemu-ppc/build/../hw/intc/spapr_xive.c:530: undefined 
reference to `kvmppc_xive_post_load'

... and tons of other symbols belonging to the KVM backend of the
openpic, XICS and XIVE interrupt controllers.

It turns out that OPENPIC_KVM, XICS_KVM and XIVE_KVM are marked
to depend on KVM but this has no effect when minikconf runs in
allnoconfig mode. Such reverse dependencies should rather be
handled with a 'select' statement, eg.

config OPENPIC
select OPENPIC_KVM if KVM

or even better by getting rid of the intermediate _KVM config
and directly checking CONFIG_KVM in the meson.build file:

specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_OPENPIC'],
if_true: files('openpic_kvm.c'))

Go for the latter with OPENPIC, XICS and XIVE. While here also move
XIVE_SPAPR to hw/intc/Kconfig where it belongs.

This went unnoticed so far because CI doesn't test the build with
--without-default-devices and KVM enabled on a POWER host.

Signed-off-by: Greg Kurz 
---
v2: - check CONFIG_KVM in the meson.build as suggested by Paolo
---
 hw/intc/Kconfig |   14 +-
 hw/intc/meson.build |9 ++---
 hw/ppc/Kconfig  |   15 ---
 3 files changed, 11 insertions(+), 27 deletions(-)

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 468d548ca771..ee60d4bf7857 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -30,23 +30,19 @@ config ARM_GIC_KVM
 default y
 depends on ARM_GIC && KVM
 
-config OPENPIC_KVM
-bool
-default y
-depends on OPENPIC && KVM
-
 config XICS
 bool
-depends on POWERNV || PSERIES
 
 config XICS_SPAPR
 bool
 select XICS
 
-config XICS_KVM
+config XIVE
 bool
-default y
-depends on XICS && KVM
+
+config XIVE_SPAPR
+bool
+select XIVE
 
 config ALLWINNER_A10_PIC
 bool
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 68da782ad2c5..b6c9218908e3 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -39,7 +39,8 @@ specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: 
files('loongson_lioint
 specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
 specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_intc.c'))
 specific_ss.add(when: 'CONFIG_OMPIC', if_true: files('ompic.c'))
-specific_ss.add(when: 'CONFIG_OPENPIC_KVM', if_true: files('openpic_kvm.c'))
+specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_OPENPIC'],
+   if_true: files('openpic_kvm.c'))
 specific_ss.add(when: 'CONFIG_POWERNV', if_true: files('xics_pnv.c', 
'pnv_xive.c'))
 specific_ss.add(when: 'CONFIG_PPC_UIC', if_true: files('ppc-uic.c'))
 specific_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_ic.c', 
'bcm2836_control.c'))
@@ -50,8 +51,10 @@ specific_ss.add(when: 'CONFIG_SH4', if_true: 
files('sh_intc.c'))
 specific_ss.add(when: 'CONFIG_SIFIVE_CLINT', if_true: files('sifive_clint.c'))
 specific_ss.add(when: 'CONFIG_SIFIVE_PLIC', if_true: files('sifive_plic.c'))
 specific_ss.add(when: 'CONFIG_XICS', if_true: files('xics.c'))
-specific_ss.add(when: 'CONFIG_XICS_KVM', if_true: files('xics_kvm.c'))
+specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XICS'],
+   if_true: files('xics_kvm.c'))
 specific_ss.add(when: 'CONFIG_XICS_SPAPR', if_true: files('xics_spapr.c'))
 specific_ss.add(when: 'CONFIG_XIVE', if_true: files('xive.c'))
-specific_ss.add(when: 'CONFIG_XIVE_KVM', if_true: files('spapr_xive_kvm.c'))
+specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'],
+   if_true: files('spapr_xive_kvm.c'))
 specific_ss.add(when: 'CONFIG_XIVE_SPAPR', if_true: files('spapr_xive.c'))
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 982d55f5875c..064bd6edd83d 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -129,21 +129,6 @@ config VIRTEX
 select XILINX_ETHLITE
 select FDT_PPC
 
-config XIVE
-bool
-depends on POWERNV || PSERIES
-
-config XIVE_SPAPR
-bool
-default y
-depends on PSERIES
-select XIVE
-
-config XIVE_KVM
-bool
-default y
-depends on XIVE_SPAPR && KVM
-
 # Only used by 64-bit targets
 config FW_CFG_PPC
 bool





[PATCH v2] target/riscv/pmp: Raise exception if no PMP entry is configured

2020-12-23 Thread Atish Patra
As per the privilege specification, any access from S/U mode should fail
if no pmp region is configured.

Signed-off-by: Atish Patra 
---
Changes from v2->v1
1. Removed the static from the function definition
---
 target/riscv/op_helper.c | 5 +
 target/riscv/pmp.c   | 4 ++--
 target/riscv/pmp.h   | 1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index d55def76cffd..1eddcb94de7e 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -150,6 +150,11 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong 
cpu_pc_deb)
 
 uint64_t mstatus = env->mstatus;
 target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
+
+if (!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
+riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+}
+
 target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
 mstatus = set_field(mstatus, MSTATUS_MIE,
 get_field(mstatus, MSTATUS_MPIE));
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 2eda8e1e2f07..80d0334e1bfc 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -74,7 +74,7 @@ static inline int pmp_is_locked(CPURISCVState *env, uint32_t 
pmp_index)
 /*
  * Count the number of active rules.
  */
-static inline uint32_t pmp_get_num_rules(CPURISCVState *env)
+uint32_t pmp_get_num_rules(CPURISCVState *env)
 {
  return env->pmp_state.num_rules;
 }
@@ -237,7 +237,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 
 /* Short cut if no rules */
 if (0 == pmp_get_num_rules(env)) {
-return true;
+return (env->priv == PRV_M) ? true : false;
 }
 
 if (size == 0) {
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index 6c6b4c9befe8..c8d5ef4a694e 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -64,5 +64,6 @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
  target_ulong *tlb_size);
 void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
 void pmp_update_rule_nums(CPURISCVState *env);
+uint32_t pmp_get_num_rules(CPURISCVState *env);
 
 #endif
-- 
2.25.1




Re: [PATCH] multi-process: Acceptance test for multiprocess QEMU

2020-12-23 Thread Wainer dos Santos Moschetta



On 12/23/20 3:44 AM, elena.ufimts...@oracle.com wrote:

From: Jagannathan Raman 

Runs the Avocado acceptance test to check if a
remote lsi53c895a device gets identified by the guest.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
  tests/acceptance/multiprocess.py | 104 +++
  1 file changed, 104 insertions(+)
  create mode 100644 tests/acceptance/multiprocess.py


The test looks good. Thanks for contributing it!

Reviewed-by: Wainer dos Santos Moschetta 



diff --git a/tests/acceptance/multiprocess.py b/tests/acceptance/multiprocess.py
new file mode 100644
index 00..d10b4d2c05
--- /dev/null
+++ b/tests/acceptance/multiprocess.py
@@ -0,0 +1,104 @@
+# Test for multiprocess qemu
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+
+from avocado_qemu import Test
+from avocado_qemu import wait_for_console_pattern
+from avocado_qemu import exec_command_and_wait_for_pattern
+
+from qemu.accel import kvm_available
+
+import os
+import socket
+
+ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available"
+KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
+
+class Multiprocess(Test):
+"""
+:avocado: tags=multiprocess
+"""
+KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
+
+def wait_for_console_pattern(self, success_message, vm=None):
+wait_for_console_pattern(self, success_message,
+ failure_message='Kernel panic - not syncing',
+ vm=vm)
+
+def do_test(self, kernel_url, initrd_url, kernel_command_line,
+machine_type):
+if not kvm_available(self.arch, self.qemu_bin):
+self.cancel(KVM_NOT_AVAILABLE)
+
+# Create socketpair to connect proxy and remote processes
+proxy_sock, remote_sock = socket.socketpair(socket.AF_UNIX,
+socket.SOCK_STREAM)
+os.set_inheritable(proxy_sock.fileno(), True)
+os.set_inheritable(remote_sock.fileno(), True)
+
+kernel_path = self.fetch_asset(kernel_url)
+initrd_path = self.fetch_asset(initrd_url)
+
+# Create remote process
+remote_vm = self.get_vm()
+remote_vm.add_args('-machine', 'x-remote')
+remote_vm.add_args('-nodefaults')
+remote_vm.add_args('-device', 'lsi53c895a,id=lsi1')
+remote_vm.add_args('-object', 'x-remote-object,id=robj1,'
+   'devid=lsi1,fd='+str(remote_sock.fileno()))
+remote_vm.launch()
+
+# Create proxy process
+self.vm.set_console()
+self.vm.add_args('-machine', machine_type)
+self.vm.add_args('-accel', 'kvm')
+self.vm.add_args('-cpu', 'host')
+self.vm.add_args("-object",
+ "memory-backend-memfd,id=sysmem-file,size=2G")
+self.vm.add_args("--numa", "node,memdev=sysmem-file")
+self.vm.add_args("-m", "2048")
+self.vm.add_args('-kernel', kernel_path,
+ '-initrd', initrd_path,
+ '-append', kernel_command_line)
+self.vm.add_args('-device',
+ 'x-pci-proxy-dev,'
+ 'id=lsi1,fd='+str(proxy_sock.fileno()))
+self.vm.launch()
+self.wait_for_console_pattern("as init process")
+exec_command_and_wait_for_pattern(self, "mount -t sysfs sysfs /sys",
+  '', '')
+exec_command_and_wait_for_pattern(self,
+  "cat /sys/bus/pci/devices/*/uevent",
+  "PCI_ID=1000:0012", '')
+
+def test_multiprocess_x86_64(self):
+"""
+:avocado: tags=arch:x86_64
+"""
+kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
+  '/linux/releases/31/Everything/x86_64/os/images'
+  '/pxeboot/vmlinuz')
+initrd_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
+  '/linux/releases/31/Everything/x86_64/os/images'
+  '/pxeboot/initrd.img')
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+   'console=ttyS0 rdinit=/bin/bash')
+machine = 'pc'
+self.do_test(kernel_url, initrd_url, kernel_command_line, machine)
+
+def test_multiprocess_aarch64(self):
+"""
+:avocado: tags=arch:aarch64
+"""
+kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
+  '/linux/releases/31/Everything/aarch64/os/images'
+  '/pxeboot/vmlinuz')
+initrd_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
+  '/linux/releases/31/Everything/aarch64/os/images'
+  

Re: [PATCH] multi-process: Acceptance test for multiprocess QEMU

2020-12-23 Thread Elena Ufimtseva
On Wed, Dec 23, 2020 at 03:01:24PM +0400, Marc-André Lureau wrote:
> Hi
> 
> On Wed, Dec 23, 2020 at 10:45 AM  wrote:
> 
> > From: Jagannathan Raman 
> >
> > Runs the Avocado acceptance test to check if a
> > remote lsi53c895a device gets identified by the guest.
> >
> > Signed-off-by: Elena Ufimtseva 
> > Signed-off-by: John G Johnson 
> > Signed-off-by: Jagannathan Raman 
> > ---
> >  tests/acceptance/multiprocess.py | 104 +++
> >  1 file changed, 104 insertions(+)
> >  create mode 100644 tests/acceptance/multiprocess.py
> >
> > diff --git a/tests/acceptance/multiprocess.py
> > b/tests/acceptance/multiprocess.py
> > new file mode 100644
> > index 00..d10b4d2c05
> > --- /dev/null
> > +++ b/tests/acceptance/multiprocess.py
> > @@ -0,0 +1,104 @@
> > +# Test for multiprocess qemu
> > +#
> > +# This work is licensed under the terms of the GNU GPL, version 2 or
> > +# later.  See the COPYING file in the top-level directory.
> > +
> > +
> > +from avocado_qemu import Test
> > +from avocado_qemu import wait_for_console_pattern
> > +from avocado_qemu import exec_command_and_wait_for_pattern
> > +
> > +from qemu.accel import kvm_available
> > +
> > +import os
> > +import socket
> > +
> > +ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available"
> > +KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
> > +
> > +class Multiprocess(Test):
> > +"""
> > +:avocado: tags=multiprocess
> > +"""
> > +KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
> > +
> > +def wait_for_console_pattern(self, success_message, vm=None):
> > +wait_for_console_pattern(self, success_message,
> > + failure_message='Kernel panic - not
> > syncing',
> > + vm=vm)
> > +
> > +def do_test(self, kernel_url, initrd_url, kernel_command_line,
> > +machine_type):
> > +if not kvm_available(self.arch, self.qemu_bin):
> > +self.cancel(KVM_NOT_AVAILABLE)
> > +
> > +# Create socketpair to connect proxy and remote processes
> > +proxy_sock, remote_sock = socket.socketpair(socket.AF_UNIX,
> > +socket.SOCK_STREAM)
> > +os.set_inheritable(proxy_sock.fileno(), True)
> > +os.set_inheritable(remote_sock.fileno(), True)
> > +
> > +kernel_path = self.fetch_asset(kernel_url)
> > +initrd_path = self.fetch_asset(initrd_url)
> > +
> > +# Create remote process
> > +remote_vm = self.get_vm()
> > +remote_vm.add_args('-machine', 'x-remote')
> > +remote_vm.add_args('-nodefaults')
> > +remote_vm.add_args('-device', 'lsi53c895a,id=lsi1')
> > +remote_vm.add_args('-object', 'x-remote-object,id=robj1,'
> > +   'devid=lsi1,fd='+str(remote_sock.fileno()))
> > +remote_vm.launch()
> > +
> > +# Create proxy process
> > +self.vm.set_console()
> > +self.vm.add_args('-machine', machine_type)
> > +self.vm.add_args('-accel', 'kvm')
> > +self.vm.add_args('-cpu', 'host')
> > +self.vm.add_args("-object",
> > + "memory-backend-memfd,id=sysmem-file,size=2G")
> > +self.vm.add_args("--numa", "node,memdev=sysmem-file")
> > +self.vm.add_args("-m", "2048")
> > +self.vm.add_args('-kernel', kernel_path,
> > + '-initrd', initrd_path,
> > + '-append', kernel_command_line)
> > +self.vm.add_args('-device',
> > + 'x-pci-proxy-dev,'
> > + 'id=lsi1,fd='+str(proxy_sock.fileno()))
> > +self.vm.launch()
> > +self.wait_for_console_pattern("as init process")
> > +exec_command_and_wait_for_pattern(self, "mount -t sysfs sysfs
> > /sys",
> > +  '', '')
> > +exec_command_and_wait_for_pattern(self,
> > +  "cat
> > /sys/bus/pci/devices/*/uevent",
> > +  "PCI_ID=1000:0012", '')
> > +
> > +def test_multiprocess_x86_64(self):
> > +"""
> > +:avocado: tags=arch:x86_64
> > +"""
> > +kernel_url = ('
> > https://archives.fedoraproject.org/pub/archive/fedora'
> > +  '/linux/releases/31/Everything/x86_64/os/images'
> > +  '/pxeboot/vmlinuz')
> > +initrd_url = ('
> > https://archives.fedoraproject.org/pub/archive/fedora'
> > +  '/linux/releases/31/Everything/x86_64/os/images'
> > +  '/pxeboot/initrd.img')
> > +kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
> > +   'console=ttyS0 rdinit=/bin/bash')
> > +machine = 'pc'
> > +self.do_test(kernel_url, initrd_url, kernel_command_line, machine)
> > +
> > +def test_multiprocess_aarch64(self):
> > +   

Re: [PATCH] multi-process: Acceptance test for multiprocess QEMU

2020-12-23 Thread Wainer dos Santos Moschetta

Hi,

On 12/23/20 8:01 AM, Marc-André Lureau wrote:

Hi

On Wed, Dec 23, 2020 at 10:45 AM > wrote:


From: Jagannathan Raman mailto:jag.ra...@oracle.com>>

Runs the Avocado acceptance test to check if a
remote lsi53c895a device gets identified by the guest.

Signed-off-by: Elena Ufimtseva mailto:elena.ufimts...@oracle.com>>
Signed-off-by: John G Johnson mailto:john.g.john...@oracle.com>>
Signed-off-by: Jagannathan Raman mailto:jag.ra...@oracle.com>>
---
 tests/acceptance/multiprocess.py | 104
+++
 1 file changed, 104 insertions(+)
 create mode 100644 tests/acceptance/multiprocess.py

diff --git a/tests/acceptance/multiprocess.py
b/tests/acceptance/multiprocess.py
new file mode 100644
index 00..d10b4d2c05
--- /dev/null
+++ b/tests/acceptance/multiprocess.py
@@ -0,0 +1,104 @@
+# Test for multiprocess qemu
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+
+from avocado_qemu import Test
+from avocado_qemu import wait_for_console_pattern
+from avocado_qemu import exec_command_and_wait_for_pattern
+
+from qemu.accel import kvm_available
+
+import os
+import socket
+
+ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be
available"
+KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
+
+class Multiprocess(Test):
+    """
+    :avocado: tags=multiprocess
+    """
+    KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
+
+    def wait_for_console_pattern(self, success_message, vm=None):
+        wait_for_console_pattern(self, success_message,
+                                 failure_message='Kernel panic -
not syncing',
+                                 vm=vm)
+
+    def do_test(self, kernel_url, initrd_url, kernel_command_line,
+                machine_type):
+        if not kvm_available(self.arch, self.qemu_bin):
+            self.cancel(KVM_NOT_AVAILABLE)
+
+        # Create socketpair to connect proxy and remote processes
+        proxy_sock, remote_sock = socket.socketpair(socket.AF_UNIX,
+ socket.SOCK_STREAM)
+        os.set_inheritable(proxy_sock.fileno(), True)
+        os.set_inheritable(remote_sock.fileno(), True)
+
+        kernel_path = self.fetch_asset(kernel_url)
+        initrd_path = self.fetch_asset(initrd_url)
+
+        # Create remote process
+        remote_vm = self.get_vm()
+        remote_vm.add_args('-machine', 'x-remote')
+        remote_vm.add_args('-nodefaults')
+        remote_vm.add_args('-device', 'lsi53c895a,id=lsi1')
+        remote_vm.add_args('-object', 'x-remote-object,id=robj1,'
+  'devid=lsi1,fd='+str(remote_sock.fileno()))
+        remote_vm.launch()
+
+        # Create proxy process
+        self.vm.set_console()
+        self.vm.add_args('-machine', machine_type)
+        self.vm.add_args('-accel', 'kvm')
+        self.vm.add_args('-cpu', 'host')
+        self.vm.add_args("-object",
+  "memory-backend-memfd,id=sysmem-file,size=2G")
+        self.vm.add_args("--numa", "node,memdev=sysmem-file")
+        self.vm.add_args("-m", "2048")
+        self.vm.add_args('-kernel', kernel_path,
+                         '-initrd', initrd_path,
+                         '-append', kernel_command_line)
+        self.vm.add_args('-device',
+                         'x-pci-proxy-dev,'
+  'id=lsi1,fd='+str(proxy_sock.fileno()))
+        self.vm.launch()
+        self.wait_for_console_pattern("as init process")
+        exec_command_and_wait_for_pattern(self, "mount -t sysfs
sysfs /sys",
+                                          '', '')
+        exec_command_and_wait_for_pattern(self,
+                                          "cat
/sys/bus/pci/devices/*/uevent",
+ "PCI_ID=1000:0012", '')
+
+    def test_multiprocess_x86_64(self):
+        """
+        :avocado: tags=arch:x86_64
+        """
+        kernel_url =
('https://archives.fedoraproject.org/pub/archive/fedora
'
+ '/linux/releases/31/Everything/x86_64/os/images'
+                      '/pxeboot/vmlinuz')
+        initrd_url =
('https://archives.fedoraproject.org/pub/archive/fedora
'
+ '/linux/releases/31/Everything/x86_64/os/images'
+                      '/pxeboot/initrd.img')
+        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+                               'console=ttyS0 rdinit=/bin/bash')
+        machine = 'pc'
+        self.do_test(kernel_url, initrd_url, kernel_command_line,
machine)
+

Re: [RFC PATCH 1/3] mm: support hugetlb free page reporting

2020-12-23 Thread Mike Kravetz
On 12/22/20 7:57 PM, Liang Li wrote:
>> On 12/21/20 11:46 PM, Liang Li wrote:
>>> +static int
>>> +hugepage_reporting_cycle(struct page_reporting_dev_info *prdev,
>>> +  struct hstate *h, unsigned int nid,
>>> +  struct scatterlist *sgl, unsigned int *offset)
>>> +{
>>> + struct list_head *list = >hugepage_freelists[nid];
>>> + unsigned int page_len = PAGE_SIZE << h->order;
>>> + struct page *page, *next;
>>> + long budget;
>>> + int ret = 0, scan_cnt = 0;
>>> +
>>> + /*
>>> +  * Perform early check, if free area is empty there is
>>> +  * nothing to process so we can skip this free_list.
>>> +  */
>>> + if (list_empty(list))
>>> + return ret;
>>
>> Do note that not all entries on the hugetlb free lists are free.  Reserved
>> entries are also on the free list.  The actual number of free entries is
>> 'h->free_huge_pages - h->resv_huge_pages'.
>> Is the intention to process reserved pages as well as free pages?
> 
> Yes, Reserved pages was treated as 'free pages'

If that is true, then this code breaks hugetlb.  hugetlb code assumes that
h->free_huge_pages is ALWAYS >= h->resv_huge_pages.  This code would break
that assumption.  If you really want to add support for hugetlb pages, then
you will need to take reserved pages into account.

P.S. There might be some confusion about 'reservations' based on the
commit message.  My comments are directed at hugetlb reservations described
in Documentation/vm/hugetlbfs_reserv.rst.

>>> +
>>> + spin_lock_irq(_lock);
>>> +
>>> + if (huge_page_order(h) > MAX_ORDER)
>>> + budget = HUGEPAGE_REPORTING_CAPACITY;
>>> + else
>>> + budget = HUGEPAGE_REPORTING_CAPACITY * 32;
>>> +
>>> + /* loop through free list adding unreported pages to sg list */
>>> + list_for_each_entry_safe(page, next, list, lru) {
>>> + /* We are going to skip over the reported pages. */
>>> + if (PageReported(page)) {
>>> + if (++scan_cnt >= MAX_SCAN_NUM) {
>>> + ret = scan_cnt;
>>> + break;
>>> + }
>>> + continue;
>>> + }
>>> +
>>> + /*
>>> +  * If we fully consumed our budget then update our
>>> +  * state to indicate that we are requesting additional
>>> +  * processing and exit this list.
>>> +  */
>>> + if (budget < 0) {
>>> + atomic_set(>state, PAGE_REPORTING_REQUESTED);
>>> + next = page;
>>> + break;
>>> + }
>>> +
>>> + /* Attempt to pull page from list and place in scatterlist */
>>> + if (*offset) {
>>> + isolate_free_huge_page(page, h, nid);
>>
>> Once a hugetlb page is isolated, it can not be used and applications that
>> depend on hugetlb pages can start to fail.
>> I assume that is acceptable/expected behavior.  Correct?
>> On some systems, hugetlb pages are a precious resource and the sysadmin
>> carefully configures the number needed by applications.  Removing a hugetlb
>> page (even for a very short period of time) could cause serious application
>> failure.
> 
> That' true, especially for 1G pages. Any suggestions?
> Let the hugepage allocator be aware of this situation and retry ?

I would hate to add that complexity to the allocator.

This question is likely based on my lack of understanding of virtio-balloon
usage and this reporting mechanism.  But, why do the hugetlb pages have to
be 'temporarily' allocated for reporting purposes?

-- 
Mike Kravetz



Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Mark Cave-Ayland

On 23/12/2020 13:17, BALATON Zoltan via wrote:


On Wed, 23 Dec 2020, Mark Cave-Ayland wrote:

On 22/12/2020 21:23, Guenter Roeck wrote:

(Added jiaxun.y...@flygoat.com as CC)


Are you sure? It does not show up on cc list for me so unless the list ate it you 
might have forgotten to copy the address there. Done now just in case, sorry if this 
resulted in double post.


Regards,
BALATON Zoltan


I've added the address to the CC (and I can confirm from the exim logs that it gets 
accepted), however the list copy removes it. Perhaps Jiaxun isn't subscribed to 
qemu-devel?



ATB,

Mark.



Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Mark Cave-Ayland

On 23/12/2020 17:01, Guenter Roeck wrote:


On 12/23/20 8:09 AM, Mark Cave-Ayland wrote:

On 23/12/2020 15:21, Philippe Mathieu-Daudé wrote:


On 12/22/20 5:16 PM, Guenter Roeck wrote:

Hi,

commit 459ca8bfa41 ("pci: Assert irqnum is between 0 and bus->nirqs in
pci_bus_change_irq_level") added sanity checks to the interrupt number passed
to pci_bus_change_irq_level(). That makes sense, given that bus->irq_count
is indexed and sized by the number of interrupts.

However, as it turns out, the interrupt number passed to this function
is the _mapped_ interrupt number. The result in assertion failures for various
emulations.

Examples (I don't know if there are others):

- ppc4xx_pci_map_irq() maps the interrupt number to "slot - 1". Obviously
    that isn't a good thing to do for slot 0, and indeed results in an
    assertion as soon as slot 0 is initialized (presumably that is the root
    bridge). Changing the mapping to "slot" doesn't help because valid slots
    are 0..4, and only four interrupts are allocated.
- pci_bonito_map_irq() changes the mapping all over the place. Whatever
    it does, it returns numbers starting with 32 for slots 5..12. With
    a total number of 32 interrupts, this again results in an assertion
    failure.

ppc4xx_pci_map_irq() is definitely buggy. I just don't know what the
correct mapping should be. slot  & 3, maybe ?

I don't really have a good solution for pci_bonito_map_irq(). It may not
matter much - I have not been able to boot fuloong_2e since qemu v4.0,
and afaics that is the only platform using it. Maybe it is just completely
broken ?


FWIW bisecting Fuloong2E starts failing here:

4ea98d317eb442c738f898f16cfdd47a18b7ca49 is the first bad commit
commit 4ea98d317eb442c738f898f16cfdd47a18b7ca49
Author: BALATON Zoltan 
Date:   Fri Jan 25 14:52:12 2019 -0500

  ide/via: Implement and use native PCI IDE mode

  This device only implemented ISA compatibility mode and native PCI IDE
  mode was missing but no clients actually need ISA mode but to the
  contrary, they usually want to switch to and use device in native
  PCI IDE mode. Therefore implement native PCI mode and switch default
  to that.

  Signed-off-by: BALATON Zoltan 
  Message-id:
c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.bala...@eik.bme.hu
  Signed-off-by: John Snow 

   hw/ide/via.c | 52 ++--
   1 file changed, 38 insertions(+), 14 deletions(-)


I think the original version of the patch broke fuloong2e, however that should 
have been fixed by my patchset here: 
https://lists.gnu.org/archive/html/qemu-devel/2020-03/msg03936.html. It might 
be that there are multiple regressions located during a full bisect :/



Not really. The following patch on top of qemu 5.2 results in the ide drive
being detected and working.

diff --git a/hw/ide/via.c b/hw/ide/via.c
index be09912b33..1bfdc422ee 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -186,11 +186,14 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
  pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]);

  bmdma_setup_bar(d);
+#if 0
  pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar);
+#endif

  qdev_init_gpio_in(ds, via_ide_set_irq, 2);
  for (i = 0; i < 2; i++) {
  ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2);
+ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, i ? 0x376 : 
0x3f6);
  ide_init2(>bus[i], qdev_get_gpio_in(ds, i));

  bmdma_init(>bus[i], >bmdma[i], d);

With the added ide_init_ioport(), the drive is detected. With the #if 0,
it actually starts working. So there are two problems: 1) The qemu ide
subsystem isn't informed about the io addresses, and 2) bmdma isn't working.


Interesting: that's basically disabling BMDMA and switching back to use legacy IDE 
again. Regardless of this it seems I need a better test case for this, and some input 
from people who know the hardware better :(



ATB,

Mark.



[PATCH] gdb: riscv: Add target description

2020-12-23 Thread Sylvain Pelissier
Target description is not currently implemented in RISC-V architecture.
Thus GDB won't set it properly when attached. The patch implements the
target description response.

Signed-off-by: Sylvain Pelissier 
---
 target/riscv/cpu.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 254cd83f8b..489d66038c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -556,6 +556,15 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };

+static gchar *riscv_gdb_arch_name(CPUState *cs)
+{
+#ifdef TARGET_RISCV64
+return g_strdup("riscv:rv64");
+#else
+return g_strdup("riscv:rv32");
+#endif
+}
+
 static void riscv_cpu_class_init(ObjectClass *c, void *data)
 {
 RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
@@ -591,6 +600,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void
*data)
 /* For now, mark unmigratable: */
 cc->vmsd = _riscv_cpu;
 #endif
+cc->gdb_arch_name = riscv_gdb_arch_name;
 #ifdef CONFIG_TCG
 cc->tcg_initialize = riscv_translate_init;
 cc->tlb_fill = riscv_cpu_tlb_fill;
-- 
2.25.1


Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Guenter Roeck
On 12/23/20 8:09 AM, Mark Cave-Ayland wrote:
> On 23/12/2020 15:21, Philippe Mathieu-Daudé wrote:
> 
>> On 12/22/20 5:16 PM, Guenter Roeck wrote:
>>> Hi,
>>>
>>> commit 459ca8bfa41 ("pci: Assert irqnum is between 0 and bus->nirqs in
>>> pci_bus_change_irq_level") added sanity checks to the interrupt number 
>>> passed
>>> to pci_bus_change_irq_level(). That makes sense, given that bus->irq_count
>>> is indexed and sized by the number of interrupts.
>>>
>>> However, as it turns out, the interrupt number passed to this function
>>> is the _mapped_ interrupt number. The result in assertion failures for 
>>> various
>>> emulations.
>>>
>>> Examples (I don't know if there are others):
>>>
>>> - ppc4xx_pci_map_irq() maps the interrupt number to "slot - 1". Obviously
>>>    that isn't a good thing to do for slot 0, and indeed results in an
>>>    assertion as soon as slot 0 is initialized (presumably that is the root
>>>    bridge). Changing the mapping to "slot" doesn't help because valid slots
>>>    are 0..4, and only four interrupts are allocated.
>>> - pci_bonito_map_irq() changes the mapping all over the place. Whatever
>>>    it does, it returns numbers starting with 32 for slots 5..12. With
>>>    a total number of 32 interrupts, this again results in an assertion
>>>    failure.
>>>
>>> ppc4xx_pci_map_irq() is definitely buggy. I just don't know what the
>>> correct mapping should be. slot  & 3, maybe ?
>>>
>>> I don't really have a good solution for pci_bonito_map_irq(). It may not
>>> matter much - I have not been able to boot fuloong_2e since qemu v4.0,
>>> and afaics that is the only platform using it. Maybe it is just completely
>>> broken ?
>>
>> FWIW bisecting Fuloong2E starts failing here:
>>
>> 4ea98d317eb442c738f898f16cfdd47a18b7ca49 is the first bad commit
>> commit 4ea98d317eb442c738f898f16cfdd47a18b7ca49
>> Author: BALATON Zoltan 
>> Date:   Fri Jan 25 14:52:12 2019 -0500
>>
>>  ide/via: Implement and use native PCI IDE mode
>>
>>  This device only implemented ISA compatibility mode and native PCI IDE
>>  mode was missing but no clients actually need ISA mode but to the
>>  contrary, they usually want to switch to and use device in native
>>  PCI IDE mode. Therefore implement native PCI mode and switch default
>>  to that.
>>
>>  Signed-off-by: BALATON Zoltan 
>>  Message-id:
>> c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.bala...@eik.bme.hu
>>  Signed-off-by: John Snow 
>>
>>   hw/ide/via.c | 52 ++--
>>   1 file changed, 38 insertions(+), 14 deletions(-)
> 
> I think the original version of the patch broke fuloong2e, however that 
> should have been fixed by my patchset here: 
> https://lists.gnu.org/archive/html/qemu-devel/2020-03/msg03936.html. It might 
> be that there are multiple regressions located during a full bisect :/
> 

Not really. The following patch on top of qemu 5.2 results in the ide drive
being detected and working.

diff --git a/hw/ide/via.c b/hw/ide/via.c
index be09912b33..1bfdc422ee 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -186,11 +186,14 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
 pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]);

 bmdma_setup_bar(d);
+#if 0
 pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar);
+#endif

 qdev_init_gpio_in(ds, via_ide_set_irq, 2);
 for (i = 0; i < 2; i++) {
 ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2);
+ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, i ? 0x376 : 
0x3f6);
 ide_init2(>bus[i], qdev_get_gpio_in(ds, i));

 bmdma_init(>bus[i], >bmdma[i], d);

With the added ide_init_ioport(), the drive is detected. With the #if 0,
it actually starts working. So there are two problems: 1) The qemu ide
subsystem isn't informed about the io addresses, and 2) bmdma isn't working.

Guenter



Re: [RFC PATCH 1/3] mm: support hugetlb free page reporting

2020-12-23 Thread Alexander Duyck
On Tue, Dec 22, 2020 at 7:39 PM Liang Li  wrote:
>
> > > +hugepage_reporting_cycle(struct page_reporting_dev_info *prdev,
> > > +struct hstate *h, unsigned int nid,
> > > +struct scatterlist *sgl, unsigned int *offset)
> > > +{
> > > +   struct list_head *list = >hugepage_freelists[nid];
> > > +   unsigned int page_len = PAGE_SIZE << h->order;
> > > +   struct page *page, *next;
> > > +   long budget;
> > > +   int ret = 0, scan_cnt = 0;
> > > +
> > > +   /*
> > > +* Perform early check, if free area is empty there is
> > > +* nothing to process so we can skip this free_list.
> > > +*/
> > > +   if (list_empty(list))
> > > +   return ret;
> > > +
> > > +   spin_lock_irq(_lock);
> > > +
> > > +   if (huge_page_order(h) > MAX_ORDER)
> > > +   budget = HUGEPAGE_REPORTING_CAPACITY;
> > > +   else
> > > +   budget = HUGEPAGE_REPORTING_CAPACITY * 32;
> >
> > Wouldn't huge_page_order always be more than MAX_ORDER? Seems like we
> > don't even really need budget since this should probably be pulling
> > out no more than one hugepage at a time.
>
> I want to disting a 2M page and 1GB page here. The order of 1GB page is 
> greater
> than MAX_ORDER while 2M page's order is less than MAX_ORDER.

The budget here is broken. When I put the budget in page reporting it
was so that we wouldn't try to report all of the memory in a given
region. It is meant to hold us to no more than one pass through 1/16
of the free memory. So essentially we will be slowly processing all of
memory and it will take 16 calls (32 seconds) for us to process a
system that is sitting completely idle. It is meant to pace us so we
don't spend a ton of time doing work that will be undone, not to
prevent us from burying a CPU which is what seems to be implied here.

Using HUGEPAGE_REPORTING_CAPACITY makes no sense here. I was using it
in the original definition because it was how many pages we could
scoop out at a time and then I was aiming for a 16th of that. Here you
are arbitrarily squaring HUGEPAGE_REPORTING_CAPACITY in terms of the
amount of work you will doo since you are using it as a multiple
instead of a divisor.

> >
> > > +   /* loop through free list adding unreported pages to sg list */
> > > +   list_for_each_entry_safe(page, next, list, lru) {
> > > +   /* We are going to skip over the reported pages. */
> > > +   if (PageReported(page)) {
> > > +   if (++scan_cnt >= MAX_SCAN_NUM) {
> > > +   ret = scan_cnt;
> > > +   break;
> > > +   }
> > > +   continue;
> > > +   }
> > > +
> >
> > It would probably have been better to place this set before your new
> > set. I don't see your new set necessarily being the best use for page
> > reporting.
>
> I haven't really latched on to what you mean, could you explain it again?

It would be better for you to spend time understanding how this patch
set works before you go about expanding it to do other things.
Mistakes like the budget one above kind of point out the fact that you
don't understand how this code was supposed to work and just kind of
shoehorned you page zeroing code onto it.

It would be better to look at trying to understand this code first
before you extend it to support your zeroing use case. So adding huge
pages first might make more sense than trying to zero and push the
order down. The fact is the page reporting extension should be minimal
for huge pages since they are just passed as a scatterlist so you
should only need to add a small bit to page_reporting.c to extend it
to support this use case.

> >
> > > +   /*
> > > +* If we fully consumed our budget then update our
> > > +* state to indicate that we are requesting additional
> > > +* processing and exit this list.
> > > +*/
> > > +   if (budget < 0) {
> > > +   atomic_set(>state, 
> > > PAGE_REPORTING_REQUESTED);
> > > +   next = page;
> > > +   break;
> > > +   }
> > > +
> >
> > If budget is only ever going to be 1 then we probably could just look
> > at making this the default case for any time we find a non-reported
> > page.
>
> and here again.

It comes down to the fact that the changes you made have a significant
impact on how this is supposed to function. Reducing the scatterlist
to a size of one makes the whole point of doing batching kind of
pointless. Basically the code should be rewritten with the assumption
that if you find a page you report it.

The old code would batch things up because there is significant
overhead to be addressed when going to the hypervisor to report said
memory. Your code doesn't seem to really take anything like that into
account 

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Mark Cave-Ayland

On 23/12/2020 15:21, Philippe Mathieu-Daudé wrote:


On 12/22/20 5:16 PM, Guenter Roeck wrote:

Hi,

commit 459ca8bfa41 ("pci: Assert irqnum is between 0 and bus->nirqs in
pci_bus_change_irq_level") added sanity checks to the interrupt number passed
to pci_bus_change_irq_level(). That makes sense, given that bus->irq_count
is indexed and sized by the number of interrupts.

However, as it turns out, the interrupt number passed to this function
is the _mapped_ interrupt number. The result in assertion failures for various
emulations.

Examples (I don't know if there are others):

- ppc4xx_pci_map_irq() maps the interrupt number to "slot - 1". Obviously
   that isn't a good thing to do for slot 0, and indeed results in an
   assertion as soon as slot 0 is initialized (presumably that is the root
   bridge). Changing the mapping to "slot" doesn't help because valid slots
   are 0..4, and only four interrupts are allocated.
- pci_bonito_map_irq() changes the mapping all over the place. Whatever
   it does, it returns numbers starting with 32 for slots 5..12. With
   a total number of 32 interrupts, this again results in an assertion
   failure.

ppc4xx_pci_map_irq() is definitely buggy. I just don't know what the
correct mapping should be. slot  & 3, maybe ?

I don't really have a good solution for pci_bonito_map_irq(). It may not
matter much - I have not been able to boot fuloong_2e since qemu v4.0,
and afaics that is the only platform using it. Maybe it is just completely
broken ?


FWIW bisecting Fuloong2E starts failing here:

4ea98d317eb442c738f898f16cfdd47a18b7ca49 is the first bad commit
commit 4ea98d317eb442c738f898f16cfdd47a18b7ca49
Author: BALATON Zoltan 
Date:   Fri Jan 25 14:52:12 2019 -0500

 ide/via: Implement and use native PCI IDE mode

 This device only implemented ISA compatibility mode and native PCI IDE
 mode was missing but no clients actually need ISA mode but to the
 contrary, they usually want to switch to and use device in native
 PCI IDE mode. Therefore implement native PCI mode and switch default
 to that.

 Signed-off-by: BALATON Zoltan 
 Message-id:
c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.bala...@eik.bme.hu
 Signed-off-by: John Snow 

  hw/ide/via.c | 52 ++--
  1 file changed, 38 insertions(+), 14 deletions(-)


I think the original version of the patch broke fuloong2e, however that should have 
been fixed by my patchset here: 
https://lists.gnu.org/archive/html/qemu-devel/2020-03/msg03936.html. It might be that 
there are multiple regressions located during a full bisect :/



ATB,

Mark.



Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Philippe Mathieu-Daudé
On 12/22/20 5:16 PM, Guenter Roeck wrote:
> Hi,
> 
> commit 459ca8bfa41 ("pci: Assert irqnum is between 0 and bus->nirqs in
> pci_bus_change_irq_level") added sanity checks to the interrupt number passed
> to pci_bus_change_irq_level(). That makes sense, given that bus->irq_count
> is indexed and sized by the number of interrupts.
> 
> However, as it turns out, the interrupt number passed to this function
> is the _mapped_ interrupt number. The result in assertion failures for various
> emulations.
> 
> Examples (I don't know if there are others):
> 
> - ppc4xx_pci_map_irq() maps the interrupt number to "slot - 1". Obviously
>   that isn't a good thing to do for slot 0, and indeed results in an
>   assertion as soon as slot 0 is initialized (presumably that is the root
>   bridge). Changing the mapping to "slot" doesn't help because valid slots
>   are 0..4, and only four interrupts are allocated.
> - pci_bonito_map_irq() changes the mapping all over the place. Whatever
>   it does, it returns numbers starting with 32 for slots 5..12. With
>   a total number of 32 interrupts, this again results in an assertion
>   failure.
> 
> ppc4xx_pci_map_irq() is definitely buggy. I just don't know what the
> correct mapping should be. slot  & 3, maybe ?
> 
> I don't really have a good solution for pci_bonito_map_irq(). It may not
> matter much - I have not been able to boot fuloong_2e since qemu v4.0,
> and afaics that is the only platform using it. Maybe it is just completely
> broken ?

FWIW bisecting Fuloong2E starts failing here:

4ea98d317eb442c738f898f16cfdd47a18b7ca49 is the first bad commit
commit 4ea98d317eb442c738f898f16cfdd47a18b7ca49
Author: BALATON Zoltan 
Date:   Fri Jan 25 14:52:12 2019 -0500

ide/via: Implement and use native PCI IDE mode

This device only implemented ISA compatibility mode and native PCI IDE
mode was missing but no clients actually need ISA mode but to the
contrary, they usually want to switch to and use device in native
PCI IDE mode. Therefore implement native PCI mode and switch default
to that.

Signed-off-by: BALATON Zoltan 
Message-id:
c323f08c59b9931310c5d92503d370f77ce3a557.1548160772.git.bala...@eik.bme.hu
Signed-off-by: John Snow 

 hw/ide/via.c | 52 ++--
 1 file changed, 38 insertions(+), 14 deletions(-)



Re: scripts/gdb: issues when loading modules after lx-symbols

2020-12-23 Thread Stefano Garzarella
On Mon, Oct 5, 2020 at 3:03 PM Stefano Garzarella  wrote:
> On Mon, Oct 05, 2020 at 01:48:35PM +0200, Jan Kiszka wrote:
> > On 05.10.20 13:05, Stefano Garzarella wrote:
> > > On Mon, Oct 05, 2020 at 11:45:41AM +0200, Jan Kiszka wrote:
> > >> On 05.10.20 11:29, Stefano Garzarella wrote:
> > >>> On Mon, Oct 05, 2020 at 10:33:30AM +0200, Jan Kiszka wrote:
> >  On 05.10.20 10:14, Stefano Garzarella wrote:
> > > On Sun, Oct 04, 2020 at 08:52:37PM +0200, Jan Kiszka wrote:
> > >> On 01.10.20 16:31, Stefano Garzarella wrote:
> > >>> Hi,
> > >>> I had some issues with gdb scripts and kernel modules in Linux 
> > >>> 5.9-rc7.
> > >>>
> > >>> If the modules are already loaded, and I do 'lx-symbols', all work 
> > >>> fine.
> > >>> But, if I load a kernel module after 'lx-symbols', I had this issue:
> > >>>
> > >>> [ 5093.393940] invalid opcode:  [#1] SMP PTI
> > >>> [ 5093.395134] CPU: 0 PID: 576 Comm: modprobe Not tainted 
> > >>> 5.9.0-rc7-ste-00010-gf0b671d9608d-dirty #2
> > >>> [ 5093.397566] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), 
> > >>> BIOS 1.13.0-2.fc32 04/01/2014
> > >>> [ 5093.400761] RIP: 0010:do_init_module+0x1/0x270
> > >>> [ 5093.402553] Code: ff ff e9 cf fe ff ff 0f 0b 49 c7 c4 f2 ff ff 
> > >>> ff e9 c1 fe ff ff e8 5f b2 65 00 66 66 2e 0f 1f 84 00 00 00 00 00 
> > >>> 0f 1f 40 00 cc <1f> 44 00 00 55 ba 10 00 00 00 be c0 0c 00 00 48 89 
> > >>> e5 41 56 41 55
> > >>> [ 5093.409505] RSP: 0018:c9563d18 EFLAGS: 00010246
> > >>> [ 5093.412056] RAX:  RBX: c010a0c0 RCX: 
> > >>> 4ee3
> > >>> [ 5093.414472] RDX: 4ee2 RSI: ea0001efe188 RDI: 
> > >>> c010a0c0
> > >>> [ 5093.416349] RBP: c9563e50 R08:  R09: 
> > >>> 0002
> > >>> [ 5093.418044] R10: 0096 R11: 08a4 R12: 
> > >>> 88807a0d1280
> > >>> [ 5093.424721] R13: c010a110 R14: 88807a0d1300 R15: 
> > >>> c9563e70
> > >>> [ 5093.427138] FS:  7f018f632740() 
> > >>> GS:88807dc0() knlGS:
> > >>> [ 5093.430037] CS:  0010 DS:  ES:  CR0: 80050033
> > >>> [ 5093.432279] CR2: 55fbe282b239 CR3: 7922a006 CR4: 
> > >>> 00170ef0
> > >>> [ 5093.435096] DR0:  DR1:  DR2: 
> > >>> 
> > >>> [ 5093.436765] DR3:  DR6: fffe0ff0 DR7: 
> > >>> 0400
> > >>> [ 5093.439689] Call Trace:
> > >>> [ 5093.440954]  ? load_module+0x24b6/0x27d0
> > >>> [ 5093.443212]  ? __kernel_read+0xd6/0x150
> > >>> [ 5093.445140]  __do_sys_finit_module+0xd3/0xf0
> > >>> [ 5093.446877]  __x64_sys_finit_module+0x1a/0x20
> > >>> [ 5093.449098]  do_syscall_64+0x38/0x50
> > >>> [ 5093.450877]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> > >>> [ 5093.456153] RIP: 0033:0x7f018f75c43d
> > >>> [ 5093.457728] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 
> > >>> 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 
> > >>> 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 2b 6a 0c 00 f7 
> > >>> d8 64 89 01 48
> > >>> [ 5093.466349] RSP: 002b:7ffd7f080368 EFLAGS: 0246 
> > >>> ORIG_RAX: 0139
> > >>> [ 5093.470613] RAX: ffda RBX: 557e5c96f9c0 RCX: 
> > >>> 7f018f75c43d
> > >>> [ 5093.474747] RDX:  RSI: 557e5c964288 RDI: 
> > >>> 0003
> > >>> [ 5093.478049] RBP: 0004 R08:  R09: 
> > >>> 
> > >>> [ 5093.481298] R10: 0003 R11: 0246 R12: 
> > >>> 
> > >>> [ 5093.483725] R13: 557e5c964288 R14: 557e5c96f950 R15: 
> > >>> 557e5c9775c0
> > >>> [ 5093.485778] Modules linked in: virtio_vdpa(+) vdpa sunrpc 
> > >>> kvm_intel kvm irqbypass virtio_blk virtio_rng rng_core [last 
> > >>> unloaded: virtio_vdpa]
> > >>> [ 5093.488695] ---[ end trace 23712ecebc11f53c ]---
> > >>>
> > >>> Guest kernel: Linux 5.9-rc7
> > >>> gdb: GNU gdb (GDB) Fedora 9.1-6.fc32
> > >>> I tried with QEMU 4.2.1 and the latest master branch: same issue.
> > >>>
> > >>>
> > >>> I did some digging, and skipping the gdb 'add-symbol-file' command 
> > >>> in symbol.py
> > >>> avoid the issue, but of course I don't have the symbols loaded:
> > >>>
> > >>> diff --git a/scripts/gdb/linux/symbols.py 
> > >>> b/scripts/gdb/linux/symbols.py
> > >>> index 1be9763cf8bb..eadfaa4d4907 100644
> > >>> --- a/scripts/gdb/linux/symbols.py
> > >>> +++ b/scripts/gdb/linux/symbols.py
> > >>> @@ -129,7 +129,7 @@ lx-symbols command."""
> > >>>  filename=module_file,
> > >>>   

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread BALATON Zoltan via

On Wed, 23 Dec 2020, Mark Cave-Ayland wrote:

On 22/12/2020 22:23, BALATON Zoltan via wrote:
I've just remembered that for sam460ex we had this commit: 484ab3dffadc 
(sam460ex: Fix PCI interrupts with multiple devices) that changed that 
mapping for that machine so I guess you got the exception with the bamboo 
board then. I'm not sure though that similar fix is applicable fot that or 
even that this fix is correct for sam460ex but appears to work so far.


FWIW you might want to review this commit: as Peter noticed it is possible to 
lose interrupts here since if one PCI interrupt is already asserted and then 
another comes along, the second PCI interrupt will unintentionally clear the 
first which could cause problems.


Yes, thanks for reminding. I think this was also raised back then but for 
some reason we thought this should not be an issue in this case but I'll 
give it a try and see if using an or-gate would be better. The only 
possible IRQ related problem I know about is choppy sound with an emulated 
PCI sound card but that may be because some other audio related problem as 
well.


Regards,
BALATON Zoltan

You probably want to keep the 4 separate PCI interrupts but feed them into an 
OR IRQ, the output of which gets fed into the UIC. Have a look at 
https://lists.gnu.org/archive/html/qemu-devel/2020-12/msg05503.html for the 
sun4m variant of this based upon Peter's original example.



ATB,

Mark.






Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread BALATON Zoltan via

On Tue, 22 Dec 2020, Guenter Roeck wrote:

On 12/22/20 2:57 PM, BALATON Zoltan wrote:

[ ... ]


I've already forgot about the details but we have analysed it quite throughly 
back when the via ide changes were made. Here are some random pointers to 
threads that could have some info:
This was the final solution that was merged as the simplest that worked for all 
cases we've tried to fix:
https://lists.nongnu.org/archive/html/qemu-devel/2020-03/msg03977.html


This set of patches is in v5.2, yet I can still not instantiate an IDE drive, 
at least
not with "-drive file=,if=ide". Is there some other means to 
instantiate
an ide drive with the fuloong2e emulation ?

For reference, here is my qemu command line:

qemu-system-mips64el -M fulong2e \
   -kernel vmlinux -no-reboot -m 256 \
   -snapshot -drive file=rootfs.mipsel.ext3,format=raw,if=ide \
   -vga none \
   --append "root=/dev/sda console=ttyS0" \
   -nographic -serial stdio -monitor none


This is what worked the last time we've tried:

https://lists.nongnu.org/archive/html/qemu-devel/2020-03/msg04086.html

and this was my understanding of the issues with this VIA IDE function of 
these integrated southbridge/superio chips and Linux's approach to them 
that may be relevant to debug this:


https://lists.nongnu.org/archive/html/qemu-devel/2020-03/msg00019.html

We've found that pegasos2 PPC board uses this "half-native" mode where 
IRQs are using ISA IRQs but not sure what the fuloong2e has. Linux did not 
seem to care as long as there's no mismatch between config bits and IRQ 
routing. Although we've also found some comments in Linux may be 
misleading:


https://lists.nongnu.org/archive/html/qemu-devel/2020-03/msg02349.html

For the command line I never know which of these work for which machines 
so I just avoid using -drive if=... If the machine has 4 IDE ports then 
-hda -hdb -cdrom usually works, otherwise the most verbose form should 
always work which is:


-drive if=none,id=cd,file=some.iso,format=raw \
-device ide-cd,drive=cd,bus=ide.1

and similar for HD image with ide-hd and bus=ide.0 or wherever you want to 
connect it.


Regards,
BALATON Zoltan



Re: [PATCH v5 2/2] hw/block: m25p80: Implement AAI-WP command support for SST flashes

2020-12-23 Thread Francisco Iglesias
On [2020 Dec 23] Wed 10:00:25, Bin Meng wrote:
> From: Xuzhou Cheng 
> 
> Auto Address Increment (AAI) Word-Program is a special command of
> SST flashes. AAI-WP allows multiple bytes of data to be programmed
> without re-issuing the next sequential address location.
> 
> Signed-off-by: Xuzhou Cheng 
> Signed-off-by: Bin Meng 

Reviewed-by: Francisco Iglesias 

> 
> ---
> 
> Changes in v5:
> - remove the guest error logging when address wrap is detected in AAI
> - change to return s->aai_enable in m25p80_aai_enable_needed()
> 
> Changes in v4:
> - simplify is_valid_aai_cmd()
> - use a subsection for s->aai_enable vm state
> 
> Changes in v3:
> - initialize aai_enable to false in reset_memory()
> 
> Changes in v2:
> - add aai_enable into the vmstate
> - validate AAI command before decoding a new command
> - log guest errors during AAI_WP command handling
> - report AAI status in the status register
> - abort AAI programming when address is wrapped
> - make sure AAI programming starts from the even address
> 
>  hw/block/m25p80.c | 73 
> +++
>  1 file changed, 73 insertions(+)
> 
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 29598b4..c64852f 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -359,6 +359,7 @@ typedef enum {
>  QPP_4 = 0x34,
>  RDID_90 = 0x90,
>  RDID_AB = 0xab,
> +AAI_WP = 0xad,
>  
>  ERASE_4K = 0x20,
>  ERASE4_4K = 0x21,
> @@ -455,6 +456,7 @@ struct Flash {
>  bool four_bytes_address_mode;
>  bool reset_enable;
>  bool quad_enable;
> +bool aai_enable;
>  uint8_t ear;
>  
>  int64_t dirty_page;
> @@ -670,6 +672,11 @@ static void complete_collecting_data(Flash *s)
>  case PP4_4:
>  s->state = STATE_PAGE_PROGRAM;
>  break;
> +case AAI_WP:
> +/* AAI programming starts from the even address */
> +s->cur_addr &= ~BIT(0);
> +s->state = STATE_PAGE_PROGRAM;
> +break;
>  case READ:
>  case READ4:
>  case FAST_READ:
> @@ -768,6 +775,7 @@ static void reset_memory(Flash *s)
>  s->write_enable = false;
>  s->reset_enable = false;
>  s->quad_enable = false;
> +s->aai_enable = false;
>  
>  switch (get_man(s)) {
>  case MAN_NUMONYX:
> @@ -973,6 +981,11 @@ static void decode_qio_read_cmd(Flash *s)
>  s->state = STATE_COLLECTING_DATA;
>  }
>  
> +static bool is_valid_aai_cmd(uint32_t cmd)
> +{
> +return cmd == AAI_WP || cmd == WRDI || cmd == RDSR;
> +}
> +
>  static void decode_new_cmd(Flash *s, uint32_t value)
>  {
>  int i;
> @@ -984,6 +997,11 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>  s->reset_enable = false;
>  }
>  
> +if (get_man(s) == MAN_SST && s->aai_enable && !is_valid_aai_cmd(value)) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "M25P80: Invalid cmd within AAI programming sequence");
> +}
> +
>  switch (value) {
>  
>  case ERASE_4K:
> @@ -1103,6 +1121,9 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>  
>  case WRDI:
>  s->write_enable = false;
> +if (get_man(s) == MAN_SST) {
> +s->aai_enable = false;
> +}
>  break;
>  case WREN:
>  s->write_enable = true;
> @@ -1113,6 +1134,10 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>  if (get_man(s) == MAN_MACRONIX) {
>  s->data[0] |= (!!s->quad_enable) << 6;
>  }
> +if (get_man(s) == MAN_SST) {
> +s->data[0] |= (!!s->aai_enable) << 6;
> +}
> +
>  s->pos = 0;
>  s->len = 1;
>  s->data_read_loop = true;
> @@ -1260,6 +1285,24 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>  case RSTQIO:
>  s->quad_enable = false;
>  break;
> +case AAI_WP:
> +if (get_man(s) == MAN_SST) {
> +if (s->write_enable) {
> +if (s->aai_enable) {
> +s->state = STATE_PAGE_PROGRAM;
> +} else {
> +s->aai_enable = true;
> +s->needed_bytes = get_addr_length(s);
> +s->state = STATE_COLLECTING_DATA;
> +}
> +} else {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "M25P80: AAI_WP with write protect\n");
> +}
> +} else {
> +qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", 
> value);
> +}
> +break;
>  default:
>  s->pos = 0;
>  s->len = 1;
> @@ -1305,6 +1348,17 @@ static uint32_t m25p80_transfer8(SSIPeripheral *ss, 
> uint32_t tx)
>  trace_m25p80_page_program(s, s->cur_addr, (uint8_t)tx);
>  flash_write8(s, s->cur_addr, (uint8_t)tx);
>  s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
> +
> +if (get_man(s) == MAN_SST && s->aai_enable && s->cur_addr == 0) {
> +/*
> + * There is no wrap 

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread BALATON Zoltan via

On Wed, 23 Dec 2020, Mark Cave-Ayland wrote:

On 22/12/2020 21:23, Guenter Roeck wrote:

(Added jiaxun.y...@flygoat.com as CC)


Are you sure? It does not show up on cc list for me so unless the list ate 
it you might have forgotten to copy the address there. Done now just in 
case, sorry if this resulted in double post.


Regards,
BALATON Zoltan


I don't really have a good solution for pci_bonito_map_irq(). It may not
matter much - I have not been able to boot fuloong_2e since qemu v4.0,
and afaics that is the only platform using it. Maybe it is just 
completely

broken ?


It looks like you want this patchset posted last week: 
https://patchew.org/QEMU/20201216022513.89451-1-jiaxun.y...@flygoat.com/ 
(specifically: 
https://patchew.org/QEMU/20201216022513.89451-1-jiaxun.y...@flygoat.com/20201216022513.89451-4-jiaxun.y...@flygoat.com/). 
Zoltan was working on the VIA southbridge wiring at the start of the year 
and provided me a test case that would boot Linux on the fulong2e machine, 
so at that point in time it wasn't completely broken.


Those patches don't help for my tests. Problem is that I try to boot from 
ide drive.


qemu-system-mips64el -M fulong2e \
 -kernel vmlinux -no-reboot -m 256 -snapshot \
 -drive file=rootfs.mipsel.ext3,format=raw,if=ide \
 -vga none -nographic \
 --append "root=/dev/sda console=ttyS0"
 -serial stdio -monitor none

This works just fine with qemu v3.1. With qemu v5.2 (after applying the
fuloong patch series), I get:

VFS: Cannot open root device "sda" or unknown-block(0,0): error -6

This used to work up to qemu v3.1. Since qemu v4.0, there has been a 
variety
of failures. Common denominator is that the ide drive is no longer 
recognized,

presumably due to related changes in the via and/or pci code between v3.1
and v4.0.

Difference in log messages:

v3.1:

pci :00:05.1: [Firmware Bug]: reg 0x10: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x14: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x18: invalid BAR (can't size)
pci :00:05.1: reg 0x1c: [mem 0x10370-0x1037f 64bit]
...
pata_via :00:05.1: BMDMA: BAR4 is zero, falling back to PIO
ata1: PATA max PIO4 cmd 0x1f0 ctl 0x3f6 irq 14
ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15
ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
...



v5.2:

pci :00:05.1: reg 0x10: [io  0x-0x0007]
pci :00:05.1: reg 0x14: [io  0x-0x0003]
pci :00:05.1: reg 0x18: [io  0x-0x0007]
pci :00:05.1: reg 0x1c: [io  0x-0x0003]
pci :00:05.1: reg 0x20: [io  0x-0x000f]
pci :00:05.1: BAR 4: assigned [io  0x4440-0x444f]
...
ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x4440 irq 14
ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x4448 irq 15
[and nothing else]

Guenter


Jiaxun: Guenter is reporting that even with your latest series at 
https://lists.gnu.org/archive/html/qemu-devel/2020-12/msg04293.html he is 
unable to boot from an IDE drive. Your cover letter suggests that it should 
be possible to boot the Debian installer: can you provide any insight here?



ATB,

Mark.






Re: [PATCH] ppc: Fix build with --without-default-devices

2020-12-23 Thread Greg Kurz
On Wed, 23 Dec 2020 09:55:58 +0100
Paolo Bonzini  wrote:

> On 23/12/20 09:10, Greg Kurz wrote:
> > Linking of the qemu-system-ppc64 fails on a POWER9 host when
> > --without-default-devices is passed to configure:
> > 
> > $ ./configure --without-default-devices \
> >--target-list=ppc64-softmmu && make
> > 
> > ...
> > 
> > libqemu-ppc64-softmmu.fa.p/hw_ppc_e500.c.o: In function 
> > `ppce500_init_mpic_kvm':
> > /home/greg/Work/qemu/qemu-ppc/build/../hw/ppc/e500.c:777: undefined 
> > reference to `kvm_openpic_connect_vcpu'
> > libqemu-ppc64-softmmu.fa.p/hw_ppc_spapr_irq.c.o: In function 
> > `spapr_irq_check':
> > /home/greg/Work/qemu/qemu-ppc/build/../hw/ppc/spapr_irq.c:189: undefined 
> > reference to `xics_kvm_has_broken_disconnect'
> > libqemu-ppc64-softmmu.fa.p/hw_intc_spapr_xive.c.o: In function 
> > `spapr_xive_post_load':
> > /home/greg/Work/qemu/qemu-ppc/build/../hw/intc/spapr_xive.c:530: undefined 
> > reference to `kvmppc_xive_post_load'
> > 
> > ... and tons of other symbols belonging to the KVM backend of the
> > openpic, XICS and XIVE interrupt controllers.
> > 
> > It turns out that OPENPIC_KVM, XICS_KVM and XIVE_KVM are marked
> > to depend on KVM but this has no effect when minikconf runs in
> > allnoconfig mode. The correct way to express that some configuration
> > A requires some other configuration B to be true is "A select B".
> > 
> > Have OPENPIC, XICS and XIVE to select their KVM counterpart if KVM
> > is set. While here, fix POWERNV to select XIVE and XICS, just like
> > PSERIES, and drop the now useless XIVE related config clauses from
> > hw/ppc/Kconfig.
> > 
> > This went unnoticed so far because CI doesn't test the build with
> > --without-default-devices and KVM enabled on a POWER host.
> > 
> > Signed-off-by: Greg Kurz 
> 
> It is also possible to remove the *_KVM symbols and just use
> 
>  when: ['CONFIG_KVM', 'CONFIG_OPENPIC']
>  when: ['CONFIG_XICS', 'CONFIG_OPENPIC']
>  when: ['CONFIG_XIVE', 'CONFIG_OPENPIC']
> 

Good idea. I'll go for that. And it seems more fixing is need
around --without-default-devices so I'll need to repost anyway,

Thanks for the suggestion !

> in the meson.build files.  Which one is preferrable depends on personal 
> taste, and I do not myself lean in one direction or the other---I 
> mention it just in case _you_ find that one preferrable.
> 
> Reviewed-by: Paolo Bonzini 
> 
> Thanks!
> 
> Paolo
> 
> > ---
> >   hw/intc/Kconfig |   18 +-
> >   hw/ppc/Kconfig  |   17 ++---
> >   2 files changed, 15 insertions(+), 20 deletions(-)
> > 
> > diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
> > index 468d548ca771..0a5c080c4f5c 100644
> > --- a/hw/intc/Kconfig
> > +++ b/hw/intc/Kconfig
> > @@ -19,6 +19,7 @@ config ARM_GIC
> >   config OPENPIC
> >   bool
> >   select MSI_NONBROKEN
> > +select OPENPIC_KVM if KVM
> >   
> >   config APIC
> >   bool
> > @@ -32,21 +33,28 @@ config ARM_GIC_KVM
> >   
> >   config OPENPIC_KVM
> >   bool
> > -default y
> > -depends on OPENPIC && KVM
> >   
> >   config XICS
> >   bool
> > -depends on POWERNV || PSERIES
> > +select XICS_KVM if KVM
> >   
> >   config XICS_SPAPR
> >   bool
> >   select XICS
> >   
> > +config XIVE
> > +bool
> > +select XIVE_KVM if KVM
> > +
> > +config XIVE_SPAPR
> > +bool
> > +select XIVE
> > +
> >   config XICS_KVM
> >   bool
> > -default y
> > -depends on XICS && KVM
> > +
> > +config XIVE_KVM
> > +bool
> >   
> >   config ALLWINNER_A10_PIC
> >   bool
> > diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
> > index 982d55f5875c..037d9332e994 100644
> > --- a/hw/ppc/Kconfig
> > +++ b/hw/ppc/Kconfig
> > @@ -31,6 +31,8 @@ config POWERNV
> >   select FDT_PPC
> >   select PCI_EXPRESS
> >   select MSI_NONBROKEN
> > +select XIVE
> > +select XICS
> >   
> >   config PPC405
> >   bool
> > @@ -129,21 +131,6 @@ config VIRTEX
> >   select XILINX_ETHLITE
> >   select FDT_PPC
> >   
> > -config XIVE
> > -bool
> > -depends on POWERNV || PSERIES
> > -
> > -config XIVE_SPAPR
> > -bool
> > -default y
> > -depends on PSERIES
> > -select XIVE
> > -
> > -config XIVE_KVM
> > -bool
> > -default y
> > -depends on XIVE_SPAPR && KVM
> > -
> >   # Only used by 64-bit targets
> >   config FW_CFG_PPC
> >   bool
> > 
> > 
> 




Re: Various spelling fixes

2020-12-23 Thread Stefan Weil

Am 23.12.20 um 11:58 schrieb Michael Tokarev:


An assorted set of spelling fixes in various places.

Signed-off-by: Michael Tokarev 

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 90e63b83674..2b096552719 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -840 +840 @@ int NMD::Disassemble(const uint16 * data, std::string & dis,
-dis = "ASE attribute missmatch";
+dis = "ASE attribute mismatch";
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index b5118acd3fd..155733646d8 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -124 +124 @@ npcm7xx_rng_write(uint64_t offset, uint64_t value, unsigned size) 
"offset: 0x%04
-stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, Line: 
%d; Level: %d"
+stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interrupt: GPIO: %d, Line: 
%d; Level: %d"
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
index 38d328587e3..27b0c37943b 100644
--- a/hw/net/allwinner-sun8i-emac.c
+++ b/hw/net/allwinner-sun8i-emac.c
@@ -582 +582 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr 
offset,
-case REG_INT_EN:/* Interupt Enable */
+case REG_INT_EN:/* Interrupt Enable */
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index 67ebb16c4d5..8fbadaf03d7 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -227 +227 @@ static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, unsigned 
int cmd_len,
-qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknow command %02X\n", 
cmd[2]);
+qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknown command %02X\n", 
cmd[2]);
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index 2d566f7db10..5c76bed77aa 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -304 +304 @@ static void *event_thread(void *arg)
-"ERROR: wrong reader: quiting event_thread\n");
+"ERROR: wrong reader: quitting event_thread\n");
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index f8c64c8b95b..1cf2816772c 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1129 +1129 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed 
*ed)
-/* An error occured so we have to clear the interrupt counter. See
+/* An error occurred so we have to clear the interrupt counter. See
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 614ccc2bcb6..87fa7b40419 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -903 +903 @@ check_dev_state:
-/* An error is occured. */
+/* An error is occurred. */



"has occurred" or better simply "occurred"



diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index 08c869ab0af..7901ab276ce 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -136 +136 @@ struct SubchDev {
-uint16_t migrated_schid; /* used for missmatch detection */
+uint16_t migrated_schid; /* used for mismatch detection */
diff --git a/qemu-options.hx b/qemu-options.hx
index 104632ea343..fd5e384d98e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -148 +148 @@ SRST
-there will be one thread per vCPU therefor taking advantage of
+there will be one thread per vCPU therefore taking advantage of
@@ -2406 +2406 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
-"use 'poll-us=n' to speciy the maximum number of microseconds 
that could be\n"
+"use 'poll-us=n' to specify the maximum number of microseconds 
that could be\n"
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5a8c96072e4..9e24e2c4822 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6916 +6916 @@ static void x86_cpu_get_crash_info_qom(Object *obj, Visitor 
*v,
-error_setg(errp, "No crash occured");
+error_setg(errp, "No crash occurred");
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 233e46bb70b..43a63c6e25d 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1159 +1159 @@ static int nested_state_post_load(void *opaque, int 
version_id)
-error_report("Recieved unsupported nested state size: "
+error_report("Received unsupported nested state size: "
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 202498deb51..c9728651f00 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -120 +120 @@ static const char *m68k_exception_name(int index)
-return "Unitialized Interruot";
+return "Uninitialized Interruot";



s/Interruot/interrupt/



diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6a0264fc6b1..d39d560cf47 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -478 +478 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
-qemu_log("vector verison is not specified, "
+qemu_log("vector version is not 

Re: [PATCH v15 08/20] multi-process: add qio channel read function

2020-12-23 Thread Marc-André Lureau
Hi

On Wed, Dec 23, 2020 at 10:17 AM  wrote:

> From: Elena Ufimtseva 
>
> Adds qio_channel_readv_full_all() to read both data and FDs.
> Refactors existing code to use this function.
>
> Signed-off-by: Elena Ufimtseva 
> Signed-off-by: John G Johnson 
> Signed-off-by: Jagannathan Raman 
> ---
>  include/io/channel.h | 25 +
>  io/channel.c | 85 +++-
>  2 files changed, 85 insertions(+), 25 deletions(-)
>
> diff --git a/include/io/channel.h b/include/io/channel.h
> index 2378567d4b..429ece9a05 100644
> --- a/include/io/channel.h
> +++ b/include/io/channel.h
> @@ -774,6 +774,31 @@ void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
>  IOHandler *io_write,
>  void *opaque);
>
> +/**
> + * qio_channel_readv_full_all:
> + * @ioc: the channel object
> + * @iov: the array of memory regions to read data to
> + * @niov: the length of the @iov array
> + * @fds: an array of file handles to read
> + * @nfds: number of file handles in @fds
> + * @errp: pointer to a NULL-initialized error object
> + *
> + *
> + * Behaves like qio_channel_readv_full but will attempt
> + * to read all data specified (file handles and memory regions).
> + * The function will wait for all requested data
> + * to be read, yielding from the current coroutine
> + * if required.
> + *
> + * Returns: 0 if all bytes were read, or -1 on error
>

It may also returns -ECANCEL. I am not sure it's a good idea.

+ */
> +
> +int qio_channel_readv_full_all(QIOChannel *ioc,
> +const struct iovec *iov,
> +size_t niov,
> +int **fds, size_t *nfds,
> +Error **errp);
> +
>  /**
>   * qio_channel_writev_full_all:
>   * @ioc: the channel object
> diff --git a/io/channel.c b/io/channel.c
> index bde1f6d0f4..5edaea1fac 100644
> --- a/io/channel.c
> +++ b/io/channel.c
> @@ -91,11 +91,49 @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
>const struct iovec *iov,
>size_t niov,
>Error **errp)
> +{
> +int ret = qio_channel_readv_full_all(ioc, iov, niov, NULL, NULL,
> errp);
> +
>
+if (ret == -ECANCELED) {
>

 No io/ functions use -errno return values so far.

Maybe the simplest is to use the same return values as read_all_eof:
 * Returns: 1 if all bytes were read, 0 if end-of-file occurs
 *  without data, or -1 on error

+error_prepend(errp,
> +  "Unexpected end-of-file before all bytes were read:
> ");
> +ret = -1;
> +}
> +
> +return ret;
> +}
> +
> +int qio_channel_readv_all(QIOChannel *ioc,
> +  const struct iovec *iov,
> +  size_t niov,
> +  Error **errp)
> +{
> +int ret = qio_channel_readv_all_eof(ioc, iov, niov, errp);
>
+
>

It looks like it would make more sense to call readv_full_all directly
instead now.

+if (ret == 0) {
> +error_setg(errp,
> +   "Unexpected end-of-file before all bytes were read");
> +return -1;
> +}
> +if (ret == 1) {
> +return 0;
> +}
> +
> +return ret;
> +}
> +
> +int qio_channel_readv_full_all(QIOChannel *ioc,
> +const struct iovec *iov,
> +size_t niov,
> +int **fds, size_t *nfds,
> +Error **errp)
>  {
>  int ret = -1;
>  struct iovec *local_iov = g_new(struct iovec, niov);
>  struct iovec *local_iov_head = local_iov;
>  unsigned int nlocal_iov = niov;
> +int **local_fds = fds;
> +size_t *local_nfds = nfds;
>  bool partial = false;
>
>  nlocal_iov = iov_copy(local_iov, nlocal_iov,
> @@ -104,7 +142,8 @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
>
>  while (nlocal_iov > 0) {
>  ssize_t len;
> -len = qio_channel_readv(ioc, local_iov, nlocal_iov, errp);
> +len = qio_channel_readv_full(ioc, local_iov, nlocal_iov,
> local_fds,
> + local_nfds, errp);
>  if (len == QIO_CHANNEL_ERR_BLOCK) {
>  if (qemu_in_coroutine()) {
>  qio_channel_yield(ioc, G_IO_IN);
> @@ -112,20 +151,33 @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
>  qio_channel_wait(ioc, G_IO_IN);
>  }
>  continue;
> -} else if (len < 0) {
> -goto cleanup;
> -} else if (len == 0) {
> -if (partial) {
> -error_setg(errp,
> -   "Unexpected end-of-file before all bytes were
> read");
> +}
> +
> +if (len <= 0) {
> +size_t fd_idx = nfds ? *nfds : 0;
> +if (partial && (len == 0)) {
> +ret = -ECANCELED;
>

Re: [PATCH] multi-process: Acceptance test for multiprocess QEMU

2020-12-23 Thread Marc-André Lureau
Hi

On Wed, Dec 23, 2020 at 10:45 AM  wrote:

> From: Jagannathan Raman 
>
> Runs the Avocado acceptance test to check if a
> remote lsi53c895a device gets identified by the guest.
>
> Signed-off-by: Elena Ufimtseva 
> Signed-off-by: John G Johnson 
> Signed-off-by: Jagannathan Raman 
> ---
>  tests/acceptance/multiprocess.py | 104 +++
>  1 file changed, 104 insertions(+)
>  create mode 100644 tests/acceptance/multiprocess.py
>
> diff --git a/tests/acceptance/multiprocess.py
> b/tests/acceptance/multiprocess.py
> new file mode 100644
> index 00..d10b4d2c05
> --- /dev/null
> +++ b/tests/acceptance/multiprocess.py
> @@ -0,0 +1,104 @@
> +# Test for multiprocess qemu
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2 or
> +# later.  See the COPYING file in the top-level directory.
> +
> +
> +from avocado_qemu import Test
> +from avocado_qemu import wait_for_console_pattern
> +from avocado_qemu import exec_command_and_wait_for_pattern
> +
> +from qemu.accel import kvm_available
> +
> +import os
> +import socket
> +
> +ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available"
> +KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
> +
> +class Multiprocess(Test):
> +"""
> +:avocado: tags=multiprocess
> +"""
> +KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
> +
> +def wait_for_console_pattern(self, success_message, vm=None):
> +wait_for_console_pattern(self, success_message,
> + failure_message='Kernel panic - not
> syncing',
> + vm=vm)
> +
> +def do_test(self, kernel_url, initrd_url, kernel_command_line,
> +machine_type):
> +if not kvm_available(self.arch, self.qemu_bin):
> +self.cancel(KVM_NOT_AVAILABLE)
> +
> +# Create socketpair to connect proxy and remote processes
> +proxy_sock, remote_sock = socket.socketpair(socket.AF_UNIX,
> +socket.SOCK_STREAM)
> +os.set_inheritable(proxy_sock.fileno(), True)
> +os.set_inheritable(remote_sock.fileno(), True)
> +
> +kernel_path = self.fetch_asset(kernel_url)
> +initrd_path = self.fetch_asset(initrd_url)
> +
> +# Create remote process
> +remote_vm = self.get_vm()
> +remote_vm.add_args('-machine', 'x-remote')
> +remote_vm.add_args('-nodefaults')
> +remote_vm.add_args('-device', 'lsi53c895a,id=lsi1')
> +remote_vm.add_args('-object', 'x-remote-object,id=robj1,'
> +   'devid=lsi1,fd='+str(remote_sock.fileno()))
> +remote_vm.launch()
> +
> +# Create proxy process
> +self.vm.set_console()
> +self.vm.add_args('-machine', machine_type)
> +self.vm.add_args('-accel', 'kvm')
> +self.vm.add_args('-cpu', 'host')
> +self.vm.add_args("-object",
> + "memory-backend-memfd,id=sysmem-file,size=2G")
> +self.vm.add_args("--numa", "node,memdev=sysmem-file")
> +self.vm.add_args("-m", "2048")
> +self.vm.add_args('-kernel', kernel_path,
> + '-initrd', initrd_path,
> + '-append', kernel_command_line)
> +self.vm.add_args('-device',
> + 'x-pci-proxy-dev,'
> + 'id=lsi1,fd='+str(proxy_sock.fileno()))
> +self.vm.launch()
> +self.wait_for_console_pattern("as init process")
> +exec_command_and_wait_for_pattern(self, "mount -t sysfs sysfs
> /sys",
> +  '', '')
> +exec_command_and_wait_for_pattern(self,
> +  "cat
> /sys/bus/pci/devices/*/uevent",
> +  "PCI_ID=1000:0012", '')
> +
> +def test_multiprocess_x86_64(self):
> +"""
> +:avocado: tags=arch:x86_64
> +"""
> +kernel_url = ('
> https://archives.fedoraproject.org/pub/archive/fedora'
> +  '/linux/releases/31/Everything/x86_64/os/images'
> +  '/pxeboot/vmlinuz')
> +initrd_url = ('
> https://archives.fedoraproject.org/pub/archive/fedora'
> +  '/linux/releases/31/Everything/x86_64/os/images'
> +  '/pxeboot/initrd.img')
> +kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
> +   'console=ttyS0 rdinit=/bin/bash')
> +machine = 'pc'
> +self.do_test(kernel_url, initrd_url, kernel_command_line, machine)
> +
> +def test_multiprocess_aarch64(self):
> +"""
> +:avocado: tags=arch:aarch64
> +"""
> +kernel_url = ('
> https://archives.fedoraproject.org/pub/archive/fedora'
> +  '/linux/releases/31/Everything/aarch64/os/images'
> +  '/pxeboot/vmlinuz')
> +initrd_url = ('
> 

Various spelling fixes

2020-12-23 Thread Michael Tokarev
An assorted set of spelling fixes in various places.

Signed-off-by: Michael Tokarev 

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 90e63b83674..2b096552719 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -840 +840 @@ int NMD::Disassemble(const uint16 * data, std::string & dis,
-dis = "ASE attribute missmatch";
+dis = "ASE attribute mismatch";
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index b5118acd3fd..155733646d8 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -124 +124 @@ npcm7xx_rng_write(uint64_t offset, uint64_t value, unsigned 
size) "offset: 0x%04
-stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, 
Line: %d; Level: %d"
+stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interrupt: GPIO: %d, 
Line: %d; Level: %d"
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
index 38d328587e3..27b0c37943b 100644
--- a/hw/net/allwinner-sun8i-emac.c
+++ b/hw/net/allwinner-sun8i-emac.c
@@ -582 +582 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr 
offset,
-case REG_INT_EN:/* Interupt Enable */
+case REG_INT_EN:/* Interrupt Enable */
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index 67ebb16c4d5..8fbadaf03d7 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -227 +227 @@ static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, unsigned 
int cmd_len,
-qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknow command %02X\n", 
cmd[2]);
+qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknown command %02X\n", 
cmd[2]);
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index 2d566f7db10..5c76bed77aa 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -304 +304 @@ static void *event_thread(void *arg)
-"ERROR: wrong reader: quiting event_thread\n");
+"ERROR: wrong reader: quitting event_thread\n");
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index f8c64c8b95b..1cf2816772c 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1129 +1129 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed 
*ed)
-/* An error occured so we have to clear the interrupt counter. See
+/* An error occurred so we have to clear the interrupt counter. See
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 614ccc2bcb6..87fa7b40419 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -903 +903 @@ check_dev_state:
-/* An error is occured. */
+/* An error is occurred. */
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index 08c869ab0af..7901ab276ce 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -136 +136 @@ struct SubchDev {
-uint16_t migrated_schid; /* used for missmatch detection */
+uint16_t migrated_schid; /* used for mismatch detection */
diff --git a/qemu-options.hx b/qemu-options.hx
index 104632ea343..fd5e384d98e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -148 +148 @@ SRST
-there will be one thread per vCPU therefor taking advantage of
+there will be one thread per vCPU therefore taking advantage of
@@ -2406 +2406 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
-"use 'poll-us=n' to speciy the maximum number of 
microseconds that could be\n"
+"use 'poll-us=n' to specify the maximum number of 
microseconds that could be\n"
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5a8c96072e4..9e24e2c4822 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6916 +6916 @@ static void x86_cpu_get_crash_info_qom(Object *obj, Visitor 
*v,
-error_setg(errp, "No crash occured");
+error_setg(errp, "No crash occurred");
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 233e46bb70b..43a63c6e25d 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1159 +1159 @@ static int nested_state_post_load(void *opaque, int 
version_id)
-error_report("Recieved unsupported nested state size: "
+error_report("Received unsupported nested state size: "
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 202498deb51..c9728651f00 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -120 +120 @@ static const char *m68k_exception_name(int index)
-return "Unitialized Interruot";
+return "Uninitialized Interruot";
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6a0264fc6b1..d39d560cf47 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -478 +478 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
-qemu_log("vector verison is not specified, "
+qemu_log("vector version is not specified, "



Re: [PATCH v2] acpi: Permit OEM ID and OEM table ID fields to be changed

2020-12-23 Thread Igor Mammedov
On Tue, 22 Dec 2020 13:33:53 +0200
Marian Posteuca  wrote:

> Qemu's ACPI table generation sets the fields OEM ID and OEM table ID
> to "BOCHS " and "BXPC" where "" is replaced by the ACPI
> table name.
> 
> Some games like Red Dead Redemption 2 seem to check the ACPI OEM ID
> and OEM table ID for the strings "BOCHS" and "BXPC" and if they are
> found, the game crashes(this may be an intentional detection
> mechanism to prevent playing the game in a virtualized environment).
> 
> This patch allows you to override these default values.
> 
> The feature can be used in this manner:
>   qemu -machine oem_id=ABCDEF,oem_table_id=EFGH
> 
> The oem_id string must be exactly 6 bytes in size, and the
> oem_table_id string must be exactly 4 bytes in size. If either of
> these parameters is not set, the current default values will be
> used for the one missing.
> 
> This does not affect the -acpitable option (for user-defined ACPI
> tables), which has precedence over -machine option.
> 
> Signed-off-by: Marian Posteuca 
> ---
>  hw/acpi/hmat.h  |  3 +-
>  hw/i386/acpi-common.h   |  3 +-
>  include/hw/acpi/aml-build.h | 12 +++--
>  include/hw/acpi/pci.h   |  3 +-
>  include/hw/acpi/vmgenid.h   |  2 +-
>  include/hw/i386/pc.h|  5 +-
>  include/hw/mem/nvdimm.h |  3 +-
>  hw/acpi/aml-build.c | 28 +++
>  hw/acpi/ghes.c  |  2 +-
>  hw/acpi/hmat.c  |  6 ++-
>  hw/acpi/nvdimm.c| 19 +---
>  hw/acpi/pci.c   |  6 ++-
>  hw/acpi/vmgenid.c   |  4 +-
>  hw/arm/virt-acpi-build.c| 23 -
>  hw/i386/acpi-build.c| 93 ++---
>  hw/i386/acpi-common.c   |  5 +-
>  hw/i386/acpi-microvm.c  |  6 +--
>  hw/i386/pc.c| 37 +++
>  18 files changed, 182 insertions(+), 78 deletions(-)
> 
> diff --git a/hw/acpi/hmat.h b/hw/acpi/hmat.h
> index e9031cac01..b57f0e7e80 100644
> --- a/hw/acpi/hmat.h
> +++ b/hw/acpi/hmat.h
> @@ -37,6 +37,7 @@
>   */
>  #define HMAT_PROXIMITY_INITIATOR_VALID  0x1
>  
> -void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState 
> *numa_state);
> +void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState 
> *numa_state,
> +const char *oem_id, const char *oem_table_id);
>  
>  #endif
> diff --git a/hw/i386/acpi-common.h b/hw/i386/acpi-common.h
> index c30e461f18..b12cd73ea5 100644
> --- a/hw/i386/acpi-common.h
> +++ b/hw/i386/acpi-common.h
> @@ -9,6 +9,7 @@
>  #define ACPI_BUILD_IOAPIC_ID 0x0
>  
>  void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
> - X86MachineState *x86ms, AcpiDeviceIf *adev);
> + X86MachineState *x86ms, AcpiDeviceIf *adev,
> + const char *oem_id, const char *oem_table_id);
>  
>  #endif
> diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
> index e727bea1bc..3f88669d6e 100644
> --- a/include/hw/acpi/aml-build.h
> +++ b/include/hw/acpi/aml-build.h
> @@ -416,7 +416,7 @@ void build_append_int_noprefix(GArray *table, uint64_t 
> value, int size);
>  void
>  build_header(BIOSLinker *linker, GArray *table_data,
>   AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
> - const char *oem_id, const char *oem_table_id);
> + const char *oem_id, const char *oem_table_id, bool use_sig_oem);
>  void *acpi_data_push(GArray *table_data, unsigned size);
>  unsigned acpi_data_len(GArray *table);
>  void acpi_add_table(GArray *table_offsets, GArray *table_data);
> @@ -426,7 +426,7 @@ void
>  build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data);
>  void
>  build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
> -   const char *oem_id, const char *oem_table_id);
> +   const char *oem_id, const char *oem_table_id, bool use_sig_oem);
>  void
>  build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
> const char *oem_id, const char *oem_table_id);
> @@ -457,10 +457,12 @@ Aml *build_crs(PCIHostState *host, CrsRangeSet 
> *range_set);
>  void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
> uint64_t len, int node, MemoryAffinityFlags flags);
>  
> -void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms);
> +void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms,
> +const char *oem_id, const char *oem_table_id);
>  
>  void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
> -const char *oem_id, const char *oem_table_id);
> +const char *oem_id, const char *oem_table_id, bool 
> use_sig_oem);
>  
> -void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog);
> +void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
> +const char *oem_id, const char *oem_table_id);
>  #endif
> diff --git 

Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Mark Cave-Ayland

On 22/12/2020 22:23, BALATON Zoltan via wrote:

I've just remembered that for sam460ex we had this commit: 484ab3dffadc (sam460ex: 
Fix PCI interrupts with multiple devices) that changed that mapping for that machine 
so I guess you got the exception with the bamboo board then. I'm not sure though that 
similar fix is applicable fot that or even that this fix is correct for sam460ex but 
appears to work so far.


FWIW you might want to review this commit: as Peter noticed it is possible to lose 
interrupts here since if one PCI interrupt is already asserted and then another comes 
along, the second PCI interrupt will unintentionally clear the first which could 
cause problems.


You probably want to keep the 4 separate PCI interrupts but feed them into an OR IRQ, 
the output of which gets fed into the UIC. Have a look at 
https://lists.gnu.org/archive/html/qemu-devel/2020-12/msg05503.html for the sun4m 
variant of this based upon Peter's original example.



ATB,

Mark.



Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Mark Cave-Ayland

On 22/12/2020 21:23, Guenter Roeck wrote:

(Added jiaxun.y...@flygoat.com as CC)


I don't really have a good solution for pci_bonito_map_irq(). It may not
matter much - I have not been able to boot fuloong_2e since qemu v4.0,
and afaics that is the only platform using it. Maybe it is just completely
broken ?


It looks like you want this patchset posted last week: 
https://patchew.org/QEMU/20201216022513.89451-1-jiaxun.y...@flygoat.com/ 
(specifically: 
https://patchew.org/QEMU/20201216022513.89451-1-jiaxun.y...@flygoat.com/20201216022513.89451-4-jiaxun.y...@flygoat.com/).
 Zoltan was working on the VIA southbridge wiring at the start of the year and 
provided me a test case that would boot Linux on the fulong2e machine, so at 
that point in time it wasn't completely broken.


Those patches don't help for my tests. Problem is that I try to boot from ide 
drive.

qemu-system-mips64el -M fulong2e \
 -kernel vmlinux -no-reboot -m 256 -snapshot \
 -drive file=rootfs.mipsel.ext3,format=raw,if=ide \
 -vga none -nographic \
 --append "root=/dev/sda console=ttyS0"
 -serial stdio -monitor none

This works just fine with qemu v3.1. With qemu v5.2 (after applying the
fuloong patch series), I get:

VFS: Cannot open root device "sda" or unknown-block(0,0): error -6

This used to work up to qemu v3.1. Since qemu v4.0, there has been a variety
of failures. Common denominator is that the ide drive is no longer recognized,
presumably due to related changes in the via and/or pci code between v3.1
and v4.0.

Difference in log messages:

v3.1:

pci :00:05.1: [Firmware Bug]: reg 0x10: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x14: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x18: invalid BAR (can't size)
pci :00:05.1: reg 0x1c: [mem 0x10370-0x1037f 64bit]
...
pata_via :00:05.1: BMDMA: BAR4 is zero, falling back to PIO
ata1: PATA max PIO4 cmd 0x1f0 ctl 0x3f6 irq 14
ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15
ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
...



v5.2:

pci :00:05.1: reg 0x10: [io  0x-0x0007]
pci :00:05.1: reg 0x14: [io  0x-0x0003]
pci :00:05.1: reg 0x18: [io  0x-0x0007]
pci :00:05.1: reg 0x1c: [io  0x-0x0003]
pci :00:05.1: reg 0x20: [io  0x-0x000f]
pci :00:05.1: BAR 4: assigned [io  0x4440-0x444f]
...
ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x4440 irq 14
ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x4448 irq 15
[and nothing else]

Guenter


Jiaxun: Guenter is reporting that even with your latest series at 
https://lists.gnu.org/archive/html/qemu-devel/2020-12/msg04293.html he is unable to 
boot from an IDE drive. Your cover letter suggests that it should be possible to boot 
the Debian installer: can you provide any insight here?



ATB,

Mark.



Re: Problems with irq mapping in qemu v5.2

2020-12-23 Thread Mark Cave-Ayland

On 22/12/2020 21:23, Guenter Roeck wrote:


ppc4xx_pci_map_irq() is definitely buggy. I just don't know what the
correct mapping should be. slot  & 3, maybe ?


Yeah that doesn't look right. Certainly both the Mac PPC machines use ((pci_dev->devfn 
>> 3)) & 3) plus the interrupt pin so I think you're right that this is missing an 
& 3 here. Does adding this allow your image to boot?



Actually, it does not help. This does:

@@ -247,7 +247,7 @@ static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int 
irq_num)

  trace_ppc4xx_pci_map_irq(pci_dev->devfn, irq_num, slot);

-return slot - 1;
+return slot ? slot - 1 : slot;
  }

but I have no idea why.


That's interesting. I had a look at bamboo.dts in Linux and the interrupt-map 
property suggests there are 4 fixed PCI slots available 1 to 4, so it shouldn't be 
possible for slot 0 to generate an IRQ as nothing can be plugged there.


Can you share your reproducer? Feel free to send me links off-list if you 
prefer.


I don't really have a good solution for pci_bonito_map_irq(). It may not
matter much - I have not been able to boot fuloong_2e since qemu v4.0,
and afaics that is the only platform using it. Maybe it is just completely
broken ?


It looks like you want this patchset posted last week: 
https://patchew.org/QEMU/20201216022513.89451-1-jiaxun.y...@flygoat.com/ 
(specifically: 
https://patchew.org/QEMU/20201216022513.89451-1-jiaxun.y...@flygoat.com/20201216022513.89451-4-jiaxun.y...@flygoat.com/).
 Zoltan was working on the VIA southbridge wiring at the start of the year and 
provided me a test case that would boot Linux on the fulong2e machine, so at 
that point in time it wasn't completely broken.


Those patches don't help for my tests. Problem is that I try to boot from ide 
drive.

qemu-system-mips64el -M fulong2e \
 -kernel vmlinux -no-reboot -m 256 -snapshot \
 -drive file=rootfs.mipsel.ext3,format=raw,if=ide \
 -vga none -nographic \
 --append "root=/dev/sda console=ttyS0"
 -serial stdio -monitor none

This works just fine with qemu v3.1. With qemu v5.2 (after applying the
fuloong patch series), I get:

VFS: Cannot open root device "sda" or unknown-block(0,0): error -6

This used to work up to qemu v3.1. Since qemu v4.0, there has been a variety
of failures. Common denominator is that the ide drive is no longer recognized,
presumably due to related changes in the via and/or pci code between v3.1
and v4.0.

Difference in log messages:

v3.1:

pci :00:05.1: [Firmware Bug]: reg 0x10: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x14: invalid BAR (can't size)
pci :00:05.1: [Firmware Bug]: reg 0x18: invalid BAR (can't size)
pci :00:05.1: reg 0x1c: [mem 0x10370-0x1037f 64bit]
...
pata_via :00:05.1: BMDMA: BAR4 is zero, falling back to PIO
ata1: PATA max PIO4 cmd 0x1f0 ctl 0x3f6 irq 14
ata2: PATA max PIO4 cmd 0x170 ctl 0x376 irq 15
ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
...



v5.2:

pci :00:05.1: reg 0x10: [io  0x-0x0007]
pci :00:05.1: reg 0x14: [io  0x-0x0003]
pci :00:05.1: reg 0x18: [io  0x-0x0007]
pci :00:05.1: reg 0x1c: [io  0x-0x0003]
pci :00:05.1: reg 0x20: [io  0x-0x000f]
pci :00:05.1: BAR 4: assigned [io  0x4440-0x444f]
...
ata1: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0x4440 irq 14
ata2: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0x4448 irq 15
[and nothing else]


Again, can you share the files that you are using here? I think it's worth adding 
Jiaxun Yang to this thread since the original cover letter at 
https://lists.gnu.org/archive/html/qemu-devel/2020-12/msg04293.html states that this 
latest series allows the Debian installer to boot.



ATB,

Mark.



Re: [PATCH 4/4] fuzz: delay IO until they can't trigger the crash

2020-12-23 Thread Qiuhao Li
On Tue, 2020-12-22 at 13:30 -0500, Alexander Bulekov wrote:
> On 201222 1922, Qiuhao Li wrote:
> > On Mon, 2020-12-21 at 16:17 -0500, Alexander Bulekov wrote:
> > > On 201220 0256, Qiuhao Li wrote:
> > > > Since programmers usually trigger an IO just before they need
> > > > it.
> > > > Try to
> > > > delay some IO instructions may help us better understanding the
> > > > timing
> > > > context when debug.
> > > >
> > > > Tested with Bug 1908062. Refined vs. Original result:
> > > >
> > > > outl 0xcf8 0x881coutl 0xcf8 0x0
> > > > outb 0xcfc 0xc3| outl 0xcf8 0x881c
> > > > outl 0xcf8 0x8804  | outb 0xcfc 0xc3
> > > > outl 0xcfc 0x1006  | outl 0xcf8 0x8804
> > > > write 0xc31028 0x1 0x5a| outl 0xcfc 0x1006
> > > > write 0xc31024 0x2 0x10| write 0xc31028 0x1 0x5a
> > > > write 0xc3101c 0x1 0x01| writel 0xc3100c 0x2a6f6c63
> > > > write 0xc33002 0x1 0x0 v write 0xc31024 0x2 0x10
> > > > write 0x5c 0x1 0x10  write 0xc3101c 0x1 0x01
> > > > writel 0xc3100c 0x2a6f6c63   write 0xc31018 0x1 0x80
> > > > write 0xc31018 0x1 0x80  write 0x5c 0x1 0x10
> > > > outl 0xcf8 0x0   write 0xc33002 0x1 0x0
> > > >
> > >
> > > In this example, I can remove the outl 0xcf8 0x0, and I still see
> > > the
> > > crash, so maybe the 1st step in the minimizer is failing
> > > somewhere..
> >
> > I think it might because of our one-time scan and remove strategy,
> > which is not suitable for timing dependent instructions.
> >
> > For example, instruction A will indicate an address where the
> > config
> > chunk locates, and instruction B will make the configuration
> > active. If
> > we have the following instruction sequence:
> >
> > ...
> > A1
> > B1
> > A2
> > B2
> > ...
> >
> > A2 and B2 are the actual instructions that trigger the bug.
> >
> > If we scan from top to bottom, after we remove A1, the behavior of
> > B1
> > might be unknowable, including not to crash the program. But we
> > will
> > successfully remove B1 later cause A2 and B2 will crash the process
> > anyway:
> >
> > ...
> > A1
> > A2
> > B2
> > ...
> >
> > Now one more trimming will remove A1.
> >
> > As for the example I gave, the instructions before the delaying
> > minimizer are like this:
> >
> > outl 0xcf8 0x881c
> > outb 0xcfc 0xc3
> > outl 0xcf8 0x0<--- The A instruction, didn't be
> > removed
> > (outl 0xcfc 0x0)  <--- The B instruction, removed
> > outl 0xcf8 0x8804
> > outl 0xcfc 0x1006
> > write 0xc31024 0x2 0x10
> > write 0xc31028 0x1 0x5a
> > write 0xc3101c 0x1 0x01
> > writel 0xc3100c 0x2a6f6c63
> > write 0xc31018 0x1 0x80
> > write 0x5c 0x1 0x10
> > write 0xc33002 0x1 0x0
> >
> > If we run the remove minimizer again, The A instruction outl 0xcf8
> > 0x0
> > will be removed.
> >
> > Since we only remove instructions, this iterative algorithm is
> > converging. Maybe we can keep removing the trace until the
> > len(newtrace) become unchanged.
> >
>
> I found a bunch of work related to this "test-case minimization".
> There
> are algorithms such as "ddmin" that try to tackle this. There might
> be
> some interesting ideas there.

Thanks, I will have a look.

> I think in the perfect case, we would need to be able to remove A and
> B
> at the same time. You described the situation where B1 might lead to
> a
> bad state without A1, but there is also the possibility that A1 might
> leave bad state around, without B1. And both of these might be true
> at
> the same time :) Probably not something we encounter very often,
> though.

You are right, and even there can be three instructions which must be removed 
together ;) But for now, how about we just add a if(len(newtrace) == old_len) 
loop  around remove minimizer? No harm.

Do you think this kind of dependence will exist in bits of the write/out 
commands? How about adding if(num_bits(data) == old_num) loop around the 
setting zero minimizer?

> > > Is the Refined one better? To me the original one read as:
> > > "Do a bunch of PCI configuration to map an MMIO BAR, then
> > > interact
> > > with
> > > the MMIO range and trigger some DMA activity". I also know
> > > exactly
> > > the
> > > line that will trigger the DMA activity and access 0x5c. With the
> > > refined one, I'm not so sure. Which line now causes the DMA read
> > > from
> > > 0x5c? writel 0xc3100c? write 0xc31018?
> > > Is there another example where this type of reordering makes the
> > > result
> > > easier to read?
> > >
> > > > Signed-off-by: Qiuhao Li 
> > > > ---
> > > >  scripts/oss-fuzz/minimize_qtest_trace.py | 21
> > > > +
> > > >  1 file changed, 21 insertions(+)
> > > >
> > > > diff --git a/scripts/oss-fuzz/minimize_qtest_trace.py
> > > > b/scripts/oss-fuzz/minimize_qtest_trace.py
> > > > index f3e88064c4..da7aa73b3c 100755
> > > > --- a/scripts/oss-fuzz/minimize_qtest_trace.py

[PATCH v3 5/8] acpi/gpex: Append pxb devs in ascending order

2020-12-23 Thread Jiahui Cen
The overlap check of IO resource window would fail when Linux kernel
registers an IO resource [b, c) earlier than another resource [a, b).
Though this incorrect check could be fixed by [1], it would be better to
append pxb devs into DSDT table in ascending order.

[1]: https://lore.kernel.org/lkml/20201218062335.5320-1-cenjia...@huawei.com/

Signed-off-by: Jiahui Cen 
---
 hw/pci-host/gpex-acpi.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index 4bf1e94309..95a7a0f12b 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -141,7 +141,7 @@ static void acpi_dsdt_add_pci_osc(Aml *dev)
 void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 {
 int nr_pcie_buses = cfg->ecam.size / PCIE_MMCFG_SIZE_MIN;
-Aml *method, *crs, *dev, *rbuf;
+Aml *method, *crs, *dev, *rbuf, *pxb_devs[nr_pcie_buses];
 PCIBus *bus = cfg->bus;
 CrsRangeSet crs_range_set;
 CrsRangeEntry *entry;
@@ -149,6 +149,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 
 /* start to construct the tables for pxb */
 crs_range_set_init(_range_set);
+memset(pxb_devs, 0, sizeof(pxb_devs));
 if (bus) {
 QLIST_FOREACH(bus, >child, sibling) {
 uint8_t bus_num = pci_bus_num(bus);
@@ -190,7 +191,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 
 acpi_dsdt_add_pci_osc(dev);
 
-aml_append(scope, dev);
+pxb_devs[bus_num] = dev;
 }
 }
 
@@ -278,5 +279,11 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 aml_append(dev, dev_res0);
 aml_append(scope, dev);
 
+for (i = 0; i < ARRAY_SIZE(pxb_devs); i++) {
+if (pxb_devs[i]) {
+aml_append(scope, pxb_devs[i]);
+}
+}
+
 crs_range_set_free(_range_set);
 }
-- 
2.29.2




[PATCH v3 8/8] acpi: Update addr_trans and _DSM in expected files

2020-12-23 Thread Jiahui Cen
Addr_trans in _CRS is changed and a new _DSM #5 method is added.
Also the expected file for pxb for ARM virt does not match the source code.

Update expected DSDT files accordingly, and re-enable their testing.

Full diff of changed files disassembly:

diff -ru /tmp/old/tests/data/acpi/microvm/DSDT.pcie.dsl 
/tmp/new/tests/data/acpi/microvm/DSDT.pcie.dsl
--- /tmp/old/tests/data/acpi/microvm/DSDT.pcie.dsl  2020-12-23 
15:49:57.161081285 +0800
+++ /tmp/new/tests/data/acpi/microvm/DSDT.pcie.dsl  2020-12-23 
15:55:11.837769953 +0800
@@ -9,9 +9,9 @@
  *
  * Original Table Header:
  * Signature"DSDT"
- * Length   0x0BCF (3023)
+ * Length   0x0BD7 (3031)
  * Revision 0x02
- * Checksum 0x29
+ * Checksum 0x99
  * OEM ID   "BOCHS "
  * OEM Table ID "BXPCDSDT"
  * OEM Revision 0x0001 (1)
@@ -1302,9 +1302,14 @@
 {
 Return (Buffer (One)
 {
- 0x01 
// .
+ 0x21 
// !
 })
 }
+
+If ((Arg2 == 0x05))
+{
+Return (Zero)
+}
 }

 Return (Buffer (One)
diff -ru /tmp/old/tests/data/acpi/virt/DSDT.dsl 
/tmp/new/tests/data/acpi/virt/DSDT.dsl
--- /tmp/old/tests/data/acpi/virt/DSDT.dsl  2020-12-23 15:49:57.421095066 
+0800
+++ /tmp/new/tests/data/acpi/virt/DSDT.dsl  2020-12-23 15:55:12.267792771 
+0800
@@ -9,9 +9,9 @@
  *
  * Original Table Header:
  * Signature"DSDT"
- * Length   0x144C (5196)
+ * Length   0x1454 (5204)
  * Revision 0x02
- * Checksum 0xF0
+ * Checksum 0x60
  * OEM ID   "BOCHS "
  * OEM Table ID "BXPCDSDT"
  * OEM Revision 0x0001 (1)
@@ -1838,9 +1838,14 @@
 {
 Return (Buffer (One)
 {
- 0x01 
// .
+ 0x21 
// !
 })
 }
+
+If ((Arg2 == 0x05))
+{
+Return (Zero)
+}
 }

 Return (Buffer (One)
diff -ru /tmp/old/tests/data/acpi/virt/DSDT.memhp.dsl 
/tmp/new/tests/data/acpi/virt/DSDT.memhp.dsl
--- /tmp/old/tests/data/acpi/virt/DSDT.memhp.dsl2020-12-23 
15:49:57.421095066 +0800
+++ /tmp/new/tests/data/acpi/virt/DSDT.memhp.dsl2020-12-23 
15:55:12.277793302 +0800
@@ -9,9 +9,9 @@
  *
  * Original Table Header:
  * Signature"DSDT"
- * Length   0x199D (6557)
+ * Length   0x19A5 (6565)
  * Revision 0x02
- * Checksum 0x11
+ * Checksum 0x90
  * OEM ID   "BOCHS "
  * OEM Table ID "BXPCDSDT"
  * OEM Revision 0x0001 (1)
@@ -1840,9 +1840,14 @@
 {
 Return (Buffer (One)
 {
- 0x01 
// .
+ 0x21 
// !
 })
 }
+
+If ((Arg2 == 0x05))
+{
+Return (Zero)
+}
 }

 Return (Buffer (One)
diff -ru /tmp/old/tests/data/acpi/virt/DSDT.numamem.dsl 
/tmp/new/tests/data/acpi/virt/DSDT.numamem.dsl
--- /tmp/old/tests/data/acpi/virt/DSDT.numamem.dsl  2020-12-23 
15:49:57.431095596 +0800
+++ /tmp/new/tests/data/acpi/virt/DSDT.numamem.dsl  2020-12-23 
15:55:12.287793832 +0800
@@ -9,9 +9,9 @@
  *
  * Original Table Header:
  * Signature"DSDT"
- * Length   0x144C (5196)
+ * Length   0x1454 (5204)
  * Revision 0x02
- * Checksum 0xF0
+ * Checksum 0x60
  * OEM ID   "BOCHS "
  * OEM Table ID "BXPCDSDT"
  * OEM Revision 0x0001 (1)
@@ -1838,9 +1838,14 @@
 {
 Return (Buffer (One)
 {
- 0x01 
// .
+ 0x21 
// !
 })
 }
+
+If ((Arg2 == 0x05))
+{
+Return (Zero)
+}
 }

 Return (Buffer (One)
diff -ru /tmp/old/tests/data/acpi/virt/DSDT.pxb.dsl 

[PATCH v3 7/8] acpi: Enable pxb unit-test for ARM virt machine

2020-12-23 Thread Jiahui Cen
No matter whether the pxb is enabled or not, the CONFIG_PXB macro in test
would keep undefined. And since pxb is now enabled for ARM Virt machine
by default, let's enable pxb unit-test by removing the CONFIG_PXB.

Signed-off-by: Jiahui Cen 
---
 tests/qtest/bios-tables-test.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 4e026f90d0..669202fc95 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1196,7 +1196,6 @@ static void test_acpi_virt_tcg_numamem(void)
 
 }
 
-#ifdef CONFIG_PXB
 static void test_acpi_virt_tcg_pxb(void)
 {
 test_data data = {
@@ -1228,7 +1227,6 @@ static void test_acpi_virt_tcg_pxb(void)
 
 free_test_data();
 }
-#endif
 
 static void test_acpi_tcg_acpi_hmat(const char *machine)
 {
@@ -1342,9 +1340,7 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/virt", test_acpi_virt_tcg);
 qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
 qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
-#ifdef CONFIG_PXB
 qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
-#endif
 }
 ret = g_test_run();
 boot_sector_cleanup(disk);
-- 
2.29.2




[PATCH v3 0/8] acpi: Some fixes for pxb support for ARM virt machine

2020-12-23 Thread Jiahui Cen
This patch series adds some fixes for ARM virt machine pxb support.
1. Pass addr offset for IO, MMIO and bus number when builing crs, because
the addr_trans is needed to describe an addr resource. [1]
2. Inform guest os not to ignore the resource map generated by firmware as
the x86 default way. [2]
3. Reorder the root bridges [3] and exclude resources of extra root bridges
from main root bridge's _CRS.
4. Enable pxb for ARM virt machine by default.
5. Update expected DSDT files with the above changes and enable the pxb
unit-test.

v2->v3:
* Reorder the root bridges.
* Exclude resources of extra root bridges from main root bridge's _CRS.

v1->v2:
* Update expected DSDT files.
* Quote PCI Firmware spec as comments.

[1]: 
https://lore.kernel.org/qemu-devel/20201217132747.4744-1-cenjia...@huawei.com/
[2]: 
https://lore.kernel.org/qemu-devel/20201217132926.4812-1-cenjia...@huawei.com/
[3]: https://lore.kernel.org/lkml/20201218062335.5320-1-cenjia...@huawei.com/

Jiahui Cen (8):
  acpi: Allow DSDT acpi table changes
  acpi: Add addr offset in build_crs
  acpi/gpex: Inform os to keep firmware resource map
  acpi/gpex: Exclude pxb's resources from PCI0
  acpi/gpex: Append pxb devs in ascending order
  Kconfig: Enable PXB for ARM_VIRT by default
  acpi: Enable pxb unit-test for ARM virt machine
  acpi: Update addr_trans and _DSM in expected files

 hw/acpi/aml-build.c   |  18 ++--
 hw/i386/acpi-build.c  |   3 +-
 hw/pci-bridge/Kconfig |   2 +-
 hw/pci-host/gpex-acpi.c   |  96 ++--
 include/hw/acpi/aml-build.h   |   4 +-
 tests/data/acpi/microvm/DSDT.pcie | Bin 3023 -> 3031 bytes
 tests/data/acpi/virt/DSDT | Bin 5196 -> 5204 bytes
 tests/data/acpi/virt/DSDT.memhp   | Bin 6557 -> 6565 bytes
 tests/data/acpi/virt/DSDT.numamem | Bin 5196 -> 5204 bytes
 tests/data/acpi/virt/DSDT.pxb | Bin 7802 -> 7689 bytes
 tests/qtest/bios-tables-test.c|   4 -
 11 files changed, 86 insertions(+), 41 deletions(-)

-- 
2.29.2




[PATCH v3 1/8] acpi: Allow DSDT acpi table changes

2020-12-23 Thread Jiahui Cen
Signed-off-by: Jiahui Cen 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..42418e58e7 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,6 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/microvm/DSDT.pcie",
+"tests/data/acpi/virt/DSDT",
+"tests/data/acpi/virt/DSDT.memhp",
+"tests/data/acpi/virt/DSDT.numamem",
+"tests/data/acpi/virt/DSDT.pxb",
-- 
2.29.2




[PATCH v3 2/8] acpi: Add addr offset in build_crs

2020-12-23 Thread Jiahui Cen
AML needs Address Translation offset to describe how a bridge translates
addresses accross the bridge when using an address descriptor, and
especially on ARM, the translation offset of pio resource is usually
non zero.

Therefore, it's necessary to pass offset for pio, mmio32, mmio64 and bus
number into build_crs.

Signed-off-by: Jiahui Cen 
---
 hw/acpi/aml-build.c | 18 ++
 hw/i386/acpi-build.c|  3 ++-
 hw/pci-host/gpex-acpi.c |  3 ++-
 include/hw/acpi/aml-build.h |  4 +++-
 4 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index f976aa667b..7b6ebb0cc8 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -2076,7 +2076,9 @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, 
GArray *tcpalog)
  tpm2_ptr, "TPM2", table_data->len - tpm2_start, 4, NULL, 
NULL);
 }
 
-Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
+Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set, uint32_t io_offset,
+   uint32_t mmio32_offset, uint64_t mmio64_offset,
+   uint16_t bus_nr_offset)
 {
 Aml *crs = aml_resource_template();
 CrsRangeSet temp_range_set;
@@ -2189,10 +2191,10 @@ Aml *build_crs(PCIHostState *host, CrsRangeSet 
*range_set)
 for (i = 0; i < temp_range_set.io_ranges->len; i++) {
 entry = g_ptr_array_index(temp_range_set.io_ranges, i);
 aml_append(crs,
-   aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,
-   AML_POS_DECODE, AML_ENTIRE_RANGE,
-   0, entry->base, entry->limit, 0,
-   entry->limit - entry->base + 1));
+   aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED,
+AML_POS_DECODE, AML_ENTIRE_RANGE,
+0, entry->base, entry->limit, io_offset,
+entry->limit - entry->base + 1));
 crs_range_insert(range_set->io_ranges, entry->base, entry->limit);
 }
 
@@ -2205,7 +2207,7 @@ Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,
 AML_MAX_FIXED, AML_NON_CACHEABLE,
 AML_READ_WRITE,
-0, entry->base, entry->limit, 0,
+0, entry->base, entry->limit, 
mmio32_offset,
 entry->limit - entry->base + 1));
 crs_range_insert(range_set->mem_ranges, entry->base, entry->limit);
 }
@@ -2217,7 +2219,7 @@ Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED,
 AML_MAX_FIXED, AML_NON_CACHEABLE,
 AML_READ_WRITE,
-0, entry->base, entry->limit, 0,
+0, entry->base, entry->limit, 
mmio64_offset,
 entry->limit - entry->base + 1));
 crs_range_insert(range_set->mem_64bit_ranges,
  entry->base, entry->limit);
@@ -2230,7 +2232,7 @@ Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
 0,
 pci_bus_num(host->bus),
 max_bus,
-0,
+bus_nr_offset,
 max_bus - pci_bus_num(host->bus) + 1));
 
 return crs;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f18b71dea9..f56d699c7f 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1360,7 +1360,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 }
 
 aml_append(dev, build_prt(false));
-crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent), _range_set);
+crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent), _range_set,
+0, 0, 0, 0);
 aml_append(dev, aml_name_decl("_CRS", crs));
 aml_append(scope, dev);
 aml_append(dsdt, scope);
diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index 7f20ee1c98..11b3db8f71 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -168,7 +168,8 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
  * 1. The resources the pci-brige/pcie-root-port need.
  * 2. The resources the devices behind pxb need.
  */
-crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent), _range_set);
+crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent), _range_set,
+cfg->pio.base, 0, 0, 0);
 aml_append(dev, aml_name_decl("_CRS", crs));
 
 acpi_dsdt_add_pci_osc(dev);
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h

[PATCH v3 4/8] acpi/gpex: Exclude pxb's resources from PCI0

2020-12-23 Thread Jiahui Cen
Exclude the resources of extra root bridges from PCI0's _CRS. Otherwise,
the resource windows would overlap in guest, and the IO resource window
would fail to be registered.

Signed-off-by: Jiahui Cen 
---
 hw/pci-host/gpex-acpi.c | 64 +---
 1 file changed, 43 insertions(+), 21 deletions(-)

diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index c189306599..4bf1e94309 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -144,6 +144,8 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 Aml *method, *crs, *dev, *rbuf;
 PCIBus *bus = cfg->bus;
 CrsRangeSet crs_range_set;
+CrsRangeEntry *entry;
+int i;
 
 /* start to construct the tables for pxb */
 crs_range_set_init(_range_set);
@@ -191,7 +193,6 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 aml_append(scope, dev);
 }
 }
-crs_range_set_free(_range_set);
 
 /* tables for the main */
 dev = aml_device("%s", "PCI0");
@@ -209,36 +210,55 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig 
*cfg)
 aml_append(method, aml_return(aml_int(cfg->ecam.base)));
 aml_append(dev, method);
 
+/*
+ * At this point crs_range_set has all the ranges used by pci
+ * busses *other* than PCI0.  These ranges will be excluded from
+ * the PCI0._CRS.
+ */
 rbuf = aml_resource_template();
 aml_append(rbuf,
 aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
 0x, 0x, nr_pcie_buses - 1, 0x,
 nr_pcie_buses));
 if (cfg->mmio32.size) {
-aml_append(rbuf,
-   aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, 
AML_MAX_FIXED,
-AML_NON_CACHEABLE, AML_READ_WRITE, 0x,
-cfg->mmio32.base,
-cfg->mmio32.base + cfg->mmio32.size - 1,
-0x,
-cfg->mmio32.size));
+crs_replace_with_free_ranges(crs_range_set.mem_ranges,
+ cfg->mmio32.base,
+ cfg->mmio32.base + cfg->mmio32.size - 1);
+for (i = 0; i < crs_range_set.mem_ranges->len; i++) {
+entry = g_ptr_array_index(crs_range_set.mem_ranges, i);
+aml_append(rbuf,
+aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
+ AML_NON_CACHEABLE, AML_READ_WRITE, 0x,
+ entry->base, entry->limit,
+ 0x, entry->limit - entry->base + 1));
+}
 }
 if (cfg->pio.size) {
-aml_append(rbuf,
-   aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
-AML_ENTIRE_RANGE, 0x, 0x,
-cfg->pio.size - 1,
-cfg->pio.base,
-cfg->pio.size));
+crs_replace_with_free_ranges(crs_range_set.io_ranges,
+ 0x,
+ cfg->pio.size - 1);
+for (i = 0; i < crs_range_set.io_ranges->len; i++) {
+entry = g_ptr_array_index(crs_range_set.io_ranges, i);
+aml_append(rbuf,
+aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
+ AML_ENTIRE_RANGE, 0x, entry->base,
+ entry->limit, cfg->pio.base,
+ entry->limit - entry->base + 1));
+}
 }
 if (cfg->mmio64.size) {
-aml_append(rbuf,
-   aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, 
AML_MAX_FIXED,
-AML_NON_CACHEABLE, AML_READ_WRITE, 0x,
-cfg->mmio64.base,
-cfg->mmio64.base + cfg->mmio64.size - 1,
-0x,
-cfg->mmio64.size));
+crs_replace_with_free_ranges(crs_range_set.mem_64bit_ranges,
+ cfg->mmio64.base,
+ cfg->mmio64.base + cfg->mmio64.size - 1);
+for (i = 0; i < crs_range_set.mem_64bit_ranges->len; i++) {
+entry = g_ptr_array_index(crs_range_set.mem_64bit_ranges, i);
+aml_append(rbuf,
+aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
+ AML_NON_CACHEABLE, AML_READ_WRITE, 0x,
+ entry->base,
+ entry->limit, 0x,
+ entry->limit - entry->base + 1));
+}
 }
 aml_append(dev, aml_name_decl("_CRS", rbuf));
 
@@ -257,4 +277,6 @@ void acpi_dsdt_add_gpex(Aml *scope, 

[PATCH v3 3/8] acpi/gpex: Inform os to keep firmware resource map

2020-12-23 Thread Jiahui Cen
There may be some differences in pci resource assignment between guest os
and firmware.

Eg. A Bridge with Bus [d2]
-+-[:d2]---01.0-[d3]01.0

where [d2:01.00] is a pcie-pci-bridge with BAR0 (mem, 64-bit, non-pref) 
[size=256]
  [d3:01.00] is a PCI Device with BAR0 (mem, 64-bit, pref) [size=128K]
  BAR4 (mem, 64-bit, pref) [size=64M]

In EDK2, the Resource Map would be:
PciBus: Resource Map for Bridge [D2|01|00]
Type = PMem64; Base = 0x800400; Length = 0x410; 
Alignment = 0x3FF
   Base = 0x800400; Length = 0x400; Alignment = 0x3FF;  
Owner = PCI [D3|01|00:20]
   Base = 0x800800; Length = 0x2;   Alignment = 0x1;
Owner = PCI [D3|01|00:10]
Type =  Mem64; Base = 0x800810; Length = 0x100; Alignment = 
0xFFF
It would use 0x410 to calculate the root bus's PMem64 resource window.

While in Linux, kernel will use 0x1FF as the alignment to calculate
the PMem64 size, which would be 0x600. So kernel would try to
allocate 0x600 from the PMem64 resource window, but since the window
size is 0x410 as assigned by EDK2, the allocation would fail.

The diffences could result in resource assignment failure.

Using _DSM #5 method to inform guest os not to ignore the PCI configuration
that firmware has done at boot time could handle the differences.

Signed-off-by: Jiahui Cen 
---
 hw/pci-host/gpex-acpi.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index 11b3db8f71..c189306599 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -112,10 +112,24 @@ static void acpi_dsdt_add_pci_osc(Aml *dev)
 UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
 ifctx = aml_if(aml_equal(aml_arg(0), UUID));
 ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(0)));
-uint8_t byte_list[1] = {1};
-buf = aml_buffer(1, byte_list);
+uint8_t byte_list[] = {
+0x1 << 0 /* support for functions other than function 0 */ |
+0x1 << 5 /* support for function 5 */
+};
+buf = aml_buffer(ARRAY_SIZE(byte_list), byte_list);
 aml_append(ifctx1, aml_return(buf));
 aml_append(ifctx, ifctx1);
+
+/* PCI Firmware Specification 3.1
+ * 4.6.5. _DSM for Ignoring PCI Boot Configurations
+ */
+/* Arg2: Function Index: 5 */
+ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(5)));
+/* 0 - The operating system must not ignore the PCI configuration that
+ * firmware has done at boot time.
+ */
+aml_append(ifctx1, aml_return(aml_int(0)));
+aml_append(ifctx, ifctx1);
 aml_append(method, ifctx);
 
 byte_list[0] = 0;
-- 
2.29.2




[PATCH v3 6/8] Kconfig: Enable PXB for ARM_VIRT by default

2020-12-23 Thread Jiahui Cen
PXB is now supported on ARM, so let's enable it by default.

Signed-off-by: Jiahui Cen 
---
 hw/pci-bridge/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci-bridge/Kconfig b/hw/pci-bridge/Kconfig
index a51ec716f5..f8df4315ba 100644
--- a/hw/pci-bridge/Kconfig
+++ b/hw/pci-bridge/Kconfig
@@ -5,7 +5,7 @@ config PCIE_PORT
 
 config PXB
 bool
-default y if Q35
+default y if Q35 || ARM_VIRT
 
 config XIO3130
 bool
-- 
2.29.2




Re: [PATCH] ppc: Fix build with --without-default-devices

2020-12-23 Thread Paolo Bonzini

On 23/12/20 09:10, Greg Kurz wrote:

Linking of the qemu-system-ppc64 fails on a POWER9 host when
--without-default-devices is passed to configure:

$ ./configure --without-default-devices \
   --target-list=ppc64-softmmu && make

...

libqemu-ppc64-softmmu.fa.p/hw_ppc_e500.c.o: In function `ppce500_init_mpic_kvm':
/home/greg/Work/qemu/qemu-ppc/build/../hw/ppc/e500.c:777: undefined reference 
to `kvm_openpic_connect_vcpu'
libqemu-ppc64-softmmu.fa.p/hw_ppc_spapr_irq.c.o: In function `spapr_irq_check':
/home/greg/Work/qemu/qemu-ppc/build/../hw/ppc/spapr_irq.c:189: undefined 
reference to `xics_kvm_has_broken_disconnect'
libqemu-ppc64-softmmu.fa.p/hw_intc_spapr_xive.c.o: In function 
`spapr_xive_post_load':
/home/greg/Work/qemu/qemu-ppc/build/../hw/intc/spapr_xive.c:530: undefined 
reference to `kvmppc_xive_post_load'

... and tons of other symbols belonging to the KVM backend of the
openpic, XICS and XIVE interrupt controllers.

It turns out that OPENPIC_KVM, XICS_KVM and XIVE_KVM are marked
to depend on KVM but this has no effect when minikconf runs in
allnoconfig mode. The correct way to express that some configuration
A requires some other configuration B to be true is "A select B".

Have OPENPIC, XICS and XIVE to select their KVM counterpart if KVM
is set. While here, fix POWERNV to select XIVE and XICS, just like
PSERIES, and drop the now useless XIVE related config clauses from
hw/ppc/Kconfig.

This went unnoticed so far because CI doesn't test the build with
--without-default-devices and KVM enabled on a POWER host.

Signed-off-by: Greg Kurz 


It is also possible to remove the *_KVM symbols and just use

when: ['CONFIG_KVM', 'CONFIG_OPENPIC']
when: ['CONFIG_XICS', 'CONFIG_OPENPIC']
when: ['CONFIG_XIVE', 'CONFIG_OPENPIC']

in the meson.build files.  Which one is preferrable depends on personal 
taste, and I do not myself lean in one direction or the other---I 
mention it just in case _you_ find that one preferrable.


Reviewed-by: Paolo Bonzini 

Thanks!

Paolo


---
  hw/intc/Kconfig |   18 +-
  hw/ppc/Kconfig  |   17 ++---
  2 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 468d548ca771..0a5c080c4f5c 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -19,6 +19,7 @@ config ARM_GIC
  config OPENPIC
  bool
  select MSI_NONBROKEN
+select OPENPIC_KVM if KVM
  
  config APIC

  bool
@@ -32,21 +33,28 @@ config ARM_GIC_KVM
  
  config OPENPIC_KVM

  bool
-default y
-depends on OPENPIC && KVM
  
  config XICS

  bool
-depends on POWERNV || PSERIES
+select XICS_KVM if KVM
  
  config XICS_SPAPR

  bool
  select XICS
  
+config XIVE

+bool
+select XIVE_KVM if KVM
+
+config XIVE_SPAPR
+bool
+select XIVE
+
  config XICS_KVM
  bool
-default y
-depends on XICS && KVM
+
+config XIVE_KVM
+bool
  
  config ALLWINNER_A10_PIC

  bool
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 982d55f5875c..037d9332e994 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -31,6 +31,8 @@ config POWERNV
  select FDT_PPC
  select PCI_EXPRESS
  select MSI_NONBROKEN
+select XIVE
+select XICS
  
  config PPC405

  bool
@@ -129,21 +131,6 @@ config VIRTEX
  select XILINX_ETHLITE
  select FDT_PPC
  
-config XIVE

-bool
-depends on POWERNV || PSERIES
-
-config XIVE_SPAPR
-bool
-default y
-depends on PSERIES
-select XIVE
-
-config XIVE_KVM
-bool
-default y
-depends on XIVE_SPAPR && KVM
-
  # Only used by 64-bit targets
  config FW_CFG_PPC
  bool







Re: [PATCH] char-socket: disable reconnect timer in the sync connect

2020-12-23 Thread Marc-André Lureau
Hi

On Mon, Dec 21, 2020 at 6:06 PM Wang Xin  wrote:

> From: suruifeng 
>
> The qio_channel_socket_connect_sync maybe called twice if the
> openvswitchd restart during we attaching a vhost-user nic.
>
> -> call trace 1:
>   net_vhost_user_init
> tcp_chr_wait_connected //loop call sync connect until socekt connected
>   tcp_chr_connect_client_sync //return, but socekt state still
> disconnected
> qio_channel_socket_connect_sync //socket connect sucess
>   tcp_chr_new_client
> tcp_chr_connect
>   qemu_chr_be_event
> net_vhost_user_event //CHR_EVENT_OPENED
>   vhost_user_start
> tcp_chr_write  //Broken Pipe, as peer restart
>   tcp_chr_disconnect_locked //disconnect & reconnect
> timer create
>
> -> call trace 2:
>   socket_reconnect_timeout //timeout, and the peer restart just finished
> tcp_chr_connect_client_async //concurrent with
> tcp_chr_connect_client_sync
>

What do you mean by "concurrent with tcp_chr_connect_client_sync"? Are we
talking about threads? If not, could you provide the full backtrace?

   tcp_chr_connect_client_task
>   qio_channel_socket_connect_sync //try connect same socket

This patch disabled tcp reconnect timer when we try to connect in
> synchronous mode,
>
it seems to work.
>
> Signed-off-by: suruifeng 
> Signed-off-by: Wang Xin 
>
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index 213a4c8dd0..da1befca9e 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -80,6 +80,7 @@ struct SocketChardev {
>
>  bool is_websock;
>
> +bool async_reconnect_disable;
>  GSource *reconnect_timer;
>  int64_t reconnect_time;
>  bool connect_err_reported;
> @@ -506,7 +507,9 @@ static void tcp_chr_disconnect_locked(Chardev *chr)
>  if (emit_close) {
>  qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
>  }
> -if (s->reconnect_time && !s->reconnect_timer) {
> +if (s->reconnect_time &&
> +!s->reconnect_timer &&
> +!s->async_reconnect_disable) {
>  qemu_chr_socket_restart_timer(chr);
>  }
>  }
> @@ -954,15 +957,23 @@ static int tcp_chr_connect_client_sync(Chardev *chr,
> Error **errp)
>  {
>  SocketChardev *s = SOCKET_CHARDEV(chr);
>  QIOChannelSocket *sioc = qio_channel_socket_new();
> +
> +s->async_reconnect_disable = true;
>

Instead of having a new field, we could probably zero s->reconnect_timer
temporarily.

 tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
>  tcp_chr_set_client_ioc_name(chr, sioc);
>  if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
>  tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
>  object_unref(OBJECT(sioc));
> +s->async_reconnect_disable = false;
>  return -1;
>  }
>  tcp_chr_new_client(chr, sioc);
>  object_unref(OBJECT(sioc));
> +s->async_reconnect_disable = false;
> +
> +if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
> +return -1;
> +}
>

How is this related?

 return 0;
>  }
>
> --
> 2.26.0.windows.1
>
>


[PATCH] ppc: Fix build with --without-default-devices

2020-12-23 Thread Greg Kurz
Linking of the qemu-system-ppc64 fails on a POWER9 host when
--without-default-devices is passed to configure:

$ ./configure --without-default-devices \
  --target-list=ppc64-softmmu && make

...

libqemu-ppc64-softmmu.fa.p/hw_ppc_e500.c.o: In function `ppce500_init_mpic_kvm':
/home/greg/Work/qemu/qemu-ppc/build/../hw/ppc/e500.c:777: undefined reference 
to `kvm_openpic_connect_vcpu'
libqemu-ppc64-softmmu.fa.p/hw_ppc_spapr_irq.c.o: In function `spapr_irq_check':
/home/greg/Work/qemu/qemu-ppc/build/../hw/ppc/spapr_irq.c:189: undefined 
reference to `xics_kvm_has_broken_disconnect'
libqemu-ppc64-softmmu.fa.p/hw_intc_spapr_xive.c.o: In function 
`spapr_xive_post_load':
/home/greg/Work/qemu/qemu-ppc/build/../hw/intc/spapr_xive.c:530: undefined 
reference to `kvmppc_xive_post_load'

... and tons of other symbols belonging to the KVM backend of the
openpic, XICS and XIVE interrupt controllers.

It turns out that OPENPIC_KVM, XICS_KVM and XIVE_KVM are marked
to depend on KVM but this has no effect when minikconf runs in
allnoconfig mode. The correct way to express that some configuration
A requires some other configuration B to be true is "A select B".

Have OPENPIC, XICS and XIVE to select their KVM counterpart if KVM
is set. While here, fix POWERNV to select XIVE and XICS, just like
PSERIES, and drop the now useless XIVE related config clauses from
hw/ppc/Kconfig.

This went unnoticed so far because CI doesn't test the build with
--without-default-devices and KVM enabled on a POWER host.

Signed-off-by: Greg Kurz 
---
 hw/intc/Kconfig |   18 +-
 hw/ppc/Kconfig  |   17 ++---
 2 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 468d548ca771..0a5c080c4f5c 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -19,6 +19,7 @@ config ARM_GIC
 config OPENPIC
 bool
 select MSI_NONBROKEN
+select OPENPIC_KVM if KVM
 
 config APIC
 bool
@@ -32,21 +33,28 @@ config ARM_GIC_KVM
 
 config OPENPIC_KVM
 bool
-default y
-depends on OPENPIC && KVM
 
 config XICS
 bool
-depends on POWERNV || PSERIES
+select XICS_KVM if KVM
 
 config XICS_SPAPR
 bool
 select XICS
 
+config XIVE
+bool
+select XIVE_KVM if KVM
+
+config XIVE_SPAPR
+bool
+select XIVE
+
 config XICS_KVM
 bool
-default y
-depends on XICS && KVM
+
+config XIVE_KVM
+bool
 
 config ALLWINNER_A10_PIC
 bool
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 982d55f5875c..037d9332e994 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -31,6 +31,8 @@ config POWERNV
 select FDT_PPC
 select PCI_EXPRESS
 select MSI_NONBROKEN
+select XIVE
+select XICS
 
 config PPC405
 bool
@@ -129,21 +131,6 @@ config VIRTEX
 select XILINX_ETHLITE
 select FDT_PPC
 
-config XIVE
-bool
-depends on POWERNV || PSERIES
-
-config XIVE_SPAPR
-bool
-default y
-depends on PSERIES
-select XIVE
-
-config XIVE_KVM
-bool
-default y
-depends on XIVE_SPAPR && KVM
-
 # Only used by 64-bit targets
 config FW_CFG_PPC
 bool