Re: [PATCH v2 2/2] hw/arm/aspeed_ast2600: create i3c instance

2022-01-10 Thread Troy Lee
On Mon, Jan 10, 2022 at 10:31 PM Cédric Le Goater  wrote:
>
> On 1/10/22 08:21, Troy Lee wrote:
> > This patch includes i3c instance in ast2600 soc.
> >
> > v2: Rebase to mainline QEMU
> >
> > Signed-off-by: Troy Lee 
> > ---
> >   hw/arm/aspeed_ast2600.c | 19 ++-
> >   include/hw/arm/aspeed_soc.h |  3 +++
> >   2 files changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> > index e33483fb5d..36aa31601a 100644
> > --- a/hw/arm/aspeed_ast2600.c
> > +++ b/hw/arm/aspeed_ast2600.c
> > @@ -29,7 +29,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
> >   [ASPEED_DEV_PWM]   = 0x1E61,
> >   [ASPEED_DEV_FMC]   = 0x1E62,
> >   [ASPEED_DEV_SPI1]  = 0x1E63,
> > -[ASPEED_DEV_SPI2]  = 0x1E641000,
> > +[ASPEED_DEV_SPI2]  = 0x1E631000,
>
> Indeed ! But this belongs to another patch fixing the value.
>

Oops, that should be in a different branch, I might accidentally pick
that into my working branch. dkodihal will send it separately.


> >   [ASPEED_DEV_EHCI1] = 0x1E6A1000,
> >   [ASPEED_DEV_EHCI2] = 0x1E6A3000,
> >   [ASPEED_DEV_MII1]  = 0x1E65,
> > @@ -61,6 +61,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
> >   [ASPEED_DEV_UART1] = 0x1E783000,
> >   [ASPEED_DEV_UART5] = 0x1E784000,
> >   [ASPEED_DEV_VUART] = 0x1E787000,
> > +[ASPEED_DEV_I3C]   = 0x1E7A,
> >   [ASPEED_DEV_SDRAM] = 0x8000,
> >   };
> >
> > @@ -108,6 +109,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
> >   [ASPEED_DEV_ETH4]  = 33,
> >   [ASPEED_DEV_KCS]   = 138,   /* 138 -> 142 */
> >   [ASPEED_DEV_DP]= 62,
> > +[ASPEED_DEV_I3C]   = 102,   /* 102 -> 107 */
> >   };
> >
> >   static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
> > @@ -223,6 +225,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
> >
> >   snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
> >   object_initialize_child(obj, "hace", >hace, typename);
> > +
> > +object_initialize_child(obj, "i3c", >i3c, TYPE_ASPEED_I3C);
> >   }
> >
> >   /*
> > @@ -523,6 +527,19 @@ static void aspeed_soc_ast2600_realize(DeviceState 
> > *dev, Error **errp)
> >   sysbus_mmio_map(SYS_BUS_DEVICE(>hace), 0, 
> > sc->memmap[ASPEED_DEV_HACE]);
> >   sysbus_connect_irq(SYS_BUS_DEVICE(>hace), 0,
> >  aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
> > +/* I3C */
> > +if (!sysbus_realize(SYS_BUS_DEVICE(>i3c), errp)) {
> > +return;
> > +}
> > +sysbus_mmio_map(SYS_BUS_DEVICE(>i3c), 0, 
> > sc->memmap[ASPEED_DEV_I3C]);
> > +sysbus_connect_irq(SYS_BUS_DEVICE(>i3c), 0,
> > +   aspeed_soc_get_irq(s, ASPEED_DEV_I3C));
>
> The controller device does not have an IRQ line.
>

Removed in v3.
Thanks for the review,
Troy Lee

> Thanks,
>
> C.
>
>
>
> > +for (i = 0; i < ASPEED_I3C_NR_DEVICES; i++) {
> > +qemu_irq irq = qdev_get_gpio_in(DEVICE(>a7mpcore),
> > +sc->irqmap[ASPEED_DEV_I3C] + i);
> > +/* The AST2600 I3C controller has one IRQ per bus. */
> > +sysbus_connect_irq(SYS_BUS_DEVICE(>i3c.devices[i]), 0, irq);
> > +}
> >   }
> >
> >   static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
> > diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> > index 18fb7eed46..cae9906684 100644
> > --- a/include/hw/arm/aspeed_soc.h
> > +++ b/include/hw/arm/aspeed_soc.h
> > @@ -21,6 +21,7 @@
> >   #include "hw/timer/aspeed_timer.h"
> >   #include "hw/rtc/aspeed_rtc.h"
> >   #include "hw/i2c/aspeed_i2c.h"
> > +#include "hw/misc/aspeed_i3c.h"
> >   #include "hw/ssi/aspeed_smc.h"
> >   #include "hw/misc/aspeed_hace.h"
> >   #include "hw/watchdog/wdt_aspeed.h"
> > @@ -51,6 +52,7 @@ struct AspeedSoCState {
> >   AspeedRtcState rtc;
> >   AspeedTimerCtrlState timerctrl;
> >   AspeedI2CState i2c;
> > +AspeedI3CState i3c;
> >   AspeedSCUState scu;
> >   AspeedHACEState hace;
> >   AspeedXDMAState xdma;
> > @@ -141,6 +143,7 @@ enum {
> >   ASPEED_DEV_HACE,
> >   ASPEED_DEV_DPMCU,
> >   ASPEED_DEV_DP,
> > +ASPEED_DEV_I3C,
> >   };
> >
> >   #endif /* ASPEED_SOC_H */
> >
>



[PATCH v1 2/2] hw/i386: Make pic a property of common x86 base machine type

2022-01-10 Thread Xiaoyao Li
Legacy PIC (8259) cannot be supported for TDX guests since TDX module
doesn't allow directly interrupt injection.  Using posted interrupts
for the PIC is not a viable option as the guest BIOS/kernel will not
do EOI for PIC IRQs, i.e. will leave the vIRR bit set.

Make PIC the property of common x86 machine type. Hence all x86
machines, including microvm, can disable it.

Signed-off-by: Xiaoyao Li 
---
 hw/i386/microvm.c | 27 +--
 hw/i386/pc_piix.c |  4 +++-
 hw/i386/pc_q35.c  |  4 +++-
 hw/i386/x86.c | 25 +
 include/hw/i386/microvm.h |  2 --
 include/hw/i386/x86.h |  2 ++
 6 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 89b555a2f584..754f1d0593e5 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -247,7 +247,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
 x86ms->pci_irq_mask = 0;
 }
 
-if (mms->pic == ON_OFF_AUTO_ON || mms->pic == ON_OFF_AUTO_AUTO) {
+if (x86ms->pic == ON_OFF_AUTO_ON || x86ms->pic == ON_OFF_AUTO_AUTO) {
 qemu_irq *i8259;
 
 i8259 = i8259_init(isa_bus, x86_allocate_cpu_irq());
@@ -491,23 +491,6 @@ static void microvm_machine_reset(MachineState *machine)
 }
 }
 
-static void microvm_machine_get_pic(Object *obj, Visitor *v, const char *name,
-void *opaque, Error **errp)
-{
-MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-OnOffAuto pic = mms->pic;
-
-visit_type_OnOffAuto(v, name, , errp);
-}
-
-static void microvm_machine_set_pic(Object *obj, Visitor *v, const char *name,
-void *opaque, Error **errp)
-{
-MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-
-visit_type_OnOffAuto(v, name, >pic, errp);
-}
-
 static void microvm_machine_get_rtc(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp)
 {
@@ -632,7 +615,6 @@ static void microvm_machine_initfn(Object *obj)
 MicrovmMachineState *mms = MICROVM_MACHINE(obj);
 
 /* Configuration */
-mms->pic = ON_OFF_AUTO_AUTO;
 mms->rtc = ON_OFF_AUTO_AUTO;
 mms->pcie = ON_OFF_AUTO_AUTO;
 mms->ioapic2 = ON_OFF_AUTO_AUTO;
@@ -684,13 +666,6 @@ static void microvm_class_init(ObjectClass *oc, void *data)
 
 x86mc->fwcfg_dma_enabled = true;
 
-object_class_property_add(oc, MICROVM_MACHINE_PIC, "OnOffAuto",
-  microvm_machine_get_pic,
-  microvm_machine_set_pic,
-  NULL, NULL);
-object_class_property_set_description(oc, MICROVM_MACHINE_PIC,
-"Enable i8259 PIC");
-
 object_class_property_add(oc, MICROVM_MACHINE_RTC, "OnOffAuto",
   microvm_machine_get_rtc,
   microvm_machine_set_rtc,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7c7790a5ce34..d05683cd0d77 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -218,7 +218,9 @@ static void pc_init1(MachineState *machine,
 }
 isa_bus_irqs(isa_bus, x86ms->gsi);
 
-pc_i8259_create(isa_bus, gsi_state->i8259_irq);
+if (x86ms->pic == ON_OFF_AUTO_ON || x86ms->pic == ON_OFF_AUTO_AUTO) {
+pc_i8259_create(isa_bus, gsi_state->i8259_irq);
+}
 
 if (pcmc->pci_enabled) {
 ioapic_init_gsi(gsi_state, "i440fx");
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 1780f79bc127..58e7e693f9e2 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -265,7 +265,9 @@ static void pc_q35_init(MachineState *machine)
 pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq);
 isa_bus = ich9_lpc->isa_bus;
 
-pc_i8259_create(isa_bus, gsi_state->i8259_irq);
+if (x86ms->pic == ON_OFF_AUTO_ON || x86ms->pic == ON_OFF_AUTO_AUTO) {
+pc_i8259_create(isa_bus, gsi_state->i8259_irq);
+}
 
 if (pcmc->pci_enabled) {
 ioapic_init_gsi(gsi_state, "q35");
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 744a50937761..d4a4c0ec8f61 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1243,6 +1243,23 @@ static void x86_machine_set_pit(Object *obj, Visitor *v, 
const char *name,
 visit_type_OnOffAuto(v, name, >pit, errp);
 }
 
+static void x86_machine_get_pic(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+X86MachineState *x86ms = X86_MACHINE(obj);
+OnOffAuto pic = x86ms->pic;
+
+visit_type_OnOffAuto(v, name, , errp);
+}
+
+static void x86_machine_set_pic(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+X86MachineState *x86ms = X86_MACHINE(obj);
+
+visit_type_OnOffAuto(v, name, >pic, errp);
+}
+
 static char *x86_machine_get_oem_id(Object *obj, Error **errp)
 {
 X86MachineState *x86ms = X86_MACHINE(obj);
@@ -1333,6 +1350,7 @@ static void x86_machine_initfn(Object *obj)
 

Re: [PATCH v2 1/2] hw/misc: Implementating dummy AST2600 I3C model

2022-01-10 Thread Troy Lee
Hi Cedric,
On Mon, Jan 10, 2022 at 10:25 PM Cédric Le Goater  wrote:
>
> Hello Troy,
>
> On 1/10/22 08:21, Troy Lee wrote:
> > Introduce a dummy AST2600 I3C model.
> >
> > Aspeed 2600 SDK enables I3C support by default.  The I3C driver will try
> > to reset the device controller and setup through device address table
> > register.  This dummy model response these register with default value
> > listed on ast2600v10 datasheet chapter 54.2.  If the device address
> > table register doesn't set correctly, it will cause guest machine kernel
> > panic due to reference to invalid address.
> >
> > v2:
> > - Split i3c model into i3c and i3c_device
> > - Create 6x i3c devices
> > - Using register fields macro
> >
> > Signed-off-by: Troy Lee 
> > ---
> >   hw/misc/aspeed_i3c.c | 410 +++
> >   hw/misc/meson.build  |   1 +
> >   hw/misc/trace-events |   6 +
> >   include/hw/misc/aspeed_i3c.h |  57 +
> >   4 files changed, 474 insertions(+)
> >   create mode 100644 hw/misc/aspeed_i3c.c
> >   create mode 100644 include/hw/misc/aspeed_i3c.h
> >
> > diff --git a/hw/misc/aspeed_i3c.c b/hw/misc/aspeed_i3c.c
> > new file mode 100644
> > index 00..16a4f2d4e4
> > --- /dev/null
> > +++ b/hw/misc/aspeed_i3c.c
> > @@ -0,0 +1,410 @@
> > +/*
> > + * ASPEED I3C Controller
> > + *
> > + * Copyright (C) 2021 ASPEED Technology Inc.
> > + *
> > + * This code is licensed under the GPL version 2 or later.  See
> > + * the COPYING file in the top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/log.h"
> > +#include "qemu/error-report.h"
> > +#include "hw/misc/aspeed_i3c.h"
> > +#include "hw/registerfields.h"
> > +#include "hw/qdev-properties.h"
> > +#include "qapi/error.h"
> > +#include "migration/vmstate.h"
> > +#include "trace.h"
> > +
> > +/* I3C Controller Registers */
> > +REG32(I3C1_REG0, 0x10)
> > +REG32(I3C1_REG1, 0x14)
> > +FIELD(I3C1_REG1, I2C_MODE,  0,  1)
> > +FIELD(I3C1_REG1, SA_EN, 15, 1)
> > +REG32(I3C2_REG0, 0x20)
> > +REG32(I3C2_REG1, 0x24)
> > +FIELD(I3C2_REG1, I2C_MODE,  0,  1)
> > +FIELD(I3C2_REG1, SA_EN, 15, 1)
> > +REG32(I3C3_REG0, 0x30)
> > +REG32(I3C3_REG1, 0x34)
> > +FIELD(I3C3_REG1, I2C_MODE,  0,  1)
> > +FIELD(I3C3_REG1, SA_EN, 15, 1)
> > +REG32(I3C4_REG0, 0x40)
> > +REG32(I3C4_REG1, 0x44)
> > +FIELD(I3C4_REG1, I2C_MODE,  0,  1)
> > +FIELD(I3C4_REG1, SA_EN, 15, 1)
> > +REG32(I3C5_REG0, 0x50)
> > +REG32(I3C5_REG1, 0x54)
> > +FIELD(I3C5_REG1, I2C_MODE,  0,  1)
> > +FIELD(I3C5_REG1, SA_EN, 15, 1)
> > +REG32(I3C6_REG0, 0x60)
> > +REG32(I3C6_REG1, 0x64)
> > +FIELD(I3C6_REG1, I2C_MODE,  0,  1)
> > +FIELD(I3C6_REG1, SA_EN, 15, 1)
> > +
> > +/* I3C Device Registers */
> > +REG32(DEVICE_CTRL,  0x00)
> > +REG32(DEVICE_ADDR,  0x04)
> > +REG32(HW_CAPABILITY,0x08)
> > +REG32(COMMAND_QUEUE_PORT,   0x0c)
> > +REG32(RESPONSE_QUEUE_PORT,  0x10)
> > +REG32(RX_TX_DATA_PORT,  0x14)
> > +REG32(IBI_QUEUE_STATUS, 0x18)
> > +REG32(IBI_QUEUE_DATA,   0x18)
> > +REG32(QUEUE_THLD_CTRL,  0x1c)
> > +REG32(DATA_BUFFER_THLD_CTRL,0x20)
> > +REG32(IBI_QUEUE_CTRL,   0x24)
> > +REG32(IBI_MR_REQ_REJECT,0x2c)
> > +REG32(IBI_SIR_REQ_REJECT,   0x30)
> > +REG32(RESET_CTRL,   0x34)
> > +REG32(SLV_EVENT_CTRL,   0x38)
> > +REG32(INTR_STATUS,  0x3c)
> > +REG32(INTR_STATUS_EN,   0x40)
> > +REG32(INTR_SIGNAL_EN,   0x44)
> > +REG32(INTR_FORCE,   0x48)
> > +REG32(QUEUE_STATUS_LEVEL,   0x4c)
> > +REG32(DATA_BUFFER_STATUS_LEVEL, 0x50)
> > +REG32(PRESENT_STATE,0x54)
> > +REG32(CCC_DEVICE_STATUS,0x58)
> > +REG32(DEVICE_ADDR_TABLE_POINTER,0x5c)
> > +FIELD(DEVICE_ADDR_TABLE_POINTER, DEPTH, 16, 16)
> > +FIELD(DEVICE_ADDR_TABLE_POINTER, ADDR,  0,  16)
> > +REG32(DEV_CHAR_TABLE_POINTER,   0x60)
> > +REG32(VENDOR_SPECIFIC_REG_POINTER,  0x6c)
> > +REG32(SLV_MIPI_PID_VALUE,   0x70)
> > +REG32(SLV_PID_VALUE,0x74)
> > +REG32(SLV_CHAR_CTRL,0x78)
> > +REG32(SLV_MAX_LEN,  0x7c)
> > +REG32(MAX_READ_TURNAROUND,  0x80)
> > +REG32(MAX_DATA_SPEED,   0x84)
> > +REG32(SLV_DEBUG_STATUS, 0x88)
> > +REG32(SLV_INTR_REQ, 0x8c)
> > +REG32(DEVICE_CTRL_EXTENDED, 0xb0)
> > +REG32(SCL_I3C_OD_TIMING,0xb4)
> > +REG32(SCL_I3C_PP_TIMING,0xb8)
> > +REG32(SCL_I2C_FM_TIMING,0xbc)
> > +REG32(SCL_I2C_FMP_TIMING,   0xc0)
> > +REG32(SCL_EXT_LCNT_TIMING,  0xc8)
> > +REG32(SCL_EXT_TERMN_LCNT_TIMING,0xcc)
> > +REG32(BUS_FREE_TIMING,  0xd4)
> > +REG32(BUS_IDLE_TIMING,  0xd8)
> > +REG32(I3C_VER_ID,   0xe0)
> > +REG32(I3C_VER_TYPE, 

[PATCH v1 0/2] i386: Make PIT and PIC the property of common x86 base machine type

2022-01-10 Thread Xiaoyao Li
For PIT, it's straightforward to merge microvm::pit and
pc_machine::pit_enabled into x86ms::pit

For PIC, move microvm::pic to x86ms:pic, which gives PC machine the
ability to dis-/en-able PIC and it's the preparation for future TDX
support.

Xiaoyao Li (2):
  hw/i386: Make pit a property of common x86 base machine type
  hw/i386: Make pic a property of common x86 base machine type

 hw/i386/microvm.c | 54 ++-
 hw/i386/pc.c  | 24 +++--
 hw/i386/pc_piix.c |  4 ++-
 hw/i386/pc_q35.c  |  4 ++-
 hw/i386/x86.c | 50 
 include/hw/i386/microvm.h |  4 ---
 include/hw/i386/pc.h  |  2 --
 include/hw/i386/x86.h |  4 +++
 8 files changed, 65 insertions(+), 81 deletions(-)

-- 
2.27.0




[PATCH v1 1/2] hw/i386: Make pit a property of common x86 base machine type

2022-01-10 Thread Xiaoyao Li
Both pc and microvm have pit property individually. Let's just make it
the property of common x86 base machine type.

Signed-off-by: Xiaoyao Li 
---
 hw/i386/microvm.c | 27 +--
 hw/i386/pc.c  | 24 +++-
 hw/i386/x86.c | 25 +
 include/hw/i386/microvm.h |  2 --
 include/hw/i386/pc.h  |  2 --
 include/hw/i386/x86.h |  2 ++
 6 files changed, 31 insertions(+), 51 deletions(-)

diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 4b3b1dd262f1..89b555a2f584 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -257,7 +257,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
 g_free(i8259);
 }
 
-if (mms->pit == ON_OFF_AUTO_ON || mms->pit == ON_OFF_AUTO_AUTO) {
+if (x86ms->pit == ON_OFF_AUTO_ON || x86ms->pit == ON_OFF_AUTO_AUTO) {
 if (kvm_pit_in_kernel()) {
 kvm_pit_init(isa_bus, 0x40);
 } else {
@@ -508,23 +508,6 @@ static void microvm_machine_set_pic(Object *obj, Visitor 
*v, const char *name,
 visit_type_OnOffAuto(v, name, >pic, errp);
 }
 
-static void microvm_machine_get_pit(Object *obj, Visitor *v, const char *name,
-void *opaque, Error **errp)
-{
-MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-OnOffAuto pit = mms->pit;
-
-visit_type_OnOffAuto(v, name, , errp);
-}
-
-static void microvm_machine_set_pit(Object *obj, Visitor *v, const char *name,
-void *opaque, Error **errp)
-{
-MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-
-visit_type_OnOffAuto(v, name, >pit, errp);
-}
-
 static void microvm_machine_get_rtc(Object *obj, Visitor *v, const char *name,
 void *opaque, Error **errp)
 {
@@ -650,7 +633,6 @@ static void microvm_machine_initfn(Object *obj)
 
 /* Configuration */
 mms->pic = ON_OFF_AUTO_AUTO;
-mms->pit = ON_OFF_AUTO_AUTO;
 mms->rtc = ON_OFF_AUTO_AUTO;
 mms->pcie = ON_OFF_AUTO_AUTO;
 mms->ioapic2 = ON_OFF_AUTO_AUTO;
@@ -709,13 +691,6 @@ static void microvm_class_init(ObjectClass *oc, void *data)
 object_class_property_set_description(oc, MICROVM_MACHINE_PIC,
 "Enable i8259 PIC");
 
-object_class_property_add(oc, MICROVM_MACHINE_PIT, "OnOffAuto",
-  microvm_machine_get_pit,
-  microvm_machine_set_pit,
-  NULL, NULL);
-object_class_property_set_description(oc, MICROVM_MACHINE_PIT,
-"Enable i8254 PIT");
-
 object_class_property_add(oc, MICROVM_MACHINE_RTC, "OnOffAuto",
   microvm_machine_get_rtc,
   microvm_machine_set_rtc,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c8696ac01e85..48ab4cf44012 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1071,6 +1071,7 @@ void pc_basic_device_init(struct PCMachineState *pcms,
 ISADevice *pit = NULL;
 MemoryRegion *ioport80_io = g_new(MemoryRegion, 1);
 MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);
+X86MachineState *x86ms = X86_MACHINE(pcms);
 
 memory_region_init_io(ioport80_io, NULL, _io_ops, NULL, 
"ioport80", 1);
 memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io);
@@ -1115,7 +1116,8 @@ void pc_basic_device_init(struct PCMachineState *pcms,
 
 qemu_register_boot_set(pc_boot_set, *rtc_state);
 
-if (!xen_enabled() && pcms->pit_enabled) {
+if (!xen_enabled() &&
+(x86ms->pit == ON_OFF_AUTO_AUTO || x86ms->pit == ON_OFF_AUTO_ON)) {
 if (kvm_pit_in_kernel()) {
 pit = kvm_pit_init(isa_bus, 0x40);
 } else {
@@ -1484,20 +1486,6 @@ static void pc_machine_set_sata(Object *obj, bool value, 
Error **errp)
 pcms->sata_enabled = value;
 }
 
-static bool pc_machine_get_pit(Object *obj, Error **errp)
-{
-PCMachineState *pcms = PC_MACHINE(obj);
-
-return pcms->pit_enabled;
-}
-
-static void pc_machine_set_pit(Object *obj, bool value, Error **errp)
-{
-PCMachineState *pcms = PC_MACHINE(obj);
-
-pcms->pit_enabled = value;
-}
-
 static bool pc_machine_get_hpet(Object *obj, Error **errp)
 {
 PCMachineState *pcms = PC_MACHINE(obj);
@@ -1640,7 +1628,6 @@ static void pc_machine_initfn(Object *obj)
 pcms->acpi_build_enabled = PC_MACHINE_GET_CLASS(pcms)->has_acpi_build;
 pcms->smbus_enabled = true;
 pcms->sata_enabled = true;
-pcms->pit_enabled = true;
 pcms->max_fw_size = 8 * MiB;
 #ifdef CONFIG_HPET
 pcms->hpet_enabled = true;
@@ -1767,11 +1754,6 @@ static void pc_machine_class_init(ObjectClass *oc, void 
*data)
 object_class_property_set_description(oc, PC_MACHINE_SATA,
 "Enable/disable Serial ATA bus");
 
-object_class_property_add_bool(oc, PC_MACHINE_PIT,
-pc_machine_get_pit, pc_machine_set_pit);
-object_class_property_set_description(oc, PC_MACHINE_PIT,
-"Enable/disable Intel 8254 programmable 

[PATCH v2 1/2] riscv: opentitan: fixup plic stride len

2022-01-10 Thread Alistair Francis
From: Wilfred Mallawa 

The following change was made to rectify incorrectly set stride length
on the PLIC [1]. Where it should be 32bit and not 24bit (0x18). This was
discovered whilst attempting to fix a bug where a timer_interrupt was
not serviced on TockOS-OpenTitan.

[1] https://docs.opentitan.org/hw/top_earlgrey/ip_autogen/rv_plic/doc/

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Tested-by: Alistair Francis 
Reviewed-by: Bin Meng 
---
 hw/riscv/opentitan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index c531450b9f..5144845567 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -160,7 +160,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 qdev_prop_set_uint32(DEVICE(>plic), "priority-base", 0x00);
 qdev_prop_set_uint32(DEVICE(>plic), "pending-base", 0x1000);
 qdev_prop_set_uint32(DEVICE(>plic), "enable-base", 0x2000);
-qdev_prop_set_uint32(DEVICE(>plic), "enable-stride", 0x18);
+qdev_prop_set_uint32(DEVICE(>plic), "enable-stride", 32);
 qdev_prop_set_uint32(DEVICE(>plic), "context-base", 0x20);
 qdev_prop_set_uint32(DEVICE(>plic), "context-stride", 8);
 qdev_prop_set_uint32(DEVICE(>plic), "aperture-size", 
memmap[IBEX_DEV_PLIC].size);
-- 
2.34.1




[PATCH] ui/cocoa: capture screencast with AVAssetWriter

2022-01-10 Thread Zhang Chen
To record screencast, AVAssetWriter APIs were called for each
cocoa_update call.

Commands for start/stop recording were added to View menu.

AVFoundation, CoreMedia and CoreVideo were added as linking
dependencies.

Signed-off-by: Zhang Chen 
---
 meson.build|   6 +++
 ui/cocoa.m | 132 +++--
 ui/meson.build |   1 +
 3 files changed, 136 insertions(+), 3 deletions(-)

diff --git a/meson.build b/meson.build
index 886f0a9343..70c38c4135 100644
--- a/meson.build
+++ b/meson.build
@@ -281,6 +281,9 @@ emulator_link_args = []
 nvmm =not_found
 hvf = not_found
 host_dsosuf = '.so'
+avfoundation = []
+coremedia = []
+corevideo = []
 if targetos == 'windows'
   socket = cc.find_library('ws2_32')
   winmm = cc.find_library('winmm')
@@ -292,6 +295,9 @@ if targetos == 'windows'
   host_dsosuf = '.dll'
 elif targetos == 'darwin'
   coref = dependency('appleframeworks', modules: 'CoreFoundation')
+  avfoundation = dependency('appleframeworks', modules: 'AVFoundation')
+  coremedia = dependency('appleframeworks', modules: 'CoreMedia')
+  corevideo = dependency('appleframeworks', modules: 'CoreVideo')
   iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
   host_dsosuf = '.dylib'
 elif targetos == 'sunos'
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 69745c483b..6a0fc24414 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 
 #import 
+#import 
 #include 
 
 #include "qemu-common.h"
@@ -309,6 +310,12 @@ static void handleAnyDeviceErrors(Error * err)
 BOOL isMouseGrabbed;
 BOOL isFullscreen;
 BOOL isAbsoluteEnabled;
+AVAssetWriter *capture;
+AVAssetWriterInput *captureInput;
+AVAssetWriterInputPixelBufferAdaptor *captureInputAdaptor;
+BOOL isCapturing;
+NSDate *captureStart;
+CVPixelBufferRef captureBuffer;
 }
 - (void) switchSurface:(pixman_image_t *)image;
 - (void) grabMouse;
@@ -332,6 +339,9 @@ static void handleAnyDeviceErrors(Error * err)
 - (float) cdy;
 - (QEMUScreen) gscreen;
 - (void) raiseAllKeys;
+- (void) startCapture;
+- (void) stopCapture;
+- (BOOL) isCapturing;
 @end
 
 QemuCocoaView *cocoaView;
@@ -364,6 +374,10 @@ QemuCocoaView *cocoaView;
 [super dealloc];
 }
 
+- (BOOL) isCapturing {
+return isCapturing;
+}
+
 - (BOOL) isOpaque
 {
 return YES;
@@ -425,6 +439,81 @@ QemuCocoaView *cocoaView;
 [NSCursor unhide];
 }
 
+- (IBAction) startCapture
+{
+NSError *err;
+
+NSString *outputPath = [NSString 
stringWithFormat:@"/tmp/capture_%.1f.mp4", [[NSDate now] 
timeIntervalSinceReferenceDate]];
+NSURL *fileURL = [NSURL fileURLWithPath:outputPath];
+capture = [[AVAssetWriter alloc] initWithURL:fileURL 
fileType:AVFileTypeMPEG4 error:];
+
+captureInput = [[AVAssetWriterInput alloc] 
initWithMediaType:AVMediaTypeVideo
+   outputSettings:@{
+AVVideoCodecKey: AVVideoCodecTypeH264,
+AVVideoWidthKey: [NSNumber numberWithInt:screen.width],
+AVVideoHeightKey: [NSNumber numberWithInt:screen.height],
+}];
+NSParameterAssert([capture canAddInput:captureInput]);
+[capture addInput:captureInput];
+captureInputAdaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] 
initWithAssetWriterInput:captureInput sourcePixelBufferAttributes:nil];
+
+OSStatus bufferStatus = CVPixelBufferCreateWithBytes(NULL,
+ screen.width,
+ screen.height,
+ 
kCVPixelFormatType_32BGRA,
+ 
pixman_image_get_data(pixman_image),
+ 
pixman_image_get_stride(pixman_image),
+ NULL,
+ NULL,
+ NULL,
+ );
+if (bufferStatus != kCVReturnSuccess) {
+NSLog(@"err creating pixel buf: %d", bufferStatus);
+return;
+}
+captureStart = [NSDate new];
+[capture startWriting];
+[capture startSessionAtSourceTime:kCMTimeZero];
+isCapturing = TRUE;
+[self captureFrame];
+}
+
+- (void) stopCapture
+{
+if (isCapturing) {
+isCapturing = FALSE;
+NSDate *now = [NSDate now];
+NSTimeInterval interval = [now timeIntervalSinceDate:captureStart];
+CMTime ts = CMTimeMakeWithSeconds(interval, 100);
+[captureInput markAsFinished];
+[capture endSessionAtSourceTime:ts];
+pixman_image_ref(pixman_image);
+[capture finishWritingWithCompletionHandler:^() {
+NSLog(@"finishWriting");
+[captureInputAdaptor release];
+[captureInput release];
+CFRelease(captureBuffer);
+ 

[PATCH v2 2/2] hw: timer: ibex_timer: update/add reg address

2022-01-10 Thread Alistair Francis
From: Wilfred Mallawa 

The following changes:
1. Fixes the incorrectly set CTRL register address. As
per [1] https://docs.opentitan.org/hw/ip/rv_timer/doc/#register-table

The CTRL register is @ 0x04.

This was found when attempting to fixup a bug where a timer_interrupt
was not serviced on TockOS-OpenTitan.

2. Adds ALERT_TEST register as documented on [1], adding repective
   switch cases to error handle and later implement functionality.

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Tested-by: Alistair Francis 
Reviewed-by: Bin Meng 
---
 hw/timer/ibex_timer.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
index 66e1f8e48c..096588ac8a 100644
--- a/hw/timer/ibex_timer.c
+++ b/hw/timer/ibex_timer.c
@@ -34,7 +34,9 @@
 #include "target/riscv/cpu.h"
 #include "migration/vmstate.h"
 
-REG32(CTRL, 0x00)
+REG32(ALERT_TEST, 0x00)
+FIELD(ALERT_TEST, FATAL_FAULT, 0, 1)
+REG32(CTRL, 0x04)
 FIELD(CTRL, ACTIVE, 0, 1)
 REG32(CFG0, 0x100)
 FIELD(CFG0, PRESCALE, 0, 12)
@@ -143,6 +145,10 @@ static uint64_t ibex_timer_read(void *opaque, hwaddr addr,
 uint64_t retvalue = 0;
 
 switch (addr >> 2) {
+case R_ALERT_TEST:
+qemu_log_mask(LOG_GUEST_ERROR,
+"Attempted to read ALERT_TEST, a write only register");
+break;
 case R_CTRL:
 retvalue = s->timer_ctrl;
 break;
@@ -186,6 +192,9 @@ static void ibex_timer_write(void *opaque, hwaddr addr,
 uint32_t val = val64;
 
 switch (addr >> 2) {
+case R_ALERT_TEST:
+qemu_log_mask(LOG_UNIMP, "Alert triggering not supported");
+break;
 case R_CTRL:
 s->timer_ctrl = val;
 break;
-- 
2.34.1




Re: [PATCH] linux-user: Fix clang warning for nios2-linux-user code

2022-01-10 Thread Laurent Vivier

Le 10/01/2022 à 20:17, Peter Maydell a écrit :

The clang in Ubuntu 18.04 (10.0.0-4ubuntu1) produces a warning
on the code added in commit f5ef0e518d03 where we use a
shifted expression in a boolean context:

../../linux-user/elfload.c:2423:16: error: converting the result of '<<' to a 
boolean always evaluates to true [-Werror,-Wtautological-constant-compare]
 } else if (LO_COMMPAGE) {
^
../../linux-user/elfload.c:1102:22: note: expanded from macro 'LO_COMMPAGE'
#define LO_COMMPAGE  TARGET_PAGE_SIZE
  ^
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/include/exec/cpu-all.h:231:31: note: 
expanded from macro 'TARGET_PAGE_SIZE'
#define TARGET_PAGE_SIZE   (1 << TARGET_PAGE_BITS)
   ^
1 error generated.

The warning is bogus because whether LO_COMMPAGE is zero or not
depends on compile-time ifdefs; shut the compiler up by adding
an explicit comparison to zero.

Fixes: f5ef0e518d0331 ("linux-user/nios2: Map a real kuser page")
Signed-off-by: Peter Maydell 
---
I'm probably going to apply this directly once it's reviewed, because
it fixes a build-break on one of my machines.

  linux-user/elfload.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 329b2375ef1..2993b01e60c 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2420,7 +2420,7 @@ static void pgb_static(const char *image_name, abi_ulong 
orig_loaddr,
  } else {
  offset = -(HI_COMMPAGE & -align);
  }
-} else if (LO_COMMPAGE) {
+} else if (LO_COMMPAGE == 0) {


It seems to revert the logic should it be "(LO_COMMPAGE != 0)"?

Thanks,
Laurent

  loaddr = MIN(loaddr, LO_COMMPAGE & -align);
  }
  





Re: [RFC PATCH 3/7] x86: Grant AMX permission for guest

2022-01-10 Thread Yang Zhong
On Mon, Jan 10, 2022 at 04:36:13PM +0800, Tian, Kevin wrote:
> > From: Zhong, Yang 
> > Sent: Friday, January 7, 2022 5:32 PM
> >
> > Kernel mechanism for dynamically enabled XSAVE features
> 
> there is no definition of "dynamically-enabled XSAVE features).
> 

  Thanks!


> > asks userspace VMM requesting guest permission if it wants
> > to expose the features. Only with the permission, kernel
> > can try to enable the features when detecting the intention
> > from guest in runtime.
> >
> > Qemu should request the permission for guest only once
> > before the first vCPU is created. KVM checks the guest
> > permission when Qemu advertises the features, and the
> > advertising operation fails w/o permission.
> 
> what about below?
> 
> "Kernel allocates 4K xstate buffer by default. For XSAVE features
> which require large state component (e.g. AMX), Linux kernel
> dynamically expands the xstate buffer only after the process has
> acquired the necessary permissions. Those are called dynamically-
> enabled XSAVE features (or dynamic xfeatures).
> 
> There are separate permissions for native tasks and guests.
> 
> Qemu should request the guest permissions for dynamic xfeatures
> which will be exposed to the guest. This only needs to be done
> once before the first vcpu is created."


  This is clearer. Will update this in new version, thanks!


> 
> >
> > Signed-off-by: Yang Zhong 
> > Signed-off-by: Jing Liu 
> > ---
> >  target/i386/cpu.h |  7 +++
> >  hw/i386/x86.c | 28 
> >  2 files changed, 35 insertions(+)
> >
> > diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> > index 768a8218be..79023fe723 100644
> > --- a/target/i386/cpu.h
> > +++ b/target/i386/cpu.h
> > @@ -549,6 +549,13 @@ typedef enum X86Seg {
> >  #define XSTATE_ZMM_Hi256_MASK   (1ULL << XSTATE_ZMM_Hi256_BIT)
> >  #define XSTATE_Hi16_ZMM_MASK(1ULL << XSTATE_Hi16_ZMM_BIT)
> >  #define XSTATE_PKRU_MASK(1ULL << XSTATE_PKRU_BIT)
> > +#define XSTATE_XTILE_CFG_MASK   (1ULL << XSTATE_XTILE_CFG_BIT)
> > +#define XSTATE_XTILE_DATA_MASK  (1ULL << XSTATE_XTILE_DATA_BIT)
> > +#define XFEATURE_XTILE_MASK (XSTATE_XTILE_CFG_MASK \
> > + | XSTATE_XTILE_DATA_MASK)
> > +
> > +#define ARCH_GET_XCOMP_GUEST_PERM   0x1024
> > +#define ARCH_REQ_XCOMP_GUEST_PERM   0x1025
> >
> >  /* CPUID feature words */
> >  typedef enum FeatureWord {
> > diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> > index b84840a1bb..0a204c375e 100644
> > --- a/hw/i386/x86.c
> > +++ b/hw/i386/x86.c
> > @@ -41,6 +41,8 @@
> >  #include "sysemu/cpu-timers.h"
> >  #include "trace.h"
> >
> > +#include 
> > +
> >  #include "hw/i386/x86.h"
> >  #include "target/i386/cpu.h"
> >  #include "hw/i386/topology.h"
> > @@ -117,6 +119,30 @@ out:
> >  object_unref(cpu);
> >  }
> >
> > +static void x86_xsave_req_perm(void)
> > +{
> > +unsigned long bitmask;
> > +
> > +long rc = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_GUEST_PERM,
> > +  XSTATE_XTILE_DATA_BIT);
> 
> Should we do it based on the cpuid for the first vcpu?


  This permission is requested before vcpu init, so put it in
  x86_cpus_init(). If the host kernel does not include AMX changes, or
  the latest kernel(include AMX) install on previous generation x86
  platform, this syscall() will directly return. I ever put this
  permission request in the vcpu create function, but it's hard
  to find a good location to handle this. As for cpuid, you mean
  I need check host cpuid info? to check if this host cpu can support
  AMX? thanks!

  Yang   
   
> 
> > +if (rc) {
> > +/*
> > + * The older kernel version(<5.15) can't support
> > + * ARCH_REQ_XCOMP_GUEST_PERM and directly return.
> > + */
> > +return;
> > +}
> > +
> > +rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_GUEST_PERM, );
> > +if (rc) {
> > +error_report("prctl(ARCH_GET_XCOMP_GUEST_PERM) error: %ld", rc);
> > +} else if (!(bitmask & XFEATURE_XTILE_MASK)) {
> > +error_report("prctl(ARCH_REQ_XCOMP_GUEST_PERM) failure "
> > + "and bitmask=0x%lx", bitmask);
> > +exit(EXIT_FAILURE);
> > +}
> > +}
> > +
> >  void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version)
> >  {
> >  int i;
> > @@ -124,6 +150,8 @@ void x86_cpus_init(X86MachineState *x86ms, int
> > default_cpu_version)
> >  MachineState *ms = MACHINE(x86ms);
> >  MachineClass *mc = MACHINE_GET_CLASS(x86ms);
> >
> > +/* Request AMX pemission for guest */
> > +x86_xsave_req_perm();
> >  x86_cpu_set_default_version(default_cpu_version);
> >
> >  /*



[PATCH v4 1/2] virtio-mem: Correct default THP size for ARM64

2022-01-10 Thread Gavin Shan
The default block size is same as to the THP size, which is either
retrieved from "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size"
or hardcoded to 2MB. There are flaws in both mechanisms and this
intends to fix them up.

  * When "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size" is
used to getting the THP size, 32MB and 512MB are valid values
when we have 16KB and 64KB page size on ARM64.

  * When the hardcoded THP size is used, 2MB, 32MB and 512MB are
valid values when we have 4KB, 16KB and 64KB page sizes on
ARM64.

Co-developed-by: David Hildenbrand 
Signed-off-by: Gavin Shan 
Reviewed-by: Jonathan Cameron 
Reviewed-by: David Hildenbrand 
---
 hw/virtio/virtio-mem.c | 32 
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index 04c223b0c9..1ca45336dc 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -46,14 +46,25 @@
  */
 #define VIRTIO_MEM_MIN_BLOCK_SIZE ((uint32_t)(1 * MiB))
 
-#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \
-defined(__powerpc64__)
-#define VIRTIO_MEM_DEFAULT_THP_SIZE ((uint32_t)(2 * MiB))
-#else
-/* fallback to 1 MiB (e.g., the THP size on s390x) */
-#define VIRTIO_MEM_DEFAULT_THP_SIZE VIRTIO_MEM_MIN_BLOCK_SIZE
+static uint32_t virtio_mem_default_thp_size(void)
+{
+uint32_t default_thp_size = VIRTIO_MEM_MIN_BLOCK_SIZE;
+
+#if defined(__x86_64__) || defined(__arm__) || defined(__powerpc64__)
+default_thp_size = 2 * MiB;
+#elif defined(__aarch64__)
+if (qemu_real_host_page_size == 4 * KiB) {
+default_thp_size = 2 * MiB;
+} else if (qemu_real_host_page_size == 16 * KiB) {
+default_thp_size = 32 * MiB;
+} else if (qemu_real_host_page_size == 64 * KiB) {
+default_thp_size = 512 * MiB;
+}
 #endif
 
+return default_thp_size;
+}
+
 /*
  * We want to have a reasonable default block size such that
  * 1. We avoid splitting THPs when unplugging memory, which degrades
@@ -86,11 +97,8 @@ static uint32_t virtio_mem_thp_size(void)
 if (g_file_get_contents(HPAGE_PMD_SIZE_PATH, , NULL, NULL) &&
 !qemu_strtou64(content, , 0, ) &&
 (!endptr || *endptr == '\n')) {
-/*
- * Sanity-check the value, if it's too big (e.g., aarch64 with 64k base
- * pages) or weird, fallback to something smaller.
- */
-if (!tmp || !is_power_of_2(tmp) || tmp > 16 * MiB) {
+/* Sanity-check the value and fallback to something reasonable. */
+if (!tmp || !is_power_of_2(tmp)) {
 warn_report("Read unsupported THP size: %" PRIx64, tmp);
 } else {
 thp_size = tmp;
@@ -98,7 +106,7 @@ static uint32_t virtio_mem_thp_size(void)
 }
 
 if (!thp_size) {
-thp_size = VIRTIO_MEM_DEFAULT_THP_SIZE;
+thp_size = virtio_mem_default_thp_size();
 warn_report("Could not detect THP size, falling back to %" PRIx64
 "  MiB.", thp_size / MiB);
 }
-- 
2.23.0




[PATCH v4 2/2] hw/arm/virt: Support for virtio-mem-pci

2022-01-10 Thread Gavin Shan
This supports virtio-mem-pci device on "virt" platform, by simply
following the implementation on x86.

   * This implements the hotplug handlers to support virtio-mem-pci
 device hot-add, while the hot-remove isn't supported as we have
 on x86.

   * The block size is 512MB on ARM64 instead of 128MB on x86.

   * It has been passing the tests with various combinations like 64KB
 and 4KB page sizes on host and guest, different memory device
 backends like normal, transparent huge page and HugeTLB, plus
 migration.

Co-developed-by: David Hildenbrand 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Gavin Shan 
Reviewed-by: Jonathan Cameron 
Reviewed-by: David Hildenbrand 
---
 hw/arm/Kconfig |  1 +
 hw/arm/virt.c  | 70 ++
 hw/virtio/virtio-mem.c |  4 ++-
 3 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index e652590943..33082adc88 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -28,6 +28,7 @@ config ARM_VIRT
 select ACPI_HW_REDUCED
 select ACPI_APEI
 select ACPI_VIOT
+select VIRTIO_MEM_SUPPORTED
 
 config CHEETAH
 bool
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b45b52c90e..1954595b6b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -71,9 +71,11 @@
 #include "hw/arm/smmuv3.h"
 #include "hw/acpi/acpi.h"
 #include "target/arm/internals.h"
+#include "hw/mem/memory-device.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/mem/nvdimm.h"
 #include "hw/acpi/generic_event_device.h"
+#include "hw/virtio/virtio-mem-pci.h"
 #include "hw/virtio/virtio-iommu.h"
 #include "hw/char/pl011.h"
 #include "qemu/guest-random.h"
@@ -2482,6 +2484,64 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
  dev, _abort);
 }
 
+static void virt_virtio_md_pci_pre_plug(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
+Error *local_err = NULL;
+
+if (!hotplug_dev2 && dev->hotplugged) {
+/*
+ * Without a bus hotplug handler, we cannot control the plug/unplug
+ * order. We should never reach this point when hotplugging on ARM.
+ * However, it's nice to add a safety net, similar to what we have
+ * on x86.
+ */
+error_setg(errp, "hotplug of virtio based memory devices not supported"
+   " on this bus.");
+return;
+}
+/*
+ * First, see if we can plug this memory device at all. If that
+ * succeeds, branch of to the actual hotplug handler.
+ */
+memory_device_pre_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev), NULL,
+   _err);
+if (!local_err && hotplug_dev2) {
+hotplug_handler_pre_plug(hotplug_dev2, dev, _err);
+}
+error_propagate(errp, local_err);
+}
+
+static void virt_virtio_md_pci_plug(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
+Error *local_err = NULL;
+
+/*
+ * Plug the memory device first and then branch off to the actual
+ * hotplug handler. If that one fails, we can easily undo the memory
+ * device bits.
+ */
+memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
+if (hotplug_dev2) {
+hotplug_handler_plug(hotplug_dev2, dev, _err);
+if (local_err) {
+memory_device_unplug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
+}
+}
+error_propagate(errp, local_err);
+}
+
+static void virt_virtio_md_pci_unplug_request(HotplugHandler *hotplug_dev,
+  DeviceState *dev, Error **errp)
+{
+/* We don't support hot unplug of virtio based memory devices */
+error_setg(errp, "virtio based memory devices cannot be unplugged.");
+}
+
+
 static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
 DeviceState *dev, Error **errp)
 {
@@ -2489,6 +2549,8 @@ static void 
virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 virt_memory_pre_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
+virt_virtio_md_pci_pre_plug(hotplug_dev, dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
 hwaddr db_start = 0, db_end = 0;
 char *resv_prop_str;
@@ -2540,6 +2602,11 @@ static void virt_machine_device_plug_cb(HotplugHandler 
*hotplug_dev,
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 virt_memory_plug(hotplug_dev, dev, errp);
 }
+
+if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
+virt_virtio_md_pci_plug(hotplug_dev, dev, errp);
+}
+
 if 

[PATCH v4 0/2] hw/arm/virt: Support for virtio-mem-pci

2022-01-10 Thread Gavin Shan
This series supports virtio-mem-pci device, by simply following the
implementation on x86. The exception is the block size is 512MB on
ARM64 instead of 128MB on x86, compatible with the memory section
size in linux guest.

The work was done by David Hildenbrand and then Jonathan Cameron. I'm
taking the patch and putting more efforts, which is all about testing
to me at current stage.

Testing
===
The upstream linux kernel (v5.16.rc3) is used on host/guest during
the testing. The guest kernel includes changes to enable virtio-mem
driver, which is simply to enable CONFIG_VIRTIO_MEM on ARM64.

Mutiple combinations like page sizes on host/guest, memory backend
device etc are covered in the testing. Besides, migration is also
tested. The following command lines are used for VM or virtio-mem-pci
device hot-add. It's notable that virtio-mem-pci device hot-remove
isn't supported, similar to what we have on x86.

  host.pgsize  guest.pgsize  backendhot-add  hot-remove  migration
  -
   4KB 4KB   normal ok   ok  ok
 THPok   ok  ok
 hugeTLBok   ok  ok
   4KB 64KB  normal ok   ok  ok
 THPok   ok  ok
 hugeTLBok   ok  ok
  64KB 4KB   normal ok   ok  ok
 THPok   ok  ok
 hugeTLBok   ok  ok
  64KB 64KB  normal ok   ok  ok
 THPok   ok  ok
 hugeTLBok   ok  ok

The command lines are used for VM. When hugeTLBfs is used, all memory
backend objects are popuated on /dev/hugepages-2048kB or
/dev/hugepages-524288kB, depending on the host page sizes.

  /home/gavin/sandbox/qemu.main/build/qemu-system-aarch64   
\
  -accel kvm -machine virt,gic-version=host 
\
  -cpu host -smp 4,sockets=2,cores=2,threads=1  
\
  -m 1024M,slots=16,maxmem=64G  
\
  -object memory-backend-ram,id=mem0,size=512M  
\
  -object memory-backend-ram,id=mem1,size=512M  
\
  -numa node,nodeid=0,cpus=0-1,memdev=mem0  
\
  -numa node,nodeid=1,cpus=2-3,memdev=mem1  
\
 :
  -kernel /home/gavin/sandbox/linux.guest/arch/arm64/boot/Image 
\
  -initrd /home/gavin/sandbox/images/rootfs.cpio.xz 
\
  -append earlycon=pl011,mmio,0x900 
\
  -device pcie-root-port,bus=pcie.0,chassis=1,id=pcie.1 
\
  -device pcie-root-port,bus=pcie.0,chassis=2,id=pcie.2 
\
  -device pcie-root-port,bus=pcie.0,chassis=3,id=pcie.3 
\
  -object memory-backend-ram,id=vmem0,size=512M 
\
  -device virtio-mem-pci,id=vm0,bus=pcie.1,memdev=vmem0,node=0,requested-size=0 
\
  -object memory-backend-ram,id=vmem1,size=512M 
\
  -device virtio-mem-pci,id=vm1,bus=pcie.2,memdev=vmem1,node=1,requested-size=0

Command lines used for memory hot-add and hot-remove:

  (qemu) qom-set vm1 requested-size 512M
  (qemu) qom-set vm1 requested-size 0
  (qemu) qom-set vm1 requested-size 512M

Command lines used for virtio-mem-pci device hot-add:

  (qemu) object_add memory-backend-ram,id=hp-mem1,size=512M
  (qemu) device_add virtio-mem-pci,id=hp-vm1,bus=pcie.3,memdev=hp-mem1,node=1
  (qemu) qom-set hp-vm1 requested-size 512M
  (qemu) qom-set hp-vm1 requested-size 0
  (qemu) qom-set hp-vm1 requested-size 512M

Changelog
=
v4:
  * Improved comments in virt_virtio_md_pci_pre_plug()  (Peter)
v3:
  * Reshuffle patches   (David)
  * Suggested code refactoring for virtio_mem_default_thp_size()(David)
  * Pick r-b from Jonathan and David(Gavin)
v2:
  * Include David/Jonathan as co-developers in the commit log   (David)
  * Decrease VIRTIO_MEM_USABLE_EXTENT to 512MB on ARM64 in PATCH[1/2]   (David)
  * PATCH[2/2] is added to correct the THP sizes on ARM64   (David)

Gavin Shan (2):
  virtio-mem: Correct default THP size for ARM64
  hw/arm/virt: Support for virtio-mem-pci

 hw/arm/Kconfig |  1 +
 hw/arm/virt.c  | 70 ++
 hw/virtio/virtio-mem.c | 36 ++
 3 files changed, 94 insertions(+), 13 deletions(-)

-- 
2.23.0




Re: [PATCH v6 12/23] target/riscv: Implement AIA interrupt filtering CSRs

2022-01-10 Thread Frank Chang
Anup Patel  於 2021年12月30日 週四 下午8:41寫道:

> From: Anup Patel 
>
> The AIA specificaiton adds interrupt filtering support for M-mode
> and HS-mode. Using AIA interrupt filtering M-mode and H-mode can
> take local interrupt 13 or above and selectively inject same local
> interrupt to lower privilege modes.
>
> At the moment, we don't have any local interrupts above 12 so we
> add dummy implementation (i.e. read zero and ignore write) of AIA
> interrupt filtering CSRs.
>
> Signed-off-by: Anup Patel 
> Signed-off-by: Anup Patel 
> Reviewed-by: Alistair Francis 
> ---
>  target/riscv/csr.c | 23 +++
>  1 file changed, 23 insertions(+)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index decb0376fc..55e747fbf7 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -154,6 +154,15 @@ static RISCVException any32(CPURISCVState *env, int
> csrno)
>
>  }
>
> +static int aia_any(CPURISCVState *env, int csrno)
> +{
> +if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
> +
> +return any(env, csrno);
> +}
> +
>  static int aia_any32(CPURISCVState *env, int csrno)
>  {
>  if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
> @@ -553,6 +562,12 @@ static RISCVException read_zero(CPURISCVState *env,
> int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> +static RISCVException write_ignore(CPURISCVState *env, int csrno,
> +   target_ulong val)
> +{
> +return RISCV_EXCP_NONE;
> +}
> +
>  static RISCVException read_mhartid(CPURISCVState *env, int csrno,
> target_ulong *val)
>  {
> @@ -2374,9 +2389,15 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_MTVAL]= { "mtval",any,  read_mtval,write_mtval},
>  [CSR_MIP]  = { "mip",  any,  NULL,NULL, rmw_mip},
>
> +/* Virtual Interrupts for Supervisor Level (AIA) */
> +[CSR_MVIEN]  = { "mvien", aia_any, read_zero, write_ignore },
> +[CSR_MVIP]   = { "mvip",  aia_any, read_zero, write_ignore },
> +
>  /* Machine-Level High-Half CSRs (AIA) */
>  [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
>  [CSR_MIEH] = { "mieh", aia_any32, NULL, NULL, rmw_mieh },
> +[CSR_MVIENH]   = { "mvienh",   aia_any32, read_zero,  write_ignore },
> +[CSR_MVIPH]= { "mviph",aia_any32, read_zero,  write_ignore },
>  [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph },
>
>  /* Supervisor Trap Setup */
> @@ -2428,12 +2449,14 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_MTINST]  = { "mtinst",  hmode,   read_mtinst,
> write_mtinst  },
>
>  /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA)
> */
> +[CSR_HVIEN]   = { "hvien",   aia_hmode, read_zero,
> write_ignore },
>  [CSR_HVICTL]  = { "hvictl",  aia_hmode, read_hvictl,
> write_hvictl },
>  [CSR_HVIPRIO1]= { "hviprio1",aia_hmode, read_hviprio1,
>  write_hviprio1 },
>  [CSR_HVIPRIO2]= { "hviprio2",aia_hmode, read_hviprio2,
>  write_hviprio2 },
>
>  /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
>  [CSR_HIDELEGH]= { "hidelegh",aia_hmode32, NULL, NULL,
> rmw_hidelegh },
> +[CSR_HVIENH]  = { "hvienh",  aia_hmode32, read_zero,
> write_ignore },
>  [CSR_HVIPH]   = { "hviph",   aia_hmode32, NULL, NULL,
> rmw_hviph },
>  [CSR_HVIPRIO1H]   = { "hviprio1h",   aia_hmode32, read_hviprio1h,
> write_hviprio1h },
>  [CSR_HVIPRIO2H]   = { "hviprio2h",   aia_hmode32, read_hviprio2h,
> write_hviprio2h },
> --
> 2.25.1
>
>
>
Reviewed-by: Frank Chang 


Re: [RFC PATCH 4/7] x86: Add XFD faulting bit for state components

2022-01-10 Thread Yang Zhong
On Mon, Jan 10, 2022 at 04:38:18PM +0800, Tian, Kevin wrote:
> > From: Zhong, Yang 
> > Sent: Friday, January 7, 2022 5:32 PM
> >
> > From: Jing Liu 
> >
> > Intel introduces XFD faulting mechanism for extended
> > XSAVE features to dynamically enable the features in
> > runtime. If CPUID (EAX=0Dh, ECX=n, n>1).ECX[2] is set
> > as 1, it indicates support for XFD faulting of this
> > state component.
> >
> > Signed-off-by: Jing Liu 
> > Signed-off-by: Yang Zhong 
> > ---
> >  target/i386/cpu.h | 2 +-
> >  target/i386/cpu.c | 2 +-
> >  target/i386/kvm/kvm-cpu.c | 1 +
> >  3 files changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> > index 79023fe723..22f7ff40a6 100644
> > --- a/target/i386/cpu.h
> > +++ b/target/i386/cpu.h
> > @@ -1375,7 +1375,7 @@
> > QEMU_BUILD_BUG_ON(sizeof(XSaveXTILE_DATA) != 0x2000);
> >  typedef struct ExtSaveArea {
> >  uint32_t feature, bits;
> >  uint32_t offset, size;
> > -uint32_t need_align;
> > +uint32_t need_align, support_xfd;
> 
> why each flag be a 32-bit field?
>
  
  Using the uint32_t to define those flags for below ecx value 
  *ecx = (esa->need_align << 1) | (esa->support_xfd << 2);

 
> also it's more natural to have them in separate lines, though I'm not
> sure why existing fields are put this way (possibly due to short names?).
> 

  Yes, support_xfd flag will be in another line to define, thanks!

  Yang


> >  } ExtSaveArea;
> >
> >  #define XSAVE_STATE_AREA_COUNT (XSTATE_XTILE_DATA_BIT + 1)
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index dd2c919c33..1adc3f0f99 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -5495,7 +5495,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t
> > index, uint32_t count,
> >  const ExtSaveArea *esa = _ext_save_areas[count];
> >  *eax = esa->size;
> >  *ebx = esa->offset;
> > -*ecx = esa->need_align << 1;
> > +*ecx = (esa->need_align << 1) | (esa->support_xfd << 2);
> >  }
> >  }
> >  break;
> > diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
> > index 6c4c1c6f9d..3b3c203f11 100644
> > --- a/target/i386/kvm/kvm-cpu.c
> > +++ b/target/i386/kvm/kvm-cpu.c
> > @@ -108,6 +108,7 @@ static void kvm_cpu_xsave_init(void)
> >
> >  uint32_t ecx = kvm_arch_get_supported_cpuid(s, 0xd, i, R_ECX);
> >  esa->need_align = ecx & (1u << 1) ? 1 : 0;
> > +esa->support_xfd = ecx & (1u << 2) ? 1 : 0;
> >  }
> >  }
> >  }



Re: [RFC PATCH 6/7] x86: Use new XSAVE ioctls handling

2022-01-10 Thread Zeng Guang

On 1/11/2022 10:30 AM, Tian, Kevin wrote:

From: Zeng, Guang 
Sent: Monday, January 10, 2022 5:47 PM

On 1/10/2022 4:40 PM, Tian, Kevin wrote:

From: Zhong, Yang 
Sent: Friday, January 7, 2022 5:32 PM

From: Jing Liu 

Extended feature has large state while current
kvm_xsave only allows 4KB. Use new XSAVE ioctls
if the xstate size is large than kvm_xsave.

shouldn't we always use the new xsave ioctls as long as
CAP_XSAVE2 is available?


CAP_XSAVE2 may return legacy xsave size or 0 working with old kvm
version in which it's not available.
QEMU just use the new xsave ioctls only when the return value of
CAP_XSAVE2 is larger than legacy xsave size.

CAP_XSAVE2  is the superset of CAP_XSAVE. If available it can support
both legacy 4K size or bigger.


Yes. According to the return value of CAP_XSAVE2, further determine 
whether need use new ioctl
KVM_GET_XSAVE2 for extended xsave state. This is the main change to 
support dynamically enabled

feature.


Signed-off-by: Jing Liu 
Signed-off-by: Zeng Guang 
Signed-off-by: Wei Wang 
Signed-off-by: Yang Zhong 
---
   linux-headers/asm-x86/kvm.h | 14 ++
   linux-headers/linux/kvm.h   |  2 ++
   target/i386/cpu.h   |  5 +
   target/i386/kvm/kvm.c   | 16 ++--
   target/i386/xsave_helper.c  | 35

+++

   5 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
index 5a776a08f7..32f2a921e8 100644
--- a/linux-headers/asm-x86/kvm.h
+++ b/linux-headers/asm-x86/kvm.h
@@ -376,6 +376,20 @@ struct kvm_debugregs {
   /* for KVM_CAP_XSAVE */
   struct kvm_xsave {
__u32 region[1024];
+   /*
+* KVM_GET_XSAVE2 and KVM_SET_XSAVE write and read as many
bytes
+* as are returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
+* respectively, when invoked on the vm file descriptor.
+*
+* The size value returned by
KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
+* will always be at least 4096. Currently, it is only greater
+* than 4096 if a dynamic feature has been enabled with
+* ``arch_prctl()``, but this may change in the future.
+*
+* The offsets of the state save areas in struct kvm_xsave follow
+* the contents of CPUID leaf 0xD on the host.
+*/
+   __u32 extra[0];
   };

   #define KVM_MAX_XCRS 16
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 02c5e7b7bb..97d5b6d81d 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1130,6 +1130,7 @@ struct kvm_ppc_resize_hpt {
   #define KVM_CAP_BINARY_STATS_FD 203
   #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
   #define KVM_CAP_ARM_MTE 205
+#define KVM_CAP_XSAVE2  207

   #ifdef KVM_CAP_IRQ_ROUTING

@@ -1550,6 +1551,7 @@ struct kvm_s390_ucas_mapping {
   /* Available with KVM_CAP_XSAVE */
   #define KVM_GET_XSAVE  _IOR(KVMIO,  0xa4, struct
kvm_xsave)
   #define KVM_SET_XSAVE  _IOW(KVMIO,  0xa5, struct
kvm_xsave)
+#define KVM_GET_XSAVE2   _IOR(KVMIO,  0xcf, struct
kvm_xsave)
   /* Available with KVM_CAP_XCRS */
   #define KVM_GET_XCRS   _IOR(KVMIO,  0xa6, struct kvm_xcrs)
   #define KVM_SET_XCRS   _IOW(KVMIO,  0xa7, struct kvm_xcrs)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 245e8b5a1a..6153c4ab1a 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1519,6 +1519,11 @@ typedef struct CPUX86State {
   YMMReg zmmh_regs[CPU_NB_REGS];
   ZMMReg hi16_zmm_regs[CPU_NB_REGS];

+#ifdef TARGET_X86_64
+uint8_t xtilecfg[64];
+uint8_t xtiledata[8192];
+#endif
+
   /* sysenter registers */
   uint32_t sysenter_cs;
   target_ulong sysenter_esp;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 3fb3ddbe2b..97520e9dff 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1983,7 +1983,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
   }

   if (has_xsave) {
-env->xsave_buf_len = sizeof(struct kvm_xsave);
+uint32_t size = kvm_vm_check_extension(cs->kvm_state,
KVM_CAP_XSAVE2);
+if (!size) {
+size = sizeof(struct kvm_xsave);
+}
+
+env->xsave_buf_len = QEMU_ALIGN_UP(size, 4096);
   env->xsave_buf = qemu_memalign(4096, env->xsave_buf_len);
   memset(env->xsave_buf, 0, env->xsave_buf_len);

@@ -2580,6 +2585,7 @@ static int kvm_put_xsave(X86CPU *cpu)
   if (!has_xsave) {
   return kvm_put_fpu(cpu);
   }
+
   x86_cpu_xsave_all_areas(cpu, xsave, env->xsave_buf_len);

   return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
@@ -3247,10 +3253,16 @@ static int kvm_get_xsave(X86CPU *cpu)
   return kvm_get_fpu(cpu);
   }

-ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_XSAVE, xsave);
+if (env->xsave_buf_len <= sizeof(struct kvm_xsave)) {
+ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_XSAVE, xsave);
+} else {
+ret = kvm_vcpu_ioctl(CPU(cpu), 

[PATCH v4 4/7] target/riscv: rvk: add implementation of instructions for Zk*

2022-01-10 Thread Weiwei Li
Co-authored-by: Ruibo Lu 
Co-authored-by: Zewen Ye 
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/crypto_helper.c| 446 ++
 target/riscv/helper.h   |  37 ++
 target/riscv/insn32.decode  |  42 +++
 target/riscv/insn_trans/trans_rvk.c.inc | 467 
 target/riscv/meson.build|   3 +-
 target/riscv/translate.c|   1 +
 6 files changed, 995 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/crypto_helper.c
 create mode 100644 target/riscv/insn_trans/trans_rvk.c.inc

diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
new file mode 100644
index 00..344eea4287
--- /dev/null
+++ b/target/riscv/crypto_helper.c
@@ -0,0 +1,446 @@
+/*
+ * RISC-V Crypto Emulation Helpers for QEMU.
+ *
+ * Copyright (c) 2021 Ruibo Lu, luruibo2...@163.com
+ * Copyright (c) 2021 Zewen Ye, lust...@foxmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "crypto/aes.h"
+#include "crypto/sm4.h"
+
+#define AES_XTIME(a) \
+((a << 1) ^ ((a & 0x80) ? 0x1b : 0))
+
+#define AES_GFMUL(a, b) (( \
+(((b) & 0x1) ?  (a)   : 0) ^ \
+(((b) & 0x2) ? AES_XTIME(a)   : 0) ^ \
+(((b) & 0x4) ?   AES_XTIME(AES_XTIME(a))  : 0) ^ \
+(((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF)
+
+#define BY(X, I) ((X >> (8 * I)) & 0xFF)
+
+#define AES_SHIFROWS_LO(RS1, RS2) ( \
+(((RS1 >> 24) & 0xFF) << 56) | \
+(((RS2 >> 48) & 0xFF) << 48) | \
+(((RS2 >>  8) & 0xFF) << 40) | \
+(((RS1 >> 32) & 0xFF) << 32) | \
+(((RS2 >> 56) & 0xFF) << 24) | \
+(((RS2 >> 16) & 0xFF) << 16) | \
+(((RS1 >> 40) & 0xFF) <<  8) | \
+(((RS1 >>  0) & 0xFF) <<  0))
+
+#define AES_INVSHIFROWS_LO(RS1, RS2) ( \
+(((RS2 >> 24) & 0xFF) << 56) | \
+(((RS2 >> 48) & 0xFF) << 48) | \
+(((RS1 >>  8) & 0xFF) << 40) | \
+(((RS1 >> 32) & 0xFF) << 32) | \
+(((RS1 >> 56) & 0xFF) << 24) | \
+(((RS2 >> 16) & 0xFF) << 16) | \
+(((RS2 >> 40) & 0xFF) <<  8) | \
+(((RS1 >>  0) & 0xFF) <<  0))
+
+#define AES_MIXBYTE(COL, B0, B1, B2, B3) ( \
+  BY(COL, B3) ^ \
+  BY(COL, B2) ^ \
+AES_GFMUL(BY(COL, B1), 3) ^ \
+AES_GFMUL(BY(COL, B0), 2)   \
+)
+
+#define AES_MIXCOLUMN(COL) ( \
+AES_MIXBYTE(COL, 3, 0, 1, 2) << 24 | \
+AES_MIXBYTE(COL, 2, 3, 0, 1) << 16 | \
+AES_MIXBYTE(COL, 1, 2, 3, 0) <<  8 | \
+AES_MIXBYTE(COL, 0, 1, 2, 3) <<  0   \
+)
+
+#define AES_INVMIXBYTE(COL, B0, B1, B2, B3) ( \
+AES_GFMUL(BY(COL, B3), 0x9) ^ \
+AES_GFMUL(BY(COL, B2), 0xd) ^ \
+AES_GFMUL(BY(COL, B1), 0xb) ^ \
+AES_GFMUL(BY(COL, B0), 0xe)   \
+)
+
+#define AES_INVMIXCOLUMN(COL) ( \
+AES_INVMIXBYTE(COL, 3, 0, 1, 2) << 24 | \
+AES_INVMIXBYTE(COL, 2, 3, 0, 1) << 16 | \
+AES_INVMIXBYTE(COL, 1, 2, 3, 0) <<  8 | \
+AES_INVMIXBYTE(COL, 0, 1, 2, 3) <<  0   \
+)
+
+static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd)
+{
+uint32_t u;
+if (fwd) {
+u = (AES_GFMUL(x, 3) << 24) |
+  (x << 16) |
+  (x <<  8) |
+(AES_GFMUL(x, 2) <<  0);
+} else {
+u = (AES_GFMUL(x, 0xb) << 24) |
+(AES_GFMUL(x, 0xd) << 16) |
+(AES_GFMUL(x, 0x9) <<  8) |
+(AES_GFMUL(x, 0xe) <<  0);
+}
+return u;
+}
+
+#define XLEN (8 * sizeof(target_ulong))
+#define zext32(x) ((uint64_t)(uint32_t)(x))
+#define sext_xlen(x) (target_ulong)(int32_t)(x)
+
+static inline target_ulong aes32_operation(target_ulong bs, target_ulong rs1,
+   target_ulong rs2, bool enc,
+   bool mix)
+{
+uint8_t shamt = bs << 3;
+uint8_t si = rs2 >> shamt;
+uint8_t so;
+uint32_t mixed;
+if (enc) {
+so = AES_sbox[si];
+if (mix) {
+mixed = aes_mixcolumn_byte(so, true);
+} else {
+mixed = so;
+}
+
+} else {
+so = AES_isbox[si];
+if (mix) {
+mixed = aes_mixcolumn_byte(so, false);
+} else {
+mixed = so;
+}
+}
+mixed = (mixed << shamt) | (mixed >> (32 - shamt));
+target_ulong 

[PATCH v4 6/7] disas/riscv.c: rvk: add disas support for Zbk* and Zk* instructions

2022-01-10 Thread Weiwei Li
Co-authored-by: Ruibo Lu 
Co-authored-by: Zewen Ye 
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 disas/riscv.c | 170 ++
 1 file changed, 170 insertions(+)

diff --git a/disas/riscv.c b/disas/riscv.c
index 03c8dc9961..44a2c16a0b 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -156,6 +156,8 @@ typedef enum {
 rv_codec_css_swsp,
 rv_codec_css_sdsp,
 rv_codec_css_sqsp,
+rv_codec_k_bs,
+rv_codec_k_rnum,
 } rv_codec;
 
 typedef enum {
@@ -521,6 +523,43 @@ typedef enum {
 rv_op_bclr = 359,
 rv_op_binv = 360,
 rv_op_bext = 361,
+rv_op_aes32esmi = 362,
+rv_op_aes32esi = 363,
+rv_op_aes32dsmi = 364,
+rv_op_aes32dsi = 365,
+rv_op_aes64ks1i = 366,
+rv_op_aes64ks2 = 367,
+rv_op_aes64im = 368,
+rv_op_aes64esm = 369,
+rv_op_aes64es = 370,
+rv_op_aes64dsm = 371,
+rv_op_aes64ds = 372,
+rv_op_sha256sig0 = 373,
+rv_op_sha256sig1 = 374,
+rv_op_sha256sum0 = 375,
+rv_op_sha256sum1 = 376,
+rv_op_sha512sig0 = 377,
+rv_op_sha512sig1 = 378,
+rv_op_sha512sum0 = 379,
+rv_op_sha512sum1 = 380,
+rv_op_sha512sum0r = 381,
+rv_op_sha512sum1r = 382,
+rv_op_sha512sig0l = 383,
+rv_op_sha512sig0h = 384,
+rv_op_sha512sig1l = 385,
+rv_op_sha512sig1h = 386,
+rv_op_sm3p0 = 387,
+rv_op_sm3p1 = 388,
+rv_op_sm4ed = 389,
+rv_op_sm4ks = 390,
+rv_op_brev8 = 391,
+rv_op_pack = 392,
+rv_op_packh = 393,
+rv_op_packw = 394,
+rv_op_unzip = 395,
+rv_op_zip = 396,
+rv_op_xperm4 = 397,
+rv_op_xperm8 = 398,
 } rv_op;
 
 /* structures */
@@ -540,6 +579,8 @@ typedef struct {
 uint8_t   succ;
 uint8_t   aq;
 uint8_t   rl;
+uint8_t   bs;
+uint8_t   rnum;
 } rv_decode;
 
 typedef struct {
@@ -615,6 +656,8 @@ static const char rv_freg_name_sym[32][5] = {
 #define rv_fmt_rd_rs2 "O\t0,2"
 #define rv_fmt_rs1_offset "O\t1,o"
 #define rv_fmt_rs2_offset "O\t2,o"
+#define rv_fmt_rs1_rs2_bs "O\t1,2,b"
+#define rv_fmt_rd_rs1_rnum"O\t0,1,n"
 
 /* pseudo-instruction constraints */
 
@@ -766,6 +809,7 @@ static const rv_comp_data rvcp_csrrw[] = {
 { rv_op_illegal, NULL }
 };
 
+
 static const rv_comp_data rvcp_csrrs[] = {
 { rv_op_rdcycle, rvcc_rdcycle },
 { rv_op_rdtime, rvcc_rdtime },
@@ -1203,6 +1247,43 @@ const rv_opcode_data opcode_data[] = {
 { "bclr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 { "binv", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
 { "bext", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "aes32esmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
+{ "aes32esi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
+{ "aes32dsmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
+{ "aes32dsi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
+{ "aes64ks1i", rv_codec_k_rnum,  rv_fmt_rd_rs1_rnum, NULL, 0, 0, 0 },
+{ "aes64ks2", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "aes64im", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+{ "aes64esm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "aes64es", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "aes64dsm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "aes64ds", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha256sig0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+{ "sha256sig1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+{ "sha256sum0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+{ "sha256sum1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+{ "sha512sig0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sig1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sum0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sum1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sum0r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sum1r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sig0l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sig0h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sig1l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sha512sig1h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sm3p0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+{ "sm3p1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 },
+{ "sm4ed", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
+{ "sm4ks", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 },
+{ "brev8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+{ "pack", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "packh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "packw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "unzip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+{ "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+{ "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, 

[PATCH v4 3/7] crypto include/crypto target/arm: move sm4_sbox to crypto

2022-01-10 Thread Weiwei Li
   - share it between target/arm and target/riscv

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Philippe Mathieu-Daudé 
---
 crypto/meson.build |  1 +
 crypto/sm4.c   | 49 ++
 include/crypto/sm4.h   |  6 +
 target/arm/crypto_helper.c | 36 +---
 4 files changed, 57 insertions(+), 35 deletions(-)
 create mode 100644 crypto/sm4.c
 create mode 100644 include/crypto/sm4.h

diff --git a/crypto/meson.build b/crypto/meson.build
index 95a6a83504..f659fc9035 100644
--- a/crypto/meson.build
+++ b/crypto/meson.build
@@ -38,6 +38,7 @@ crypto_ss.add(when: 'CONFIG_SECRET_KEYRING', if_true: 
files('secret_keyring.c'))
 crypto_ss.add(when: 'CONFIG_AF_ALG', if_true: files('afalg.c', 
'cipher-afalg.c', 'hash-afalg.c'))
 crypto_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c'))
 
+util_ss.add(files('sm4.c'))
 util_ss.add(files('aes.c'))
 util_ss.add(files('init.c'))
 if gnutls.found()
diff --git a/crypto/sm4.c b/crypto/sm4.c
new file mode 100644
index 00..9f0cd452c7
--- /dev/null
+++ b/crypto/sm4.c
@@ -0,0 +1,49 @@
+/*
+ * QEMU crypto sm4 support
+ *
+ * Copyright (C) 2013 - 2018 Linaro Ltd 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "crypto/sm4.h"
+
+uint8_t const sm4_sbox[] = {
+0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
+0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
+0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
+0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
+0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
+0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
+0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
+0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
+0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
+0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
+0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
+0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
+0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
+0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
+0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
+0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
+0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
+0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
+0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
+0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
+0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
+0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
+0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
+0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
+0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
+0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
+0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
+0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
+0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
+0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
+0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
+0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
+};
+
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
new file mode 100644
index 00..9bd3ebc62e
--- /dev/null
+++ b/include/crypto/sm4.h
@@ -0,0 +1,6 @@
+#ifndef QEMU_SM4_H
+#define QEMU_SM4_H
+
+extern const uint8_t sm4_sbox[256];
+
+#endif
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
index 28a84c2dbd..390020672a 100644
--- a/target/arm/crypto_helper.c
+++ b/target/arm/crypto_helper.c
@@ -15,6 +15,7 @@
 #include "exec/helper-proto.h"
 #include "tcg/tcg-gvec-desc.h"
 #include "crypto/aes.h"
+#include "crypto/sm4.h"
 #include "vec_internal.h"
 
 union CRYPTO_STATE {
@@ -694,41 +695,6 @@ DO_SM3TT(crypto_sm3tt2b, 3)
 
 #undef DO_SM3TT
 
-static uint8_t const sm4_sbox[] = {
-0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
-0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
-0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
-0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
-0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
-0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
-0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
-0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
-0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
-0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
-0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
-0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
-0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
-0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
-0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
-0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
-0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
-0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
-0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,

[PATCH v4 2/7] target/riscv: rvk: add implementation of instructions for Zbk*

2022-01-10 Thread Weiwei Li
   - reuse partial instructions of Zbb/Zbc extensions
   - add brev8, packh, unzip, zip, etc.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/bitmanip_helper.c  |  74 ++
 target/riscv/helper.h   |   5 +
 target/riscv/insn32.decode  |  52 ++
 target/riscv/insn_trans/trans_rvb.c.inc | 127 +---
 target/riscv/translate.c|   7 ++
 5 files changed, 234 insertions(+), 31 deletions(-)

diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
index f1b5e5549f..dc3dcf685a 100644
--- a/target/riscv/bitmanip_helper.c
+++ b/target/riscv/bitmanip_helper.c
@@ -49,3 +49,77 @@ target_ulong HELPER(clmulr)(target_ulong rs1, target_ulong 
rs2)
 
 return result;
 }
+
+static inline target_ulong do_swap(target_ulong x, uint64_t mask, int shift)
+{
+return ((x & mask) << shift) | ((x & ~mask) >> shift);
+}
+
+target_ulong HELPER(brev8)(target_ulong rs1)
+{
+target_ulong x = rs1;
+x = do_swap(x, 0xull, 1);
+x = do_swap(x, 0xull, 2);
+x = do_swap(x, 0x0f0f0f0f0f0f0f0full, 4);
+return x;
+}
+
+static inline target_ulong do_xperm(target_ulong rs1, target_ulong rs2,
+uint32_t sz_log2)
+{
+target_ulong r = 0;
+target_ulong sz = 1LL << sz_log2;
+target_ulong mask = (1LL << sz) - 1;
+for (int i = 0; i < TARGET_LONG_BITS; i += sz) {
+target_ulong pos = ((rs2 >> i) & mask) << sz_log2;
+if (pos < sizeof(target_ulong) * 8) {
+r |= ((rs1 >> pos) & mask) << i;
+}
+}
+return r;
+}
+
+target_ulong HELPER(xperm4)(target_ulong rs1, target_ulong rs2)
+{
+return do_xperm(rs1, rs2, 2);
+}
+
+target_ulong HELPER(xperm8)(target_ulong rs1, target_ulong rs2)
+{
+return do_xperm(rs1, rs2, 3);
+}
+
+static const uint64_t shuf_masks[] = {
+dup_const(MO_8, 0x44),
+dup_const(MO_8, 0x30),
+dup_const(MO_16, 0x0f00),
+dup_const(MO_32, 0xff)
+};
+
+static inline target_ulong do_shuf_stage(target_ulong src, uint64_t maskL,
+ uint64_t maskR, int shift)
+{
+target_ulong x = src & ~(maskL | maskR);
+x |= ((src << shift) & maskL) | ((src >> shift) & maskR);
+return x;
+}
+
+target_ulong HELPER(unzip)(target_ulong rs1)
+{
+target_ulong x = rs1;
+x = do_shuf_stage(x, shuf_masks[0], shuf_masks[0] >> 1, 1);
+x = do_shuf_stage(x, shuf_masks[1], shuf_masks[1] >> 2, 2);
+x = do_shuf_stage(x, shuf_masks[2], shuf_masks[2] >> 4, 4);
+x = do_shuf_stage(x, shuf_masks[3], shuf_masks[3] >> 8, 8);
+return x;
+}
+
+target_ulong HELPER(zip)(target_ulong rs1)
+{
+target_ulong x = rs1;
+x = do_shuf_stage(x, shuf_masks[3], shuf_masks[3] >> 8, 8);
+x = do_shuf_stage(x, shuf_masks[2], shuf_masks[2] >> 4, 4);
+x = do_shuf_stage(x, shuf_masks[1], shuf_masks[1] >> 2, 2);
+x = do_shuf_stage(x, shuf_masks[0], shuf_masks[0] >> 1, 1);
+return x;
+}
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6cf6d6ce98..2bd6ac8280 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -66,6 +66,11 @@ DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
 /* Bitmanip */
 DEF_HELPER_FLAGS_2(clmul, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 DEF_HELPER_FLAGS_2(clmulr, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(xperm4, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(xperm8, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_1(brev8, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_1(unzip, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_1(zip, TCG_CALL_NO_RWG_SE, tl, tl)
 
 /* Floating Point - Half Precision */
 DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 5bbedc254c..7491b2d562 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -717,8 +717,22 @@ sh2add_uw  001 .. 100 . 0111011 @r
 sh3add_uw  001 .. 110 . 0111011 @r
 slli_uw1  001 . 0011011 @sh
 
-# *** RV32 Zbb Standard Extension ***
+# *** RV32 Zbb/Zbkb Standard Extension ***
 andn   010 .. 111 . 0110011 @r
+rol011 .. 001 . 0110011 @r
+ror011 .. 101 . 0110011 @r
+rori   01100  101 . 0010011 @sh
+# The encoding for rev8 differs between RV32 and RV64.
+# rev8_32 denotes the RV32 variant.
+rev8_32011010 011000 . 101 . 0010011 @r2
+# The encoding for zext.h differs between RV32 and RV64.
+# zext_h_32 denotes the RV32 variant.
+{
+  zext_h_32  100 0 . 100 . 0110011 @r2
+  pack   100 . . 100 . 0110011 @r
+}
+xnor   010 .. 100 . 0110011 @r
+# *** RV32 extra Zbb Standard Extension ***
 clz011000 00 . 001 . 0010011 @r2
 cpop   011000 10 . 001 . 0010011 @r2
 ctz  

[PATCH v4 0/7] support subsets of scalar crypto extension

2022-01-10 Thread Weiwei Li
This patchset implements RISC-V scalar crypto extension v1.0.0 version 
instructions. 
Partial instructions are reused from B-extension.

Specification:
https://github.com/riscv/riscv-crypto

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-k-upstream-v4

To test rvk implementation,  specify cpu argument with 'zks=true,zkn=true'  
or 
"zbkb=true,zbkc=true,zbkx=true,zknd=true,zkne=true,zknh=true,zksed=true,zksh=true,zkr=true"
 to enable  K-extension support.  This implementation can pass the ACT tests 
for K with our extended act support for qemu (available at 
https://github.com/plctlab/plct-qemu/tree/plct-k-upstream-v4-with-act)

v4:
* drop "x-" in exposed properties
* delete unrelated changes

v3:
* add extension check for SEED csr access

v2:
* optimize implementation for brev8, xperm, zip, unzip
* use aes related sbox array from crypto/aes.h
* move sm4_sbox to crypto/sm4.c, and share it with target/arm

Weiwei Li (7):
  target/riscv: rvk: add cfg properties for zbk* and zk*
  target/riscv: rvk: add implementation of instructions for Zbk*
  crypto include/crypto target/arm: move sm4_sbox to crypto
  target/riscv: rvk: add implementation of instructions for Zk*
  target/riscv: rvk: add CSR support for Zkr
  disas/riscv.c: rvk: add disas support for Zbk* and Zk* instructions
  target/riscv: rvk: expose zbk* and zk* properties

 crypto/meson.build  |   1 +
 crypto/sm4.c|  49 +++
 disas/riscv.c   | 170 +
 include/crypto/sm4.h|   6 +
 target/arm/crypto_helper.c  |  36 +-
 target/riscv/bitmanip_helper.c  |  74 
 target/riscv/cpu.c  |  37 ++
 target/riscv/cpu.h  |  13 +
 target/riscv/cpu_bits.h |   9 +
 target/riscv/crypto_helper.c| 446 ++
 target/riscv/csr.c  |  74 
 target/riscv/helper.h   |  42 +++
 target/riscv/insn32.decode  |  94 -
 target/riscv/insn_trans/trans_rvb.c.inc | 127 ++-
 target/riscv/insn_trans/trans_rvk.c.inc | 467 
 target/riscv/meson.build|   3 +-
 target/riscv/pmp.h  |   8 +-
 target/riscv/translate.c|   8 +
 18 files changed, 1594 insertions(+), 70 deletions(-)
 create mode 100644 crypto/sm4.c
 create mode 100644 include/crypto/sm4.h
 create mode 100644 target/riscv/crypto_helper.c
 create mode 100644 target/riscv/insn_trans/trans_rvk.c.inc

-- 
2.17.1




[PATCH v4 7/7] target/riscv: rvk: expose zbk* and zk* properties

2022-01-10 Thread Weiwei Li
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b487a8282c..628a782ba9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -694,9 +694,23 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
 DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
 DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),
+DEFINE_PROP_BOOL("zbkb", RISCVCPU, cfg.ext_zbkb, false),
+DEFINE_PROP_BOOL("zbkc", RISCVCPU, cfg.ext_zbkc, false),
+DEFINE_PROP_BOOL("zbkx", RISCVCPU, cfg.ext_zbkx, false),
 DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true),
+DEFINE_PROP_BOOL("zk", RISCVCPU, cfg.ext_zk, false),
+DEFINE_PROP_BOOL("zkn", RISCVCPU, cfg.ext_zkn, false),
+DEFINE_PROP_BOOL("zknd", RISCVCPU, cfg.ext_zknd, false),
+DEFINE_PROP_BOOL("zkne", RISCVCPU, cfg.ext_zkne, false),
+DEFINE_PROP_BOOL("zknh", RISCVCPU, cfg.ext_zknh, false),
+DEFINE_PROP_BOOL("zkr", RISCVCPU, cfg.ext_zkr, false),
+DEFINE_PROP_BOOL("zks", RISCVCPU, cfg.ext_zks, false),
+DEFINE_PROP_BOOL("zksed", RISCVCPU, cfg.ext_zksed, false),
+DEFINE_PROP_BOOL("zksh", RISCVCPU, cfg.ext_zksh, false),
+DEFINE_PROP_BOOL("zkt", RISCVCPU, cfg.ext_zkt, false),
 
 /* These are experimental so mark with 'x-' */
+DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
-- 
2.17.1




[PATCH v4 5/7] target/riscv: rvk: add CSR support for Zkr

2022-01-10 Thread Weiwei Li
   - add SEED CSR
   - add USEED, SSEED fields for MSECCFG CSR

Co-authored-by: Ruibo Lu 
Co-authored-by: Zewen Ye 
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu_bits.h |  9 +
 target/riscv/csr.c  | 74 +
 target/riscv/pmp.h  |  8 +++--
 3 files changed, 88 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 5a6d49aa64..65c708622b 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -374,6 +374,9 @@
 #define CSR_VSPMMASK0x2c1
 #define CSR_VSPMBASE0x2c2
 
+/* Crypto Extension */
+#define CSR_SEED   0x015
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE 0x0001
 #define MSTATUS_SIE 0x0002
@@ -628,4 +631,10 @@ typedef enum RISCVException {
 #define UMTE_U_PM_INSN  U_PM_INSN
 #define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN)
 
+/* seed CSR bits */
+#define SEED_OPST(0b11 << 30)
+#define SEED_OPST_BIST   (0b00 << 30)
+#define SEED_OPST_WAIT   (0b01 << 30)
+#define SEED_OPST_ES16   (0b10 << 30)
+#define SEED_OPST_DEAD   (0b11 << 30)
 #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index adb3d4381d..9d93e72f68 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -22,6 +22,8 @@
 #include "cpu.h"
 #include "qemu/main-loop.h"
 #include "exec/exec-all.h"
+#include "qemu/guest-random.h"
+#include "qapi/error.h"
 
 /* CSR function table public API */
 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
@@ -222,6 +224,38 @@ static RISCVException epmp(CPURISCVState *env, int csrno)
 }
 #endif
 
+/* Predicates */
+static RISCVException seed(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+if (!cpu->cfg.ext_zkr) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+#if !defined(CONFIG_USER_ONLY)
+if (riscv_has_ext(env, RVS) && riscv_has_ext(env, RVH)) {
+/* Hypervisor extension is supported */
+if (riscv_cpu_virt_enabled(env) && (env->priv != PRV_M)) {
+if (env->mseccfg & MSECCFG_SSEED) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+} else {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+}
+if (env->priv == PRV_M) {
+return RISCV_EXCP_NONE;
+} else if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) {
+return RISCV_EXCP_NONE;
+} else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) {
+return RISCV_EXCP_NONE;
+} else {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+#else
+return RISCV_EXCP_NONE;
+#endif
+}
+
 /* User Floating-Point CSRs */
 static RISCVException read_fflags(CPURISCVState *env, int csrno,
   target_ulong *val)
@@ -1785,6 +1819,39 @@ static RISCVException write_upmbase(CPURISCVState *env, 
int csrno,
 
 #endif
 
+/* Crypto Extension */
+static int read_seed(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = 0;
+uint32_t return_status =  SEED_OPST_ES16;
+*val = (*val) | return_status;
+if (return_status == SEED_OPST_ES16) {
+uint16_t random_number;
+Error *err = NULL;
+if (qemu_guest_getrandom(_number, sizeof(random_number),
+ ) < 0) {
+qemu_log_mask(LOG_UNIMP, "Seed: Crypto failure: %s",
+  error_get_pretty(err));
+error_free(err);
+return -1;
+}
+*val = (*val) | random_number;
+} else if (return_status == SEED_OPST_BIST) {
+/* Do nothing */
+} else if (return_status == SEED_OPST_WAIT) {
+/* Do nothing */
+} else if (return_status == SEED_OPST_DEAD) {
+/* Do nothing */
+}
+return 0;
+}
+
+static RISCVException write_seed(CPURISCVState *env, int csrno,
+target_ulong val)
+{
+return RISCV_EXCP_NONE;
+}
+
 /*
  * riscv_csrrw - read and/or update control and status register
  *
@@ -1823,6 +1890,10 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+if (!write_mask && (csrno == CSR_SEED)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
 /* ensure the CSR extension is enabled. */
 if (!cpu->cfg.ext_icsr) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -2011,6 +2082,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_TIME]  = { "time",  ctr,   read_time  },
 [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
 
+/* Crypto Extension */
+[CSR_SEED] = { "seed", seed, read_seed, write_seed},
+
 #if !defined(CONFIG_USER_ONLY)
 /* Machine Timers and Counters */
 [CSR_MCYCLE]= { "mcycle",any,   read_instret  },
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index a9a0b363a7..83135849bb 100644
--- a/target/riscv/pmp.h
+++ 

[PATCH v4 1/7] target/riscv: rvk: add cfg properties for zbk* and zk*

2022-01-10 Thread Weiwei Li
Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Acked-by: Alistair Francis 
---
 target/riscv/cpu.c | 23 +++
 target/riscv/cpu.h | 13 +
 2 files changed, 36 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9bc25d3055..b487a8282c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -518,6 +518,29 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 cpu->cfg.ext_d = true;
 }
 
+if (cpu->cfg.ext_zk) {
+cpu->cfg.ext_zkn = true;
+cpu->cfg.ext_zkr = true;
+cpu->cfg.ext_zkt = true;
+}
+
+if (cpu->cfg.ext_zkn) {
+cpu->cfg.ext_zbkb = true;
+cpu->cfg.ext_zbkc = true;
+cpu->cfg.ext_zbkx = true;
+cpu->cfg.ext_zkne = true;
+cpu->cfg.ext_zknd = true;
+cpu->cfg.ext_zknh = true;
+}
+
+if (cpu->cfg.ext_zks) {
+cpu->cfg.ext_zbkb = true;
+cpu->cfg.ext_zbkc = true;
+cpu->cfg.ext_zbkx = true;
+cpu->cfg.ext_zksed = true;
+cpu->cfg.ext_zksh = true;
+}
+
 /* Set the ISA extensions, checks should have happened above */
 if (cpu->cfg.ext_i) {
 ext |= RVI;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4d63086765..2c14fe8ed9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -323,7 +323,20 @@ struct RISCVCPU {
 bool ext_zba;
 bool ext_zbb;
 bool ext_zbc;
+bool ext_zbkb;
+bool ext_zbkc;
+bool ext_zbkx;
 bool ext_zbs;
+bool ext_zk;
+bool ext_zkn;
+bool ext_zknd;
+bool ext_zkne;
+bool ext_zknh;
+bool ext_zkr;
+bool ext_zks;
+bool ext_zksed;
+bool ext_zksh;
+bool ext_zkt;
 bool ext_counters;
 bool ext_ifencei;
 bool ext_icsr;
-- 
2.17.1




Re: [PATCH v2 19/37] console: save current scanout details

2022-01-10 Thread Akihiko Odaki

Hi,

I found this brings an inconsistency and a flaw to scanout semantics and 
think the inconsistency should be fixed or this should be reverted 
before the next release comes up.


The inconsistency is in the handling of the console size. A guest 
hardware (especially I'm looking at virtio-gpu-virgl) tells the size 
change with qemu_console_resize. It causes the replacement of the 
surface, and the host display sees the change of the size via the 
surface. The replacement of the surface does *not* mean the surface 
should be scanned out; if an OpenGL texture is already provided, the 
host display should scan out it, not the replaced surface. 
dpy_gl_scanout_disable will be called when the surface becomes the 
source of the scanouts.


However, this change brings some contradicting behaviors.
- qemu_console_get_width and qemu_console_get_height now relies on the 
texture size as the source of the console size while the resize is 
delivered via the surface.
- dpy_gfx_replace_surface makes the surface as the source of the 
scanouts while its guest hardware semantics does not mean that.
- dpy_gl_scanout_disable sets the scanout kind to SCANOUT_NONE while it 
actually means the surface is now the source of the scanout.


Besides that, displaychangelistener_display_console has a flaw that it 
does not tell the switch to a console with SCANOUT_NONE. The intention 
of SCANOUT_NONE is not entirely clear.


I think there are two options to fix the problem except reverting:
- Rework this change to make it consistent with the existing semantics.
- Remove the use of qemu_console_resize and dpy_gl_scanout_disable from
  hardwares providing OpenGL textures or DMA-BUF to make it consistent
  with the new semantics.

Regards,
Akihiko Odaki

On 2021/10/10 6:08, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

Add a new DisplayScanout structure to save the current scanout details.
This allows to attach later UI backends and set the scanout.

Introduce displaychangelistener_display_console() helper function to
handle the dpy_gfx_switch/gl_scanout() & dpy_gfx_update() calls.

Signed-off-by: Marc-André Lureau 
---
  include/ui/console.h |  27 +++
  ui/console.c | 165 +--
  2 files changed, 138 insertions(+), 54 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index b23ae283be..ab55d71894 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -108,6 +108,17 @@ struct QemuConsoleClass {
  #define QEMU_ALLOCATED_FLAG 0x01
  #define QEMU_PLACEHOLDER_FLAG   0x02
  
+typedef struct ScanoutTexture {

+uint32_t backing_id;
+bool backing_y_0_top;
+uint32_t backing_width;
+uint32_t backing_height;
+uint32_t x;
+uint32_t y;
+uint32_t width;
+uint32_t height;
+} ScanoutTexture;
+
  typedef struct DisplaySurface {
  pixman_format_code_t format;
  pixman_image_t *image;
@@ -173,6 +184,22 @@ typedef struct QemuDmaBuf {
  bool  allow_fences;
  } QemuDmaBuf;
  
+enum display_scanout {

+SCANOUT_NONE,
+SCANOUT_SURFACE,
+SCANOUT_TEXTURE,
+SCANOUT_DMABUF,
+};
+
+typedef struct DisplayScanout {
+enum display_scanout kind;
+union {
+/* DisplaySurface *surface; is kept in QemuConsole */
+ScanoutTexture texture;
+QemuDmaBuf *dmabuf;
+};
+} DisplayScanout;
+
  typedef struct DisplayState DisplayState;
  typedef struct DisplayGLCtx DisplayGLCtx;
  
diff --git a/ui/console.c b/ui/console.c

index e5a2c84dd9..a1c6a78523 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -126,6 +126,7 @@ struct QemuConsole {
  console_type_t console_type;
  DisplayState *ds;
  DisplaySurface *surface;
+DisplayScanout scanout;
  int dcls;
  DisplayGLCtx *gl;
  int gl_block;
@@ -197,6 +198,7 @@ static void dpy_refresh(DisplayState *s);
  static DisplayState *get_alloc_displaystate(void);
  static void text_console_update_cursor_timer(void);
  static void text_console_update_cursor(void *opaque);
+static bool displaychangelistener_has_dmabuf(DisplayChangeListener *dcl);
  
  static void gui_update(void *opaque)

  {
@@ -532,6 +534,8 @@ static void text_console_resize(QemuConsole *s)
  TextCell *cells, *c, *c1;
  int w1, x, y, last_width;
  
+assert(s->scanout.kind == SCANOUT_SURFACE);

+
  last_width = s->width;
  s->width = surface_width(s->surface) / FONT_WIDTH;
  s->height = surface_height(s->surface) / FONT_HEIGHT;
@@ -1103,6 +1107,48 @@ static void console_putchar(QemuConsole *s, int ch)
  }
  }
  
+static void displaychangelistener_display_console(DisplayChangeListener *dcl,

+  QemuConsole *con)
+{
+static const char nodev[] =
+"This VM has no graphic display device.";
+static DisplaySurface *dummy;
+
+if (!con) {
+if (!dcl->ops->dpy_gfx_switch) {
+return;
+}
+if (!dummy) {
+dummy = 

[PATCH] softmmu/device_tree: Remove redundant pointer assignment

2022-01-10 Thread Yanan Wang via
The pointer assignment "const char *p = path;" in function
qemu_fdt_add_path is unnecessary. Let's remove it and just
use the "path" passed in. No functional change.

Suggested-by: Richard Henderson 
Signed-off-by: Yanan Wang 
---
Based on: softmmu/device_tree: Silence compiler warning with --enable-sanitizers
https://patchew.org/QEMU/20220107133844.145039-1-th...@redhat.com/
---
 softmmu/device_tree.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
index 9e96f5ecd5..8897c79ea4 100644
--- a/softmmu/device_tree.c
+++ b/softmmu/device_tree.c
@@ -556,7 +556,6 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
 int qemu_fdt_add_path(void *fdt, const char *path)
 {
 const char *name;
-const char *p = path;
 int namelen, retval;
 int parent = 0;
 
@@ -565,9 +564,9 @@ int qemu_fdt_add_path(void *fdt, const char *path)
 }
 
 do {
-name = p + 1;
-p = strchr(name, '/');
-namelen = p != NULL ? p - name : strlen(name);
+name = path + 1;
+path = strchr(name, '/');
+namelen = path != NULL ? path - name : strlen(name);
 
 retval = fdt_subnode_offset_namelen(fdt, parent, name, namelen);
 if (retval < 0 && retval != -FDT_ERR_NOTFOUND) {
@@ -584,7 +583,7 @@ int qemu_fdt_add_path(void *fdt, const char *path)
 }
 
 parent = retval;
-} while (p);
+} while (path);
 
 return retval;
 }
-- 
2.27.0




Re: [RFC PATCH 1/7] x86: Fix the 64-byte boundary enumeration for extended state

2022-01-10 Thread Yang Zhong
On Mon, Jan 10, 2022 at 04:20:41PM +0800, Tian, Kevin wrote:
> > From: Zhong, Yang 
> > Sent: Friday, January 7, 2022 5:31 PM
> >
> > From: Jing Liu 
> >
> > The extended state subleaves (EAX=0Dh, ECX=n, n>1).ECX[1]
> > are all zero, while spec actually introduces that bit 01
> > should indicate if the extended state component locates
> > on the next 64-byte boundary following the preceding state
> > component when the compacted format of an XSAVE area is
> > used.
> 
> Above would read clearer if you revise to:
> 
> "The extended state subleaves (EAX=0Dh, ECX=n, n>1).ECX[1]
> indicate whether the extended state component locates
> on the next 64-byte boundary following the preceding state
> component when the compacted format of an XSAVE area is
> used.
> 
> But ECX[1] is always cleared in current implementation."

  Thanks Kevin, I will update this in next version.

  Yang




Re: [RFC PATCH 2/7] x86: Add AMX XTILECFG and XTILEDATA components

2022-01-10 Thread Yang Zhong
On Mon, Jan 10, 2022 at 04:23:47PM +0800, Tian, Kevin wrote:
> > From: Zhong, Yang 
> > Sent: Friday, January 7, 2022 5:31 PM
> >
> > From: Jing Liu 
> >
> > AMX XTILECFG and XTILEDATA are managed by XSAVE feature
> > set. State component 17 is used for 64-byte TILECFG register
> > (XTILECFG state) and component 18 is used for 8192 bytes
> > of tile data (XTILEDATA state).
> 
> to be consistent, "tile data" -> "TILEDATA"
> 
> >
> > Add AMX feature bits to x86_ext_save_areas array to set
> > up AMX components. Add structs that define the layout of
> > AMX XSAVE areas and use QEMU_BUILD_BUG_ON to validate the
> > structs sizes.
> >
> > Signed-off-by: Jing Liu 
> > Signed-off-by: Yang Zhong 
> > ---
> >  target/i386/cpu.h | 16 +++-
> >  target/i386/cpu.c |  8 
> >  2 files changed, 23 insertions(+), 1 deletion(-)
> >
> > diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> > index 7f9700544f..768a8218be 100644
> > --- a/target/i386/cpu.h
> > +++ b/target/i386/cpu.h
> > @@ -537,6 +537,8 @@ typedef enum X86Seg {
> >  #define XSTATE_ZMM_Hi256_BIT6
> >  #define XSTATE_Hi16_ZMM_BIT 7
> >  #define XSTATE_PKRU_BIT 9
> > +#define XSTATE_XTILE_CFG_BIT17
> > +#define XSTATE_XTILE_DATA_BIT   18
> >
> >  #define XSTATE_FP_MASK  (1ULL << XSTATE_FP_BIT)
> >  #define XSTATE_SSE_MASK (1ULL << XSTATE_SSE_BIT)
> > @@ -1343,6 +1345,16 @@ typedef struct XSavePKRU {
> >  uint32_t padding;
> >  } XSavePKRU;
> >
> > +/* Ext. save area 17: AMX XTILECFG state */
> > +typedef struct XSaveXTILE_CFG {
> 
> remove "_"?
> 
> > +uint8_t xtilecfg[64];
> > +} XSaveXTILE_CFG;
> > +
> > +/* Ext. save area 18: AMX XTILEDATA state */
> > +typedef struct XSaveXTILE_DATA {
> 
> ditto
>

  Thanks Kevin, I will update this in new version.

  Yang 



Re: [PATCH 6/8] target/ppc: 405: Machine check exception cleanup

2022-01-10 Thread David Gibson
On Mon, Jan 10, 2022 at 03:15:44PM -0300, Fabiano Rosas wrote:
> powerpc_excp_40x applies only to the 405, so remove HV code and
> references to BookE.
> 
> Signed-off-by: Fabiano Rosas 

Reviewed-by: David Gibson 

> ---
>  target/ppc/excp_helper.c | 26 ++
>  1 file changed, 2 insertions(+), 24 deletions(-)
> 
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index fecf4d5a4e..82ade5d7bd 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -449,34 +449,12 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  cs->halted = 1;
>  cpu_interrupt_exittb(cs);
>  }
> -if (env->msr_mask & MSR_HVB) {
> -/*
> - * ISA specifies HV, but can be delivered to guest with HV
> - * clear (e.g., see FWNMI in PAPR).
> - */
> -new_msr |= (target_ulong)MSR_HVB;
> -}
>  
>  /* machine check exceptions don't have ME set */
>  new_msr &= ~((target_ulong)1 << MSR_ME);
>  
> -/* XXX: should also have something loaded in DAR / DSISR */
> -switch (excp_model) {
> -case POWERPC_EXCP_40x:
> -srr0 = SPR_40x_SRR2;
> -srr1 = SPR_40x_SRR3;
> -break;
> -case POWERPC_EXCP_BOOKE:
> -/* FIXME: choose one or the other based on CPU type */
> -srr0 = SPR_BOOKE_MCSRR0;
> -srr1 = SPR_BOOKE_MCSRR1;
> -
> -env->spr[SPR_BOOKE_CSRR0] = env->nip;
> -env->spr[SPR_BOOKE_CSRR1] = msr;
> -break;
> -default:
> -break;
> -}
> +srr0 = SPR_40x_SRR2;
> +srr1 = SPR_40x_SRR3;
>  break;
>  case POWERPC_EXCP_DSI:   /* Data storage exception   
> */
>  trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]);

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


signature.asc
Description: PGP signature


Re: [PATCH 7/8] target/ppc: 405: External exception cleanup

2022-01-10 Thread David Gibson
On Mon, Jan 10, 2022 at 03:15:45PM -0300, Fabiano Rosas wrote:
> 405 has no MSR_HV and EPR is BookE only so we can remove it all.
> 
> Signed-off-by: Fabiano Rosas 

Reviewed-by: David Gibson 

> ---
>  target/ppc/excp_helper.c | 37 -
>  1 file changed, 37 deletions(-)
> 
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 82ade5d7bd..f7b9af5065 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -464,44 +464,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  msr |= env->error_code;
>  break;
>  case POWERPC_EXCP_EXTERNAL:  /* External input   
> */
> -{
> -bool lpes0;
> -
> -cs = CPU(cpu);
> -
> -/*
> - * Exception targeting modifiers
> - *
> - * LPES0 is supported on POWER7/8/9
> - * LPES1 is not supported (old iSeries mode)
> - *
> - * On anything else, we behave as if LPES0 is 1
> - * (externals don't alter MSR:HV)
> - */
> -#if defined(TARGET_PPC64)
> -if (excp_model == POWERPC_EXCP_POWER7 ||
> -excp_model == POWERPC_EXCP_POWER8 ||
> -excp_model == POWERPC_EXCP_POWER9 ||
> -excp_model == POWERPC_EXCP_POWER10) {
> -lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
> -} else
> -#endif /* defined(TARGET_PPC64) */
> -{
> -lpes0 = true;
> -}
> -
> -if (!lpes0) {
> -new_msr |= (target_ulong)MSR_HVB;
> -new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> -srr0 = SPR_HSRR0;
> -srr1 = SPR_HSRR1;
> -}
> -if (env->mpic_proxy) {
> -/* IACK the IRQ on delivery */
> -env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
> -}
>  break;
> -}
>  case POWERPC_EXCP_ALIGN: /* Alignment exception  
> */
>  /* Get rS/rD and rA from faulting opcode */
>  /*

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


signature.asc
Description: PGP signature


Re: [PATCH 3/8] target/ppc: Introduce powerpc_excp_40x

2022-01-10 Thread David Gibson
On Mon, Jan 10, 2022 at 03:15:41PM -0300, Fabiano Rosas wrote:
> Signed-off-by: Fabiano Rosas 
> ---
> I copied powerpc_excp_legacy verbatim in this commit so the next
> one has a clean diff. We can squash both commits before merging.

I think copying it verbatim then simplifying is a good idea, even for
the final version, but the commit messages would need to be updated a
bit.  I'd suggest:

 * "Introduce powerpc_excp_40x" with a message saying it's just a copy
   of the legacy function for now

then

 * "Simplify "powerpc_excp_40x", where you cut out the non-405 stuff

> ---
>  target/ppc/excp_helper.c | 474 +++
>  1 file changed, 474 insertions(+)
> 
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index bc646c67a0..12ab5e1b34 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -392,6 +392,477 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu,
>  check_tlb_flush(env, false);
>  }
>  
> +static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
> +{
> +CPUState *cs = CPU(cpu);
> +CPUPPCState *env = >env;
> +int excp_model = env->excp_model;
> +target_ulong msr, new_msr, vector;
> +int srr0, srr1, lev = -1;
> +
> +if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
> +cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
> +}
> +
> +qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
> +  " => %s (%d) error=%02x\n", env->nip, 
> powerpc_excp_name(excp),
> +  excp, env->error_code);
> +
> +/* new srr1 value excluding must-be-zero bits */
> +if (excp_model == POWERPC_EXCP_BOOKE) {
> +msr = env->msr;
> +} else {
> +msr = env->msr & ~0x783fULL;
> +}
> +
> +/*
> + * new interrupt handler msr preserves existing HV and ME unless
> + * explicitly overriden
> + */
> +new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
> +
> +/* target registers */
> +srr0 = SPR_SRR0;
> +srr1 = SPR_SRR1;
> +
> +/*
> + * check for special resume at 0x100 from doze/nap/sleep/winkle on
> + * P7/P8/P9
> + */
> +if (env->resume_as_sreset) {
> +excp = powerpc_reset_wakeup(cs, env, excp, );
> +}
> +
> +/*
> + * Hypervisor emulation assistance interrupt only exists on server
> + * arch 2.05 server or later. We also don't want to generate it if
> + * we don't have HVB in msr_mask (PAPR mode).
> + */
> +if (excp == POWERPC_EXCP_HV_EMU
> +#if defined(TARGET_PPC64)
> +&& !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB))
> +#endif /* defined(TARGET_PPC64) */
> +
> +) {
> +excp = POWERPC_EXCP_PROGRAM;
> +}
> +
> +#ifdef TARGET_PPC64
> +/*
> + * SPEU and VPU share the same IVOR but they exist in different
> + * processors. SPEU is e500v1/2 only and VPU is e6500 only.
> + */
> +if (excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) {
> +excp = POWERPC_EXCP_SPEU;
> +}
> +#endif
> +
> +vector = env->excp_vectors[excp];
> +if (vector == (target_ulong)-1ULL) {
> +cpu_abort(cs, "Raised an exception without defined vector %d\n",
> +  excp);
> +}
> +
> +vector |= env->excp_prefix;
> +
> +switch (excp) {
> +case POWERPC_EXCP_CRITICAL:/* Critical input 
> */
> +switch (excp_model) {
> +case POWERPC_EXCP_40x:
> +srr0 = SPR_40x_SRR2;
> +srr1 = SPR_40x_SRR3;
> +break;
> +case POWERPC_EXCP_BOOKE:
> +srr0 = SPR_BOOKE_CSRR0;
> +srr1 = SPR_BOOKE_CSRR1;
> +break;
> +case POWERPC_EXCP_G2:
> +break;
> +default:
> +goto excp_invalid;
> +}
> +break;
> +case POWERPC_EXCP_MCHECK:/* Machine check exception  
> */
> +if (msr_me == 0) {
> +/*
> + * Machine check exception is not enabled.  Enter
> + * checkstop state.
> + */
> +fprintf(stderr, "Machine check while not allowed. "
> +"Entering checkstop state\n");
> +if (qemu_log_separate()) {
> +qemu_log("Machine check while not allowed. "
> +"Entering checkstop state\n");
> +}
> +cs->halted = 1;
> +cpu_interrupt_exittb(cs);
> +}
> +if (env->msr_mask & MSR_HVB) {
> +/*
> + * ISA specifies HV, but can be delivered to guest with HV
> + * clear (e.g., see FWNMI in PAPR).
> + */
> +new_msr |= (target_ulong)MSR_HVB;
> +}
> +
> +/* machine check exceptions don't have ME set */
> +new_msr &= ~((target_ulong)1 << MSR_ME);
> +
> +/* XXX: should also have something loaded in DAR / DSISR */
> +switch 

Re: [PATCH 2/8] target/ppc: 405: Add missing exception handlers

2022-01-10 Thread David Gibson
On Mon, Jan 10, 2022 at 03:15:40PM -0300, Fabiano Rosas wrote:
> Signed-off-by: Fabiano Rosas 
> ---
>  target/ppc/cpu_init.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index a50ddaeaae..9097948e67 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -1951,7 +1951,9 @@ static void init_excp_4xx_softmmu(CPUPPCState *env)
>  env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x0500;
>  env->excp_vectors[POWERPC_EXCP_ALIGN]= 0x0600;
>  env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x0700;
> +env->excp_vectors[POWERPC_EXCP_FPU]  = 0x0800;

I have a vague recollection from my days of working on 405 that there
may have been something funky with FP emulation on there: e.g. FP
instructions causing 0x700 program interrupts instead of FP unavailble
interrupts or something.

I might be remembering incorrectly - the manual does seem to imply
that 0x800 FP unavailable is there as normal, but it might be worth
double checking this (against real hardware, if possible).

>  env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x0C00;
> +env->excp_vectors[POWERPC_EXCP_APU]  = 0x0F20;
>  env->excp_vectors[POWERPC_EXCP_PIT]  = 0x1000;
>  env->excp_vectors[POWERPC_EXCP_FIT]  = 0x1010;
>  env->excp_vectors[POWERPC_EXCP_WDT]  = 0x1020;

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


signature.asc
Description: PGP signature


Re: [PATCH 1/8] target/ppc: 405: Add missing MSR bits to msr_mask

2022-01-10 Thread David Gibson
On Mon, Jan 10, 2022 at 03:15:39PM -0300, Fabiano Rosas wrote:
> Some bits described in the user manual are missing from msr_mask. Add
> them.
> 
> Signed-off-by: Fabiano Rosas 
> ---
>  target/ppc/cpu_init.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index e30e86fe9d..a50ddaeaae 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -2535,15 +2535,19 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
> PPC_MEM_SYNC | PPC_MEM_EIEIO |
> PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
> PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
> -pcc->msr_mask = (1ull << MSR_POW) |
> +pcc->msr_mask = (1ull << MSR_AP) |
> +(1ull << MSR_POW) |

If I'm looking at things correctly, the "MSR_POW" bit on 405 is
actually called "MSR_WE", which appears related, but not quite
identical.  I think it would be good to introduce a new define to get
it a name matching the user manual.

>  (1ull << MSR_CE) |
>  (1ull << MSR_EE) |
>  (1ull << MSR_PR) |
>  (1ull << MSR_FP) |
> +(1ull << MSR_ME) |
>  (1ull << MSR_DWE) |
>  (1ull << MSR_DE) |
> +(1ull << MSR_FE1) |
>  (1ull << MSR_IR) |
>  (1ull << MSR_DR);
> +
>  pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
>  pcc->excp_model = POWERPC_EXCP_40x;
>  pcc->bus_model = PPC_FLAGS_INPUT_405;

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


signature.asc
Description: PGP signature


Re: [PATCH 5/8] target/ppc: 405: Critical exceptions cleanup

2022-01-10 Thread David Gibson
On Mon, Jan 10, 2022 at 03:15:43PM -0300, Fabiano Rosas wrote:
> In powerpc_excp_40x the Critical exception is now for 405 only, so we
> can remove the BookE and G2 blocks.
> 
> Signed-off-by: Fabiano Rosas 

Reviewed-by: David Gibson 

> ---
>  target/ppc/excp_helper.c | 17 ++---
>  1 file changed, 2 insertions(+), 15 deletions(-)
> 
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 1d997c4d6b..fecf4d5a4e 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -431,20 +431,8 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  
>  switch (excp) {
>  case POWERPC_EXCP_CRITICAL:/* Critical input 
> */
> -switch (excp_model) {
> -case POWERPC_EXCP_40x:
> -srr0 = SPR_40x_SRR2;
> -srr1 = SPR_40x_SRR3;
> -break;
> -case POWERPC_EXCP_BOOKE:
> -srr0 = SPR_BOOKE_CSRR0;
> -srr1 = SPR_BOOKE_CSRR1;
> -break;
> -case POWERPC_EXCP_G2:
> -break;
> -default:
> -goto excp_invalid;
> -}
> +srr0 = SPR_40x_SRR2;
> +srr1 = SPR_40x_SRR3;
>  break;
>  case POWERPC_EXCP_MCHECK:/* Machine check exception  
> */
>  if (msr_me == 0) {
> @@ -698,7 +686,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>powerpc_excp_name(excp));
>  break;
>  default:
> -excp_invalid:
>  cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
>  break;
>  }

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


signature.asc
Description: PGP signature


Re: [PATCH 8/8] target/ppc: 405: System call exception cleanup

2022-01-10 Thread David Gibson
On Mon, Jan 10, 2022 at 03:15:46PM -0300, Fabiano Rosas wrote:
> There's no sc 1.
> 
> We also only used env->nip because of the vhyp code, so change to
> 'vector' now.

I don't think this is right.  The point with the env->nip change is
changing the PC as it appeared *before* saving it to SRR0, so that
we'll eventually return to the right place.  'vector' is the address
for the interrupt vector itself.


> 
> Signed-off-by: Fabiano Rosas 
> ---
>  target/ppc/excp_helper.c | 23 +++
>  1 file changed, 3 insertions(+), 20 deletions(-)
> 
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index f7b9af5065..ab298d0d8f 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -398,7 +398,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  CPUPPCState *env = >env;
>  int excp_model = env->excp_model;
>  target_ulong msr, new_msr, vector;
> -int srr0, srr1, lev = -1;
> +int srr0, srr1;
>  
>  if (excp <= POWERPC_EXCP_NONE || excp >= POWERPC_EXCP_NB) {
>  cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
> @@ -518,30 +518,13 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
>  }
>  break;
>  case POWERPC_EXCP_SYSCALL:   /* System call exception
> */
> -lev = env->error_code;
> -
> -if ((lev == 1) && cpu->vhyp) {
> -dump_hcall(env);
> -} else {
> -dump_syscall(env);
> -}
> +dump_syscall(env);
>  
>  /*
>   * We need to correct the NIP which in this case is supposed
>   * to point to the next instruction
>   */
> -env->nip += 4;
> -
> -/* "PAPR mode" built-in hypercall emulation */
> -if ((lev == 1) && cpu->vhyp) {
> -PPCVirtualHypervisorClass *vhc =
> -PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> -vhc->hypercall(cpu->vhyp, cpu);
> -return;
> -}
> -if (lev == 1) {
> -new_msr |= (target_ulong)MSR_HVB;
> -}
> +vector += 4;
>  break;
>  case POWERPC_EXCP_FPU:   /* Floating-point unavailable exception 
> */
>  case POWERPC_EXCP_APU:   /* Auxiliary processor unavailable  
> */

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


signature.asc
Description: PGP signature


Re: [PATCH 1/8] target/ppc: 405: Add missing MSR bits to msr_mask

2022-01-10 Thread David Gibson
On Tue, Jan 11, 2022 at 01:04:14PM +1100, David Gibson wrote:
> On Mon, Jan 10, 2022 at 03:15:39PM -0300, Fabiano Rosas wrote:
> > Some bits described in the user manual are missing from msr_mask. Add
> > them.
> > 
> > Signed-off-by: Fabiano Rosas 
> > ---
> >  target/ppc/cpu_init.c | 6 +-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> > index e30e86fe9d..a50ddaeaae 100644
> > --- a/target/ppc/cpu_init.c
> > +++ b/target/ppc/cpu_init.c
> > @@ -2535,15 +2535,19 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
> > PPC_MEM_SYNC | PPC_MEM_EIEIO |
> > PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
> > PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
> > -pcc->msr_mask = (1ull << MSR_POW) |
> > +pcc->msr_mask = (1ull << MSR_AP) |
> > +(1ull << MSR_POW) |
> 
> If I'm looking at things correctly, the "MSR_POW" bit on 405 is
> actually called "MSR_WE", which appears related, but not quite
> identical.  I think it would be good to introduce a new define to get
> it a name matching the user manual.

Also, it looks like this is still missing the MSR[APE] bit (in the
same place as the MSR_KEY bit on 603e).

> >  (1ull << MSR_CE) |
> >  (1ull << MSR_EE) |
> >  (1ull << MSR_PR) |
> >  (1ull << MSR_FP) |
> > +(1ull << MSR_ME) |
> >  (1ull << MSR_DWE) |
> >  (1ull << MSR_DE) |
> > +(1ull << MSR_FE1) |
> >  (1ull << MSR_IR) |
> >  (1ull << MSR_DR);
> > +
> >  pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
> >  pcc->excp_model = POWERPC_EXCP_40x;
> >  pcc->bus_model = PPC_FLAGS_INPUT_405;
> 



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


signature.asc
Description: PGP signature


RE: [RFC PATCH 6/7] x86: Use new XSAVE ioctls handling

2022-01-10 Thread Tian, Kevin
> From: Zeng, Guang 
> Sent: Monday, January 10, 2022 5:47 PM
> 
> On 1/10/2022 4:40 PM, Tian, Kevin wrote:
> >> From: Zhong, Yang 
> >> Sent: Friday, January 7, 2022 5:32 PM
> >>
> >> From: Jing Liu 
> >>
> >> Extended feature has large state while current
> >> kvm_xsave only allows 4KB. Use new XSAVE ioctls
> >> if the xstate size is large than kvm_xsave.
> > shouldn't we always use the new xsave ioctls as long as
> > CAP_XSAVE2 is available?
> 
> 
> CAP_XSAVE2 may return legacy xsave size or 0 working with old kvm
> version in which it's not available.
> QEMU just use the new xsave ioctls only when the return value of
> CAP_XSAVE2 is larger than legacy xsave size.

CAP_XSAVE2  is the superset of CAP_XSAVE. If available it can support
both legacy 4K size or bigger.

> 
> >> Signed-off-by: Jing Liu 
> >> Signed-off-by: Zeng Guang 
> >> Signed-off-by: Wei Wang 
> >> Signed-off-by: Yang Zhong 
> >> ---
> >>   linux-headers/asm-x86/kvm.h | 14 ++
> >>   linux-headers/linux/kvm.h   |  2 ++
> >>   target/i386/cpu.h   |  5 +
> >>   target/i386/kvm/kvm.c   | 16 ++--
> >>   target/i386/xsave_helper.c  | 35
> +++
> >>   5 files changed, 70 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
> >> index 5a776a08f7..32f2a921e8 100644
> >> --- a/linux-headers/asm-x86/kvm.h
> >> +++ b/linux-headers/asm-x86/kvm.h
> >> @@ -376,6 +376,20 @@ struct kvm_debugregs {
> >>   /* for KVM_CAP_XSAVE */
> >>   struct kvm_xsave {
> >>__u32 region[1024];
> >> +  /*
> >> +   * KVM_GET_XSAVE2 and KVM_SET_XSAVE write and read as many
> >> bytes
> >> +   * as are returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
> >> +   * respectively, when invoked on the vm file descriptor.
> >> +   *
> >> +   * The size value returned by
> >> KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
> >> +   * will always be at least 4096. Currently, it is only greater
> >> +   * than 4096 if a dynamic feature has been enabled with
> >> +   * ``arch_prctl()``, but this may change in the future.
> >> +   *
> >> +   * The offsets of the state save areas in struct kvm_xsave follow
> >> +   * the contents of CPUID leaf 0xD on the host.
> >> +   */
> >> +  __u32 extra[0];
> >>   };
> >>
> >>   #define KVM_MAX_XCRS 16
> >> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> >> index 02c5e7b7bb..97d5b6d81d 100644
> >> --- a/linux-headers/linux/kvm.h
> >> +++ b/linux-headers/linux/kvm.h
> >> @@ -1130,6 +1130,7 @@ struct kvm_ppc_resize_hpt {
> >>   #define KVM_CAP_BINARY_STATS_FD 203
> >>   #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
> >>   #define KVM_CAP_ARM_MTE 205
> >> +#define KVM_CAP_XSAVE2  207
> >>
> >>   #ifdef KVM_CAP_IRQ_ROUTING
> >>
> >> @@ -1550,6 +1551,7 @@ struct kvm_s390_ucas_mapping {
> >>   /* Available with KVM_CAP_XSAVE */
> >>   #define KVM_GET_XSAVE  _IOR(KVMIO,  0xa4, struct
> >> kvm_xsave)
> >>   #define KVM_SET_XSAVE  _IOW(KVMIO,  0xa5, struct
> >> kvm_xsave)
> >> +#define KVM_GET_XSAVE2  _IOR(KVMIO,  0xcf, struct
> >> kvm_xsave)
> >>   /* Available with KVM_CAP_XCRS */
> >>   #define KVM_GET_XCRS   _IOR(KVMIO,  0xa6, struct kvm_xcrs)
> >>   #define KVM_SET_XCRS   _IOW(KVMIO,  0xa7, struct kvm_xcrs)
> >> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> >> index 245e8b5a1a..6153c4ab1a 100644
> >> --- a/target/i386/cpu.h
> >> +++ b/target/i386/cpu.h
> >> @@ -1519,6 +1519,11 @@ typedef struct CPUX86State {
> >>   YMMReg zmmh_regs[CPU_NB_REGS];
> >>   ZMMReg hi16_zmm_regs[CPU_NB_REGS];
> >>
> >> +#ifdef TARGET_X86_64
> >> +uint8_t xtilecfg[64];
> >> +uint8_t xtiledata[8192];
> >> +#endif
> >> +
> >>   /* sysenter registers */
> >>   uint32_t sysenter_cs;
> >>   target_ulong sysenter_esp;
> >> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
> >> index 3fb3ddbe2b..97520e9dff 100644
> >> --- a/target/i386/kvm/kvm.c
> >> +++ b/target/i386/kvm/kvm.c
> >> @@ -1983,7 +1983,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
> >>   }
> >>
> >>   if (has_xsave) {
> >> -env->xsave_buf_len = sizeof(struct kvm_xsave);
> >> +uint32_t size = kvm_vm_check_extension(cs->kvm_state,
> >> KVM_CAP_XSAVE2);
> >> +if (!size) {
> >> +size = sizeof(struct kvm_xsave);
> >> +}
> >> +
> >> +env->xsave_buf_len = QEMU_ALIGN_UP(size, 4096);
> >>   env->xsave_buf = qemu_memalign(4096, env->xsave_buf_len);
> >>   memset(env->xsave_buf, 0, env->xsave_buf_len);
> >>
> >> @@ -2580,6 +2585,7 @@ static int kvm_put_xsave(X86CPU *cpu)
> >>   if (!has_xsave) {
> >>   return kvm_put_fpu(cpu);
> >>   }
> >> +
> >>   x86_cpu_xsave_all_areas(cpu, xsave, env->xsave_buf_len);
> >>
> >>   return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
> >> @@ -3247,10 +3253,16 @@ static int kvm_get_xsave(X86CPU *cpu)
> >>   return kvm_get_fpu(cpu);
> >>   }
> 

Re: [PULL 00/13] Net patches

2022-01-10 Thread Jason Wang
On Tue, Jan 11, 2022 at 12:49 AM Peter Maydell  wrote:
>
> On Mon, 10 Jan 2022 at 03:40, Jason Wang  wrote:
> >
> > The following changes since commit df722e33d5da26ea8604500ca8f509245a0ea524:
> >
> >   Merge tag 'bsd-user-arm-pull-request' of gitlab.com:bsdimp/qemu into 
> > staging (2022-01-08 09:37:59 -0800)
> >
> > are available in the git repository at:
> >
> >   https://github.com/jasowang/qemu.git tags/net-pull-request
> >
> > for you to fetch changes up to 5136cc6d3b8b74f4fa572f0874656947a401330e:
> >
> >   net/vmnet: update MAINTAINERS list (2022-01-10 11:30:55 +0800)
> >
> > 
> >
> > 
>
> Fails to build on OSX Catalina:
>
> ../../net/vmnet-common.m:165:10: error: use of undeclared identifier
> 'VMNET_SHARING_SERVICE_BUSY'
> case VMNET_SHARING_SERVICE_BUSY:
>  ^
>
> This constant only got added in macOS 11.0. I guess that technically
> our supported-platforms policy only requires us to support 11 (Big Sur)
> and 12 (Monterey) at this point, but it would be nice to still be able
> to build on Catalina (10.15).

Yes, it was only supported by the vmnet framework starting from
Catalyst according to
https://developer.apple.com/documentation/vmnet?language=objc.

>
> (Personally I would like Catalina still to work at least for a little
> while, because my x86 Mac is old enough that it is not supported by
> Big Sur. I'll have to dump it once Apple stops doing security support
> for Catalina, but they haven't done that quite yet.)

Sure, Vladislav please fix this and send a new version.

Thanks

>
> -- PMM
>




Re: [PATCH 0/2] scsi: to fix issue on passing host_status to the guest kernel

2022-01-10 Thread Dongli Zhang
ping?

Thank you very much!

Dongli Zhang

On 12/10/21 6:16 AM, Dongli Zhang wrote:
> This patchset fixes the issue on passing 'host_status' to the guest kernel.
> 
> The 1st patch fixes the erroneous usage of req->host_status.
> 
> The 2nd patch is to pass the SCSI_HOST_ERROR to the guest kernel when the
> req->bus->info->fail() is not implemented. I do not add 'Fixes:' because I
> am not sure if to not pass SCSI_HOST_ERROR was on purpose, especially for
> security reason.
> 
> Thank you very much!
> 
> Dongli Zhang
> 
> 
> 



[PATCH v4 4/5] ppc/pnv: Introduce user creatable pnv-phb4 devices

2022-01-10 Thread Daniel Henrique Barboza
This patch introduces pnv-phb4 user creatable devices that are created
in a similar manner as pnv-phb3 devices, allowing the user to interact
with the PHBs directly instead of creating PCI Express Controllers that
will create a certain amount of PHBs per controller index.

We accomplish this by doing the following:

- add a pnv_phb4_get_stack() helper to retrieve which stack an user
created phb4 would occupy;

- when dealing with an user created pnv-phb4 (detected by checking if
phb->stack is NULL at the start of phb4_realize()), retrieve its stack
and initialize its properties as done in stk_realize();

- use 'defaults_enabled()' in stk_realize() to avoid creating and
initializing a 'stack->phb' qdev that might be overwritten by an user
created pnv-phb4 device.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/pci-host/pnv_phb4.c | 75 +-
 hw/pci-host/pnv_phb4_pec.c |  5 +++
 hw/ppc/pnv.c   |  2 +
 3 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 3ffa8f51e9..10f8d6a919 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1487,15 +1487,86 @@ static void pnv_phb4_instance_init(Object *obj)
 object_initialize_child(obj, "source", >xsrc, TYPE_XIVE_SOURCE);
 }
 
+static PnvPhb4PecStack *pnv_phb4_get_stack(int chip_id, int index,
+   Error **errp)
+{
+PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+PnvChip *chip = pnv_get_chip(pnv, chip_id);
+Pnv9Chip *chip9 = PNV9_CHIP(chip);
+int i, j;
+
+for (i = 0; i < chip->num_pecs; i++) {
+/*
+ * For each PEC, check the amount of stacks it supports
+ * and see if the given phb4 index matches a stack.
+ */
+PnvPhb4PecState *pec = >pecs[i];
+
+for (j = 0; j < pec->num_stacks; j++) {
+if (index == pnv_phb4_pec_get_phb_id(pec, j)) {
+return >stacks[j];
+}
+}
+}
+
+error_setg(errp,
+   "pnv-phb4 chip-id %d index %d didn't match any existing PEC",
+   chip_id, index);
+
+return NULL;
+}
+
 static void pnv_phb4_realize(DeviceState *dev, Error **errp)
 {
 PnvPHB4 *phb = PNV_PHB4(dev);
 PCIHostState *pci = PCI_HOST_BRIDGE(dev);
 XiveSource *xsrc = >xsrc;
+Error *local_err = NULL;
 int nr_irqs;
 char name[32];
 
-assert(phb->stack);
+/* User created PHB */
+if (!phb->stack) {
+PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+PnvChip *chip = pnv_get_chip(pnv, phb->chip_id);
+PnvPhb4PecClass *pecc;
+BusState *s;
+
+if (!chip) {
+error_setg(errp, "invalid chip id: %d", phb->chip_id);
+return;
+}
+
+phb->stack = pnv_phb4_get_stack(phb->chip_id, phb->phb_id,
+_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+/* All other phb properties but 'version' are already set */
+pecc = PNV_PHB4_PEC_GET_CLASS(phb->stack->pec);
+object_property_set_int(OBJECT(phb), "version", pecc->version,
+_fatal);
+
+/*
+ * Assign stack->phb since pnv_phb4_update_regions() uses it
+ * to access the phb.
+ */
+phb->stack->phb = phb;
+
+/*
+ * Reparent user created devices to the chip to build
+ * correctly the device tree.
+ */
+pnv_chip_parent_fixup(chip, OBJECT(phb), phb->phb_id);
+
+s = qdev_get_parent_bus(DEVICE(chip));
+if (!qdev_set_parent_bus(DEVICE(phb), s, _err)) {
+error_propagate(errp, local_err);
+return;
+}
+}
 
 pnv_phb4_XSCOM_init(phb);
 
@@ -1600,7 +1671,7 @@ static void pnv_phb4_class_init(ObjectClass *klass, void 
*data)
 dc->realize = pnv_phb4_realize;
 device_class_set_props(dc, pnv_phb4_properties);
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
-dc->user_creatable  = false;
+dc->user_creatable  = true;
 
 xfc->notify = pnv_phb4_xive_notify;
 }
diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c
index d4c52a5d28..dfd25831d5 100644
--- a/hw/pci-host/pnv_phb4_pec.c
+++ b/hw/pci-host/pnv_phb4_pec.c
@@ -19,6 +19,7 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/ppc/pnv.h"
 #include "hw/qdev-properties.h"
+#include "sysemu/sysemu.h"
 
 #include 
 
@@ -282,6 +283,10 @@ static void pnv_pec_stk_realize(DeviceState *dev, Error 
**errp)
 PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec);
 int phb_id = pnv_phb4_pec_get_phb_id(pec, stack->stack_no);
 
+if (!defaults_enabled()) {
+return;
+}
+
 stack->phb = PNV_PHB4(qdev_new(TYPE_PNV_PHB4));
 
 object_property_set_int(OBJECT(stack->phb), "chip-id", pec->chip_id,
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 

[PATCH v4 5/5] ppc/pnv: turn pnv_phb4_update_regions() into static

2022-01-10 Thread Daniel Henrique Barboza
Its only callers are inside pnv_phb4.c.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/pci-host/pnv_phb4.c | 52 +-
 include/hw/pci-host/pnv_phb4.h |  1 -
 2 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 10f8d6a919..34c43bd0f5 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -868,6 +868,32 @@ static uint64_t pnv_pec_stk_nest_xscom_read(void *opaque, 
hwaddr addr,
 return stack->nest_regs[reg];
 }
 
+static void pnv_phb4_update_regions(PnvPhb4PecStack *stack)
+{
+PnvPHB4 *phb = stack->phb;
+
+/* Unmap first always */
+if (memory_region_is_mapped(>mr_regs)) {
+memory_region_del_subregion(>phbbar, >mr_regs);
+}
+if (memory_region_is_mapped(>xsrc.esb_mmio)) {
+memory_region_del_subregion(>intbar, >xsrc.esb_mmio);
+}
+
+/* Map registers if enabled */
+if (memory_region_is_mapped(>phbbar)) {
+memory_region_add_subregion(>phbbar, 0, >mr_regs);
+}
+
+/* Map ESB if enabled */
+if (memory_region_is_mapped(>intbar)) {
+memory_region_add_subregion(>intbar, 0, >xsrc.esb_mmio);
+}
+
+/* Check/update m32 */
+pnv_phb4_check_all_mbt(phb);
+}
+
 static void pnv_pec_stk_update_map(PnvPhb4PecStack *stack)
 {
 PnvPhb4PecState *pec = stack->pec;
@@ -1797,32 +1823,6 @@ static void pnv_phb4_register_types(void)
 
 type_init(pnv_phb4_register_types);
 
-void pnv_phb4_update_regions(PnvPhb4PecStack *stack)
-{
-PnvPHB4 *phb = stack->phb;
-
-/* Unmap first always */
-if (memory_region_is_mapped(>mr_regs)) {
-memory_region_del_subregion(>phbbar, >mr_regs);
-}
-if (memory_region_is_mapped(>xsrc.esb_mmio)) {
-memory_region_del_subregion(>intbar, >xsrc.esb_mmio);
-}
-
-/* Map registers if enabled */
-if (memory_region_is_mapped(>phbbar)) {
-memory_region_add_subregion(>phbbar, 0, >mr_regs);
-}
-
-/* Map ESB if enabled */
-if (memory_region_is_mapped(>intbar)) {
-memory_region_add_subregion(>intbar, 0, >xsrc.esb_mmio);
-}
-
-/* Check/update m32 */
-pnv_phb4_check_all_mbt(phb);
-}
-
 void pnv_phb4_pic_print_info(PnvPHB4 *phb, Monitor *mon)
 {
 uint32_t offset = phb->regs[PHB_INT_NOTIFY_INDEX >> 3];
diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h
index 82f054cf21..4b7ce8a723 100644
--- a/include/hw/pci-host/pnv_phb4.h
+++ b/include/hw/pci-host/pnv_phb4.h
@@ -131,7 +131,6 @@ struct PnvPHB4 {
 };
 
 void pnv_phb4_pic_print_info(PnvPHB4 *phb, Monitor *mon);
-void pnv_phb4_update_regions(PnvPhb4PecStack *stack);
 int pnv_phb4_pec_get_phb_id(PnvPhb4PecState *pec, int stack_index);
 extern const MemoryRegionOps pnv_phb4_xscom_ops;
 
-- 
2.33.1




[PATCH v4 1/5] ppc/pnv: set phb4 properties in stk_realize()

2022-01-10 Thread Daniel Henrique Barboza
Moving all phb4 properties setup to stk_realize() keeps this logic in
a single place instead of having it scattered between stk_realize() and
pec_realize().

'phb->index' can be retrieved using stack->stack_no and
pnv_phb4_pec_get_phb_id(), deprecating the use of 'phb-id' alias that
was being used for this purpose in pec_realize().

Signed-off-by: Daniel Henrique Barboza 
---
 hw/pci-host/pnv_phb4_pec.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c
index d64310e7db..f8038dff17 100644
--- a/hw/pci-host/pnv_phb4_pec.c
+++ b/hw/pci-host/pnv_phb4_pec.c
@@ -392,10 +392,8 @@ static void pnv_pec_realize(DeviceState *dev, Error **errp)
 for (i = 0; i < pec->num_stacks; i++) {
 PnvPhb4PecStack *stack = >stacks[i];
 Object *stk_obj = OBJECT(stack);
-int phb_id = pnv_phb4_pec_get_phb_id(pec, i);
 
 object_property_set_int(stk_obj, "stack-no", i, _abort);
-object_property_set_int(stk_obj, "phb-id", phb_id, _abort);
 object_property_set_link(stk_obj, "pec", OBJECT(pec), _abort);
 if (!qdev_realize(DEVICE(stk_obj), NULL, errp)) {
 return;
@@ -534,7 +532,6 @@ static void pnv_pec_stk_instance_init(Object *obj)
 PnvPhb4PecStack *stack = PNV_PHB4_PEC_STACK(obj);
 
 object_initialize_child(obj, "phb", >phb, TYPE_PNV_PHB4);
-object_property_add_alias(obj, "phb-id", OBJECT(>phb), "index");
 }
 
 static void pnv_pec_stk_realize(DeviceState *dev, Error **errp)
@@ -543,6 +540,7 @@ static void pnv_pec_stk_realize(DeviceState *dev, Error 
**errp)
 PnvPhb4PecState *pec = stack->pec;
 PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec);
 PnvChip *chip = pec->chip;
+int phb_id = pnv_phb4_pec_get_phb_id(pec, stack->stack_no);
 uint32_t pec_nest_base;
 uint32_t pec_pci_base;
 char name[64];
@@ -570,6 +568,8 @@ static void pnv_pec_stk_realize(DeviceState *dev, Error 
**errp)
 
 object_property_set_int(OBJECT(>phb), "chip-id", pec->chip_id,
 _fatal);
+object_property_set_int(OBJECT(>phb), "index", phb_id,
+_fatal);
 object_property_set_int(OBJECT(>phb), "version", pecc->version,
 _fatal);
 object_property_set_link(OBJECT(>phb), "stack", OBJECT(stack),
-- 
2.33.1




[PATCH v4 0/5] user creatable pnv-phb4 devices

2022-01-10 Thread Daniel Henrique Barboza
Hi,

This new version contains the remaining v3 patches that weren't accepted
yet, which is the case of patches 10, 2 and 3.

There are fewer patches this time due to 2 design changes made: move the
phb property setup to stk_realize() and all XSCOM initialization to
phb4_realize().

As a note/TODO, at the end of this work it became clear that it would be
interesting to rethink what we expect about the PnvPhb4Stack object
in the overall design. The object ended up with no init() and its realize
is used as a glorified setup for its phb, being a no-op if the user runs
with -nodefaults. There might be an opportunity for further cleanups and
simplifications.

changes from v3:
- patches 2, 3, and 10 from v3: accepted
- patch 1:
  * do not create a function to set the properties
  * set all properties in stk_realize()
  * remove the 'phb-id' link during this process instead of using a separated
patch
- patch 2:
  * move all XSCOM init to phb4_realize()
- patch 4:
  * review changes proposed by Cedric in v3
- patch 5 (new):
  * a trivial cleanup following patch 2
- v3 link: https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg01931.html


Daniel Henrique Barboza (5):
  ppc/pnv: set phb4 properties in stk_realize()
  ppc/pnv: move PHB4 XSCOM init to phb4_realize()
  ppc/pnv: turn 'phb' into a pointer in struct PnvPhb4PecStack
  ppc/pnv: Introduce user creatable pnv-phb4 devices
  ppc/pnv: turn pnv_phb4_update_regions() into static

 hw/pci-host/pnv_phb4.c | 431 ++---
 hw/pci-host/pnv_phb4_pec.c | 317 +---
 hw/ppc/pnv.c   |   2 +
 include/hw/pci-host/pnv_phb4.h |   8 +-
 4 files changed, 422 insertions(+), 336 deletions(-)

-- 
2.33.1




[PATCH v4 2/5] ppc/pnv: move PHB4 XSCOM init to phb4_realize()

2022-01-10 Thread Daniel Henrique Barboza
The 'stack->phb_regs_mr' PHB4 passthrough XSCOM initialization relies on
'stack->phb' being not NULL. Moving 'stack->phb_regs_mr' region_init()
and add_subregion() to phb4_realize() time is a natural thing to do
since it's strictly PHB related.

The remaining XSCOM initialization is also related to 'stack->phb' but
in a different manner. For instance, 'stack->nest_regs_mr'
MemoryRegionOps, 'pnv_pec_stk_nest_xscom_ops', uses
pnv_pec_stk_nest_xscom_write() as a write callback. When trying to write
the PEC_NEST_STK_BAR_EN reg, pnv_pec_stk_update_map() is called. Inside
this function, pnv_phb4_update_regions() is called twice. This function
uses 'stack->phb' to manipulate memory regions of the phb.

This is not a problem now but, when enabling user creatable phb4s, a
stack that doesn't have an associated phb (i.e. stack->phb = NULL) it
will cause a SIGINT during boot in pnv_phb4_update_regions().

All this can be avoided if all XSCOM init is moved to phb4_realize(),
when we have certainty about the existence of 'stack->phb'. A lot of
code was moved from pnv_phb4_pec.c to pnv_phb4.c due to static constant
and variables being used but the cleaner logic is worth the trouble.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/pci-host/pnv_phb4.c | 304 +
 hw/pci-host/pnv_phb4_pec.c | 292 ---
 2 files changed, 304 insertions(+), 292 deletions(-)

diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index b7b0091f93..1bd74fd932 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -29,6 +29,10 @@
 qemu_log_mask(LOG_GUEST_ERROR, "phb4[%d:%d]: " fmt "\n",\
   (phb)->chip_id, (phb)->phb_id, ## __VA_ARGS__)
 
+#define phb_pec_error(pec, fmt, ...)\
+qemu_log_mask(LOG_GUEST_ERROR, "phb4_pec[%d:%d]: " fmt "\n",\
+  (pec)->chip_id, (pec)->index, ## __VA_ARGS__)
+
 /*
  * QEMU version of the GETFIELD/SETFIELD macros
  *
@@ -854,6 +858,258 @@ const MemoryRegionOps pnv_phb4_xscom_ops = {
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
+static uint64_t pnv_pec_stk_nest_xscom_read(void *opaque, hwaddr addr,
+unsigned size)
+{
+PnvPhb4PecStack *stack = PNV_PHB4_PEC_STACK(opaque);
+uint32_t reg = addr >> 3;
+
+/* TODO: add list of allowed registers and error out if not */
+return stack->nest_regs[reg];
+}
+
+static void pnv_pec_stk_update_map(PnvPhb4PecStack *stack)
+{
+PnvPhb4PecState *pec = stack->pec;
+MemoryRegion *sysmem = get_system_memory();
+uint64_t bar_en = stack->nest_regs[PEC_NEST_STK_BAR_EN];
+uint64_t bar, mask, size;
+char name[64];
+
+/*
+ * NOTE: This will really not work well if those are remapped
+ * after the PHB has created its sub regions. We could do better
+ * if we had a way to resize regions but we don't really care
+ * that much in practice as the stuff below really only happens
+ * once early during boot
+ */
+
+/* Handle unmaps */
+if (memory_region_is_mapped(>mmbar0) &&
+!(bar_en & PEC_NEST_STK_BAR_EN_MMIO0)) {
+memory_region_del_subregion(sysmem, >mmbar0);
+}
+if (memory_region_is_mapped(>mmbar1) &&
+!(bar_en & PEC_NEST_STK_BAR_EN_MMIO1)) {
+memory_region_del_subregion(sysmem, >mmbar1);
+}
+if (memory_region_is_mapped(>phbbar) &&
+!(bar_en & PEC_NEST_STK_BAR_EN_PHB)) {
+memory_region_del_subregion(sysmem, >phbbar);
+}
+if (memory_region_is_mapped(>intbar) &&
+!(bar_en & PEC_NEST_STK_BAR_EN_INT)) {
+memory_region_del_subregion(sysmem, >intbar);
+}
+
+/* Update PHB */
+pnv_phb4_update_regions(stack);
+
+/* Handle maps */
+if (!memory_region_is_mapped(>mmbar0) &&
+(bar_en & PEC_NEST_STK_BAR_EN_MMIO0)) {
+bar = stack->nest_regs[PEC_NEST_STK_MMIO_BAR0] >> 8;
+mask = stack->nest_regs[PEC_NEST_STK_MMIO_BAR0_MASK];
+size = ((~mask) >> 8) + 1;
+snprintf(name, sizeof(name), "pec-%d.%d-stack-%d-mmio0",
+ pec->chip_id, pec->index, stack->stack_no);
+memory_region_init(>mmbar0, OBJECT(stack), name, size);
+memory_region_add_subregion(sysmem, bar, >mmbar0);
+stack->mmio0_base = bar;
+stack->mmio0_size = size;
+}
+if (!memory_region_is_mapped(>mmbar1) &&
+(bar_en & PEC_NEST_STK_BAR_EN_MMIO1)) {
+bar = stack->nest_regs[PEC_NEST_STK_MMIO_BAR1] >> 8;
+mask = stack->nest_regs[PEC_NEST_STK_MMIO_BAR1_MASK];
+size = ((~mask) >> 8) + 1;
+snprintf(name, sizeof(name), "pec-%d.%d-stack-%d-mmio1",
+ pec->chip_id, pec->index, stack->stack_no);
+memory_region_init(>mmbar1, OBJECT(stack), name, size);
+memory_region_add_subregion(sysmem, bar, >mmbar1);
+stack->mmio1_base = bar;
+stack->mmio1_size = size;
+}
+if 

[PATCH v4 3/5] ppc/pnv: turn 'phb' into a pointer in struct PnvPhb4PecStack

2022-01-10 Thread Daniel Henrique Barboza
At this moment, stack->phb is the plain PnvPHB4 device itself instead of
a pointer to the device. This will present a problem when adding user
creatable devices because we can't deal with this struct and the
realize() callback from the user creatable device.

We can't get rid of this attribute, similar to what we did when enabling
pnv-phb3 user creatable devices, because pnv_phb4_update_regions() needs
to access stack->phb to do its job. This function is called twice in
pnv_pec_stk_update_map(), which is one of the nested xscom write
callbacks (via pnv_pec_stk_nest_xscom_write()). In fact,
pnv_pec_stk_update_map() code comment is explicit about how the order of
the unmap/map operations relates with the PHB subregions.

All of this indicates that this code is tied together in a way that we
either go on a crusade, featuring lots of refactories and redesign and
considerable pain, to decouple stack and phb mapping, or we allow stack
update_map operations to access the associated PHB as it is today even
after introducing pnv-phb4 user devices.

This patch chooses the latter. Instead of getting rid of stack->phb,
turn it into a PHB pointer. This will allow us to assign an user created
PHB to an existing stack later. In this process,
pnv_pec_stk_instance_init() is removed because stack->phb is being
initialized in stk_realize() instead.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/pci-host/pnv_phb4.c |  2 +-
 hw/pci-host/pnv_phb4_pec.c | 20 +++-
 include/hw/pci-host/pnv_phb4.h |  7 +--
 3 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 1bd74fd932..3ffa8f51e9 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1728,7 +1728,7 @@ type_init(pnv_phb4_register_types);
 
 void pnv_phb4_update_regions(PnvPhb4PecStack *stack)
 {
-PnvPHB4 *phb = >phb;
+PnvPHB4 *phb = stack->phb;
 
 /* Unmap first always */
 if (memory_region_is_mapped(>mr_regs)) {
diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c
index bf0fdf33fd..d4c52a5d28 100644
--- a/hw/pci-host/pnv_phb4_pec.c
+++ b/hw/pci-host/pnv_phb4_pec.c
@@ -275,13 +275,6 @@ static const TypeInfo pnv_pec_type_info = {
 }
 };
 
-static void pnv_pec_stk_instance_init(Object *obj)
-{
-PnvPhb4PecStack *stack = PNV_PHB4_PEC_STACK(obj);
-
-object_initialize_child(obj, "phb", >phb, TYPE_PNV_PHB4);
-}
-
 static void pnv_pec_stk_realize(DeviceState *dev, Error **errp)
 {
 PnvPhb4PecStack *stack = PNV_PHB4_PEC_STACK(dev);
@@ -289,15 +282,17 @@ static void pnv_pec_stk_realize(DeviceState *dev, Error 
**errp)
 PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec);
 int phb_id = pnv_phb4_pec_get_phb_id(pec, stack->stack_no);
 
-object_property_set_int(OBJECT(>phb), "chip-id", pec->chip_id,
+stack->phb = PNV_PHB4(qdev_new(TYPE_PNV_PHB4));
+
+object_property_set_int(OBJECT(stack->phb), "chip-id", pec->chip_id,
 _fatal);
-object_property_set_int(OBJECT(>phb), "index", phb_id,
+object_property_set_int(OBJECT(stack->phb), "index", phb_id,
 _fatal);
-object_property_set_int(OBJECT(>phb), "version", pecc->version,
+object_property_set_int(OBJECT(stack->phb), "version", pecc->version,
 _fatal);
-object_property_set_link(OBJECT(>phb), "stack", OBJECT(stack),
+object_property_set_link(OBJECT(stack->phb), "stack", OBJECT(stack),
  _abort);
-if (!sysbus_realize(SYS_BUS_DEVICE(>phb), errp)) {
+if (!sysbus_realize(SYS_BUS_DEVICE(stack->phb), errp)) {
 return;
 }
 }
@@ -324,7 +319,6 @@ static const TypeInfo pnv_pec_stk_type_info = {
 .name  = TYPE_PNV_PHB4_PEC_STACK,
 .parent= TYPE_DEVICE,
 .instance_size = sizeof(PnvPhb4PecStack),
-.instance_init = pnv_pec_stk_instance_init,
 .class_init= pnv_pec_stk_class_init,
 .interfaces= (InterfaceInfo[]) {
 { TYPE_PNV_XSCOM_INTERFACE },
diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h
index 5ee996ebc6..82f054cf21 100644
--- a/include/hw/pci-host/pnv_phb4.h
+++ b/include/hw/pci-host/pnv_phb4.h
@@ -177,8 +177,11 @@ struct PnvPhb4PecStack {
 /* The owner PEC */
 PnvPhb4PecState *pec;
 
-/* The actual PHB */
-PnvPHB4 phb;
+/*
+ * PHB4 pointer. pnv_phb4_update_regions() needs to access
+ * the PHB4 via a PnvPhb4PecStack pointer.
+ */
+PnvPHB4 *phb;
 };
 
 struct PnvPhb4PecState {
-- 
2.33.1




Re: [PATCH v4 06/12] target/riscv: Support start kernel directly by KVM

2022-01-10 Thread Alistair Francis
On Mon, Jan 10, 2022 at 11:52 AM Yifei Jiang via  wrote:
>
> Get kernel and fdt start address in virt.c, and pass them to KVM
> when cpu reset. Add kvm_riscv.h to place riscv specific interface.
>
> In addition, PLIC is created without M-mode PLIC contexts when KVM
> is enabled.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Mingwang Li 
> Reviewed-by: Alistair Francis 
> ---
>  hw/intc/sifive_plic.c| 21 +++---
>  hw/riscv/boot.c  | 16 +++-
>  hw/riscv/virt.c  | 83 
>  include/hw/riscv/boot.h  |  1 +
>  target/riscv/cpu.c   |  8 
>  target/riscv/cpu.h   |  3 ++
>  target/riscv/kvm-stub.c  | 25 
>  target/riscv/kvm.c   | 14 +++
>  target/riscv/kvm_riscv.h | 24 
>  target/riscv/meson.build |  2 +-
>  10 files changed, 164 insertions(+), 33 deletions(-)
>  create mode 100644 target/riscv/kvm-stub.c
>  create mode 100644 target/riscv/kvm_riscv.h
>
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index 877e76877c..58c16881cb 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -30,6 +30,7 @@
>  #include "target/riscv/cpu.h"
>  #include "migration/vmstate.h"
>  #include "hw/irq.h"
> +#include "sysemu/kvm.h"
>
>  #define RISCV_DEBUG_PLIC 0
>
> @@ -533,6 +534,8 @@ DeviceState *sifive_plic_create(hwaddr addr, char 
> *hart_config,
>  {
>  DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
>  int i;
> +SiFivePLICState *plic;
> +int s_count = 0, m_count = 0;
>
>  assert(enable_stride == (enable_stride & -enable_stride));
>  assert(context_stride == (context_stride & -context_stride));
> @@ -550,13 +553,19 @@ DeviceState *sifive_plic_create(hwaddr addr, char 
> *hart_config,
>  sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
>  sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
>
> -for (i = 0; i < num_harts; i++) {
> -CPUState *cpu = qemu_get_cpu(hartid_base + i);
> +plic = SIFIVE_PLIC(dev);
> +for (i = 0; i < plic->num_addrs; i++) {
> +CPUState *cpu = qemu_get_cpu(plic->addr_config[i].hartid);
>
> -qdev_connect_gpio_out(dev, i,
> -  qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
> -qdev_connect_gpio_out(dev, num_harts + i,
> -  qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
> +if (plic->addr_config[i].mode == PLICMode_S) {
> +qdev_connect_gpio_out(dev, s_count++,
> +  qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
> +}
> +
> +if (plic->addr_config[i].mode == PLICMode_M) {
> +qdev_connect_gpio_out(dev, num_harts + m_count++,
> +  qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
> +}
>  }

This PLIC change breaks my 5.11.0 buildroot test case on the SiFive U board

The boot process just hangs at:

[0.542798] usbcore: registered new interface driver usbhid
[0.543021] usbhid: USB HID core driver
[0.544584] NET: Registered protocol family 10
[4.054768] Segment Routing with IPv6
[4.055325] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[4.057956] NET: Registered protocol family 17
[4.059327] 9pnet: Installing 9P2000 support
[4.059787] Key type dns_resolver registered
[4.060515] debug_vm_pgtable: [debug_vm_pgtable ]:
Validating architecture page table helpers
[4.078710] macb 1009.ethernet eth0: PHY
[1009.ethernet-:00] driver [Generic PHY] (irq=POLL)
[4.079454] macb 1009.ethernet eth0: configuring for phy/gmii link mode
[4.087031] macb 1009.ethernet eth0: Link is Up - 1Gbps/Full -
flow control tx
[4.094634] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

Alistair



Re: [PATCH v3 00/31] Python: delete synchronous qemu.qmp package

2022-01-10 Thread John Snow
On Mon, Jan 10, 2022 at 6:29 PM John Snow  wrote:

> Based-on: <20220110232521.1922962-1-js...@redhat.com>
>   (jsnow/python staging branch)
>

Sorry, I goofed. This series accidentally re-includes these patches. You
can ignore the first four patches, or apply directly on top of
origin/master. Sorry for the inconvenience.

--js


> GitLab: https://gitlab.com/jsnow/qemu/-/commits/python-qmp-legacy-switch
> CI: https://gitlab.com/jsnow/qemu/-/pipelines/445163212
>
> Hi, this series is part of an effort to publish the qemu.qmp package on
> PyPI. It is the first of three series to complete this work:
>
> --> (1) Switch the new Async QMP library in to python/qemu/qmp
> (2) Fork python/qemu/qmp out into its own repository,
> with updated GitLab CI/CD targets to build packages.
> (3) Update qemu.git to install qemu.qmp from PyPI,
> and then delete python/qemu/qmp.
>
> This series swaps out qemu.qmp for qemu.aqmp permanently, instead of
> hiding it behind an environment variable toggle. This leaves us with
> just one QMP library to worry about. It also implements the rename of
> "qemu.aqmp" to "qemu.qmp".
>
> I suspect the most potential disruption to iotest and avocado
> maintainers, as those two subsystems rely on the QMP features the
> most. Would appreciate at least an ACK from each of those camps if
> you're willing to give benefit-of-the-doubt on the actual Python code.
>
> V3:
>  - Rebased on top of jsnow/python (For GitLab CI fixes)
>  - Added a new patch 001 to fix a typo Vladimir found.
>  - Tiny change in 006 due to the new patch 001
>  - Reworded subject of patch 007
>  - Changed import statement in patch 013 (Vladimir)
>  - Rebase-related changes in patch 021
>  - Removed 'aqmp' from internal variable names in 026
>  - Added new patch to rename aqmp-tui to qmp-tui in 027
>
> V2:
>  - Integrate the renaming of qemu.aqmp to qemu.qmp in this series
>  - Minor bits and pieces.
>
> John Snow (30):
>   python/aqmp: use absolute import statement
>   Python/aqmp: fix type definitions for mypy 0.920
>   python: update type hints for mypy 0.930
>   python/aqmp: fix docstring typo
>   python/aqmp: add __del__ method to legacy interface
>   python/aqmp: handle asyncio.TimeoutError on execute()
>   python/aqmp: copy type definitions from qmp
>   python/aqmp: add SocketAddrT to package root
>   python/aqmp: rename AQMPError to QMPError
>   python/qemu-ga-client: don't use deprecated CLI syntax in usage
> comment
>   python/qmp: switch qemu-ga-client to AQMP
>   python/qmp: switch qom tools to AQMP
>   python/qmp: switch qmp-shell to AQMP
>   python: move qmp utilities to python/qemu/utils
>   python: move qmp-shell under the AQMP package
>   python/machine: permanently switch to AQMP
>   scripts/cpu-x86-uarch-abi: fix CLI parsing
>   scripts/cpu-x86-uarch-abi: switch to AQMP
>   scripts/render-block-graph: switch to AQMP
>   scripts/bench-block-job: switch to AQMP
>   iotests/mirror-top-perms: switch to AQMP
>   iotests: switch to AQMP
>   python: temporarily silence pylint duplicate-code warnings
>   python/aqmp: take QMPBadPortError and parse_address from qemu.qmp
>   python/aqmp: fully separate from qmp.QEMUMonitorProtocol
>   python/aqmp: copy qmp docstrings to qemu.aqmp.legacy
>   python: remove the old QMP package
>   python: re-enable pylint duplicate-code warnings
>   python: rename qemu.aqmp to qemu.qmp
>   python: rename 'aqmp-tui' to 'qmp-tui'
>
> Stefan Weil (1):
>   simplebench: Fix Python syntax error (reported by LGTM)
>
>  python/qemu/qmp/README.rst|   9 -
>  python/qemu/aqmp/__init__.py  |  51 --
>  python/qemu/aqmp/legacy.py| 138 --
>  python/qemu/aqmp/py.typed |   0
>  python/qemu/machine/machine.py|  18 +-
>  python/qemu/machine/qtest.py  |   2 +-
>  python/qemu/qmp/__init__.py   | 441 ++
>  python/qemu/{aqmp => qmp}/error.py|  12 +-
>  python/qemu/{aqmp => qmp}/events.py   |   6 +-
>  python/qemu/qmp/legacy.py | 319 +
>  python/qemu/{aqmp => qmp}/message.py  |   0
>  python/qemu/{aqmp => qmp}/models.py   |   0
>  python/qemu/{aqmp => qmp}/protocol.py |  33 +-
>  python/qemu/{aqmp => qmp}/qmp_client.py   |  32 +-
>  python/qemu/qmp/qmp_shell.py  |  31 +-
>  .../qemu/{aqmp/aqmp_tui.py => qmp/qmp_tui.py} |  14 +-
>  python/qemu/{aqmp => qmp}/util.py |   0
>  python/qemu/{qmp => utils}/qemu_ga_client.py  |  24 +-
>  python/qemu/{qmp => utils}/qom.py |   5 +-
>  python/qemu/{qmp => utils}/qom_common.py  |   9 +-
>  python/qemu/{qmp => utils}/qom_fuse.py|  11 +-
>  python/setup.cfg  |  23 +-
>  python/tests/protocol.py  |  14 +-
>  scripts/cpu-x86-uarch-abi.py  |   7 +-
>  scripts/device-crash-test |   4 +-
>  

[PATCH v3 28/31] python: remove the old QMP package

2022-01-10 Thread John Snow
Thank you for your service!

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/PACKAGE.rst  |   4 +-
 python/README.rst   |   2 +-
 python/qemu/qmp/README.rst  |   9 -
 python/qemu/qmp/__init__.py | 396 
 python/qemu/qmp/py.typed|   0
 python/setup.cfg|   3 +-
 6 files changed, 4 insertions(+), 410 deletions(-)
 delete mode 100644 python/qemu/qmp/README.rst
 delete mode 100644 python/qemu/qmp/__init__.py
 delete mode 100644 python/qemu/qmp/py.typed

diff --git a/python/PACKAGE.rst b/python/PACKAGE.rst
index b0b86cc4c3..ddfa9ba3f5 100644
--- a/python/PACKAGE.rst
+++ b/python/PACKAGE.rst
@@ -8,11 +8,11 @@ to change at any time.
 Usage
 -
 
-The ``qemu.qmp`` subpackage provides a library for communicating with
+The ``qemu.aqmp`` subpackage provides a library for communicating with
 QMP servers. The ``qemu.machine`` subpackage offers rudimentary
 facilities for launching and managing QEMU processes. Refer to each
 package's documentation
-(``>>> help(qemu.qmp)``, ``>>> help(qemu.machine)``)
+(``>>> help(qemu.aqmp)``, ``>>> help(qemu.machine)``)
 for more information.
 
 Contributing
diff --git a/python/README.rst b/python/README.rst
index fcf74f69ea..eb5213337d 100644
--- a/python/README.rst
+++ b/python/README.rst
@@ -3,7 +3,7 @@ QEMU Python Tooling
 
 This directory houses Python tooling used by the QEMU project to build,
 configure, and test QEMU. It is organized by namespace (``qemu``), and
-then by package (e.g. ``qemu/machine``, ``qemu/qmp``, etc).
+then by package (e.g. ``qemu/machine``, ``qemu/aqmp``, etc).
 
 ``setup.py`` is used by ``pip`` to install this tooling to the current
 environment. ``setup.cfg`` provides the packaging configuration used by
diff --git a/python/qemu/qmp/README.rst b/python/qemu/qmp/README.rst
deleted file mode 100644
index 5bfb82535f..00
--- a/python/qemu/qmp/README.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-qemu.qmp package
-
-
-This package provides a library used for connecting to and communicating
-with QMP servers. It is used extensively by iotests, vm tests,
-avocado tests, and other utilities in the ./scripts directory. It is
-not a fully-fledged SDK and is subject to change at any time.
-
-See the documentation in ``__init__.py`` for more information.
diff --git a/python/qemu/qmp/__init__.py b/python/qemu/qmp/__init__.py
deleted file mode 100644
index 4e08641154..00
--- a/python/qemu/qmp/__init__.py
+++ /dev/null
@@ -1,396 +0,0 @@
-"""
-QEMU Monitor Protocol (QMP) development library & tooling.
-
-This package provides a fairly low-level class for communicating to QMP
-protocol servers, as implemented by QEMU, the QEMU Guest Agent, and the
-QEMU Storage Daemon. This library is not intended for production use.
-
-`QEMUMonitorProtocol` is the primary class of interest, and all errors
-raised derive from `QMPError`.
-"""
-
-# Copyright (C) 2009, 2010 Red Hat Inc.
-#
-# Authors:
-#  Luiz Capitulino 
-#
-# This work is licensed under the terms of the GNU GPL, version 2.  See
-# the COPYING file in the top-level directory.
-
-import errno
-import json
-import logging
-import socket
-import struct
-from types import TracebackType
-from typing import (
-Any,
-Dict,
-List,
-Optional,
-TextIO,
-Tuple,
-Type,
-TypeVar,
-Union,
-cast,
-)
-
-
-#: QMPMessage is an entire QMP message of any kind.
-QMPMessage = Dict[str, Any]
-
-#: QMPReturnValue is the 'return' value of a command.
-QMPReturnValue = object
-
-#: QMPObject is any object in a QMP message.
-QMPObject = Dict[str, object]
-
-# QMPMessage can be outgoing commands or incoming events/returns.
-# QMPReturnValue is usually a dict/json object, but due to QAPI's
-# 'returns-whitelist', it can actually be anything.
-#
-# {'return': {}} is a QMPMessage,
-# {} is the QMPReturnValue.
-
-
-InternetAddrT = Tuple[str, int]
-UnixAddrT = str
-SocketAddrT = Union[InternetAddrT, UnixAddrT]
-
-
-class QMPError(Exception):
-"""
-QMP base exception
-"""
-
-
-class QMPConnectError(QMPError):
-"""
-QMP connection exception
-"""
-
-
-class QMPCapabilitiesError(QMPError):
-"""
-QMP negotiate capabilities exception
-"""
-
-
-class QMPTimeoutError(QMPError):
-"""
-QMP timeout exception
-"""
-
-
-class QMPProtocolError(QMPError):
-"""
-QMP protocol error; unexpected response
-"""
-
-
-class QMPResponseError(QMPError):
-"""
-Represents erroneous QMP monitor reply
-"""
-def __init__(self, reply: QMPMessage):
-try:
-desc = reply['error']['desc']
-except KeyError:
-desc = reply
-super().__init__(desc)
-self.reply = reply
-
-
-class QEMUMonitorProtocol:
-"""
-Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP) and then
-allow to handle commands and events.
-"""
-
-#: Logger object for debugging 

[PATCH v3 27/31] python/aqmp: copy qmp docstrings to qemu.aqmp.legacy

2022-01-10 Thread John Snow
Copy the docstrings out of qemu.qmp, adjusting them as necessary to
more accurately reflect the current state of this class.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/qemu/aqmp/legacy.py | 110 ++---
 1 file changed, 102 insertions(+), 8 deletions(-)

diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py
index 8f38e7d912..6c250cd46a 100644
--- a/python/qemu/aqmp/legacy.py
+++ b/python/qemu/aqmp/legacy.py
@@ -1,9 +1,23 @@
 """
-Sync QMP Wrapper
+(Legacy) Sync QMP Wrapper
 
-This class pretends to be qemu.qmp.QEMUMonitorProtocol.
+This module provides the `QEMUMonitorProtocol` class, which is a
+synchronous wrapper around `QMPClient`.
+
+Its design closely resembles that of the original QEMUMonitorProtocol
+class, originally written by Luiz Capitulino.
 """
 
+# Copyright (C) 2009, 2010, 2021 Red Hat Inc.
+#
+# Authors:
+#  Luiz Capitulino 
+#  John Snow 
+#
+# This work is licensed under the terms of the GNU GPL, version 2.
+# See the COPYING file in the top-level directory.
+
+
 import asyncio
 from types import TracebackType
 from typing import (
@@ -39,9 +53,6 @@
 # {} is the QMPReturnValue.
 
 
-# pylint: disable=missing-docstring
-
-
 class QMPBadPortError(QMPError):
 """
 Unable to parse socket address: Port was non-numerical.
@@ -49,6 +60,21 @@ class QMPBadPortError(QMPError):
 
 
 class QEMUMonitorProtocol:
+"""
+Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP)
+and then allow to handle commands and events.
+
+:param address:  QEMU address, can be either a unix socket path (string)
+ or a tuple in the form ( address, port ) for a TCP
+ connection
+:param server:   Deprecated, ignored. (See 'accept')
+:param nickname: Optional nickname used for logging.
+
+..note::
+No connection is established during `__init__`, this is done by
+the `connect()` or `accept()` methods.
+"""
+
 def __init__(self, address: SocketAddrT,
  server: bool = False,  # pylint: disable=unused-argument
  nickname: Optional[str] = None):
@@ -108,6 +134,12 @@ def parse_address(cls, address: str) -> SocketAddrT:
 return address
 
 def connect(self, negotiate: bool = True) -> Optional[QMPMessage]:
+"""
+Connect to the QMP Monitor and perform capabilities negotiation.
+
+:return: QMP greeting dict, or None if negotiate is false
+:raise ConnectError: on connection errors
+"""
 self._aqmp.await_greeting = negotiate
 self._aqmp.negotiate = negotiate
 
@@ -117,6 +149,16 @@ def connect(self, negotiate: bool = True) -> 
Optional[QMPMessage]:
 return self._get_greeting()
 
 def accept(self, timeout: Optional[float] = 15.0) -> QMPMessage:
+"""
+Await connection from QMP Monitor and perform capabilities negotiation.
+
+:param timeout:
+timeout in seconds (nonnegative float number, or None).
+If None, there is no timeout, and this may block forever.
+
+:return: QMP greeting dict
+:raise ConnectError: on connection errors
+"""
 self._aqmp.await_greeting = True
 self._aqmp.negotiate = True
 
@@ -130,6 +172,12 @@ def accept(self, timeout: Optional[float] = 15.0) -> 
QMPMessage:
 return ret
 
 def cmd_obj(self, qmp_cmd: QMPMessage) -> QMPMessage:
+"""
+Send a QMP command to the QMP Monitor.
+
+:param qmp_cmd: QMP command to be sent as a Python dict
+:return: QMP response as a Python dict
+"""
 return dict(
 self._sync(
 # pylint: disable=protected-access
@@ -148,9 +196,9 @@ def cmd(self, name: str,
 """
 Build a QMP command and send it to the QMP Monitor.
 
-@param name: command name (string)
-@param args: command arguments (dict)
-@param cmd_id: command id (dict, list, string or int)
+:param name: command name (string)
+:param args: command arguments (dict)
+:param cmd_id: command id (dict, list, string or int)
 """
 qmp_cmd: QMPMessage = {'execute': name}
 if args:
@@ -160,6 +208,9 @@ def cmd(self, name: str,
 return self.cmd_obj(qmp_cmd)
 
 def command(self, cmd: str, **kwds: object) -> QMPReturnValue:
+"""
+Build and send a QMP command to the monitor, report errors if any
+"""
 return self._sync(
 self._aqmp.execute(cmd, kwds),
 self._timeout
@@ -167,6 +218,19 @@ def command(self, cmd: str, **kwds: object) -> 
QMPReturnValue:
 
 def pull_event(self,
wait: Union[bool, float] = False) -> Optional[QMPMessage]:
+"""
+Pulls a single event.
+
+:param wait:
+If False or 0, do not wait. Return None if no events ready.
+

[PATCH v3 30/31] python: rename qemu.aqmp to qemu.qmp

2022-01-10 Thread John Snow
Now that we are fully switched over to the new QMP library, move it back
over the old namespace. This is being done primarily so that we may
upload this package simply as "qemu.qmp" without introducing confusion
over whether or not "aqmp" is a new protocol or not.

The trade-off is increased confusion inside the QEMU developer
tree. Sorry!

Note: the 'private' member "_aqmp" in legacy.py also changes to "_qmp";
not out of necessity, but just to remove any traces of the "aqmp"
name.

Signed-off-by: John Snow 
---
 python/PACKAGE.rst|  4 +--
 python/README.rst |  4 +--
 python/qemu/machine/machine.py|  4 +--
 python/qemu/machine/qtest.py  |  2 +-
 python/qemu/{aqmp => qmp}/__init__.py |  6 ++--
 python/qemu/{aqmp => qmp}/aqmp_tui.py |  0
 python/qemu/{aqmp => qmp}/error.py|  0
 python/qemu/{aqmp => qmp}/events.py   |  2 +-
 python/qemu/{aqmp => qmp}/legacy.py   | 36 +++
 python/qemu/{aqmp => qmp}/message.py  |  0
 python/qemu/{aqmp => qmp}/models.py   |  0
 python/qemu/{aqmp => qmp}/protocol.py |  4 +--
 python/qemu/{aqmp => qmp}/py.typed|  0
 python/qemu/{aqmp => qmp}/qmp_client.py   | 16 +-
 python/qemu/{aqmp => qmp}/qmp_shell.py|  4 +--
 python/qemu/{aqmp => qmp}/util.py |  0
 python/qemu/utils/qemu_ga_client.py   |  4 +--
 python/qemu/utils/qom.py  |  2 +-
 python/qemu/utils/qom_common.py   |  4 +--
 python/qemu/utils/qom_fuse.py |  2 +-
 python/setup.cfg  |  8 ++---
 python/tests/protocol.py  | 14 -
 scripts/cpu-x86-uarch-abi.py  |  2 +-
 scripts/device-crash-test |  4 +--
 scripts/qmp/qmp-shell |  2 +-
 scripts/render_block_graph.py |  4 +--
 scripts/simplebench/bench_block_job.py|  2 +-
 tests/qemu-iotests/iotests.py |  2 +-
 tests/qemu-iotests/tests/mirror-top-perms |  6 ++--
 29 files changed, 69 insertions(+), 69 deletions(-)
 rename python/qemu/{aqmp => qmp}/__init__.py (87%)
 rename python/qemu/{aqmp => qmp}/aqmp_tui.py (100%)
 rename python/qemu/{aqmp => qmp}/error.py (100%)
 rename python/qemu/{aqmp => qmp}/events.py (99%)
 rename python/qemu/{aqmp => qmp}/legacy.py (92%)
 rename python/qemu/{aqmp => qmp}/message.py (100%)
 rename python/qemu/{aqmp => qmp}/models.py (100%)
 rename python/qemu/{aqmp => qmp}/protocol.py (99%)
 rename python/qemu/{aqmp => qmp}/py.typed (100%)
 rename python/qemu/{aqmp => qmp}/qmp_client.py (97%)
 rename python/qemu/{aqmp => qmp}/qmp_shell.py (99%)
 rename python/qemu/{aqmp => qmp}/util.py (100%)

diff --git a/python/PACKAGE.rst b/python/PACKAGE.rst
index ddfa9ba3f5..b0b86cc4c3 100644
--- a/python/PACKAGE.rst
+++ b/python/PACKAGE.rst
@@ -8,11 +8,11 @@ to change at any time.
 Usage
 -
 
-The ``qemu.aqmp`` subpackage provides a library for communicating with
+The ``qemu.qmp`` subpackage provides a library for communicating with
 QMP servers. The ``qemu.machine`` subpackage offers rudimentary
 facilities for launching and managing QEMU processes. Refer to each
 package's documentation
-(``>>> help(qemu.aqmp)``, ``>>> help(qemu.machine)``)
+(``>>> help(qemu.qmp)``, ``>>> help(qemu.machine)``)
 for more information.
 
 Contributing
diff --git a/python/README.rst b/python/README.rst
index eb5213337d..9c1fceaee7 100644
--- a/python/README.rst
+++ b/python/README.rst
@@ -3,7 +3,7 @@ QEMU Python Tooling
 
 This directory houses Python tooling used by the QEMU project to build,
 configure, and test QEMU. It is organized by namespace (``qemu``), and
-then by package (e.g. ``qemu/machine``, ``qemu/aqmp``, etc).
+then by package (e.g. ``qemu/machine``, ``qemu/qmp``, etc).
 
 ``setup.py`` is used by ``pip`` to install this tooling to the current
 environment. ``setup.cfg`` provides the packaging configuration used by
@@ -59,7 +59,7 @@ Package installation also normally provides executable 
console scripts,
 so that tools like ``qmp-shell`` are always available via $PATH. To
 invoke them without installation, you can invoke e.g.:
 
-``> PYTHONPATH=~/src/qemu/python python3 -m qemu.aqmp.qmp_shell``
+``> PYTHONPATH=~/src/qemu/python python3 -m qemu.qmp.qmp_shell``
 
 The mappings between console script name and python module path can be
 found in ``setup.cfg``.
diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index 21fb4a4f30..6e4bf6520c 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -40,8 +40,8 @@
 TypeVar,
 )
 
-from qemu.aqmp import SocketAddrT
-from qemu.aqmp.legacy import (
+from qemu.qmp import SocketAddrT
+from qemu.qmp.legacy import (
 QEMUMonitorProtocol,
 QMPMessage,
 QMPReturnValue,
diff --git a/python/qemu/machine/qtest.py b/python/qemu/machine/qtest.py
index 13e0aaff84..1a1fc6c9b0 100644
--- a/python/qemu/machine/qtest.py
+++ b/python/qemu/machine/qtest.py
@@ -26,7 +26,7 

[PATCH v3 23/31] iotests: switch to AQMP

2022-01-10 Thread John Snow
Simply import the type defition from the new location.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 tests/qemu-iotests/iotests.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 1e2f2391d1..98bc50cb3a 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -37,7 +37,7 @@
 from contextlib import contextmanager
 
 from qemu.machine import qtest
-from qemu.qmp import QMPMessage
+from qemu.aqmp.legacy import QMPMessage
 
 # Use this logger for logging messages directly from the iotests module
 logger = logging.getLogger('qemu.iotests')
-- 
2.31.1




[PATCH v3 26/31] python/aqmp: fully separate from qmp.QEMUMonitorProtocol

2022-01-10 Thread John Snow
After this patch, qemu.aqmp.legacy.QEMUMonitorProtocol no longer
inherits from qemu.qmp.QEMUMonitorProtocol. To do this, several
inherited methods need to be explicitly re-defined.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/qemu/aqmp/legacy.py | 38 --
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py
index 76b09671cc..8f38e7d912 100644
--- a/python/qemu/aqmp/legacy.py
+++ b/python/qemu/aqmp/legacy.py
@@ -5,18 +5,18 @@
 """
 
 import asyncio
+from types import TracebackType
 from typing import (
 Any,
 Awaitable,
 Dict,
 List,
 Optional,
+Type,
 TypeVar,
 Union,
 )
 
-import qemu.qmp
-
 from .error import QMPError
 from .protocol import Runstate, SocketAddrT
 from .qmp_client import QMPClient
@@ -48,9 +48,9 @@ class QMPBadPortError(QMPError):
 """
 
 
-class QEMUMonitorProtocol(qemu.qmp.QEMUMonitorProtocol):
+class QEMUMonitorProtocol:
 def __init__(self, address: SocketAddrT,
- server: bool = False,
+ server: bool = False,  # pylint: disable=unused-argument
  nickname: Optional[str] = None):
 
 # pylint: disable=super-init-not-called
@@ -74,7 +74,18 @@ def _get_greeting(self) -> Optional[QMPMessage]:
 return self._aqmp.greeting._asdict()
 return None
 
-# __enter__ and __exit__ need no changes
+def __enter__(self: _T) -> _T:
+# Implement context manager enter function.
+return self
+
+def __exit__(self,
+ # pylint: disable=duplicate-code
+ # see https://github.com/PyCQA/pylint/issues/3619
+ exc_type: Optional[Type[BaseException]],
+ exc_val: Optional[BaseException],
+ exc_tb: Optional[TracebackType]) -> None:
+# Implement context manager exit function.
+self.close()
 
 @classmethod
 def parse_address(cls, address: str) -> SocketAddrT:
@@ -131,7 +142,22 @@ def cmd_obj(self, qmp_cmd: QMPMessage) -> QMPMessage:
 )
 )
 
-# Default impl of cmd() delegates to cmd_obj
+def cmd(self, name: str,
+args: Optional[Dict[str, object]] = None,
+cmd_id: Optional[object] = None) -> QMPMessage:
+"""
+Build a QMP command and send it to the QMP Monitor.
+
+@param name: command name (string)
+@param args: command arguments (dict)
+@param cmd_id: command id (dict, list, string or int)
+"""
+qmp_cmd: QMPMessage = {'execute': name}
+if args:
+qmp_cmd['arguments'] = args
+if cmd_id:
+qmp_cmd['id'] = cmd_id
+return self.cmd_obj(qmp_cmd)
 
 def command(self, cmd: str, **kwds: object) -> QMPReturnValue:
 return self._sync(
-- 
2.31.1




[PATCH v3 25/31] python/aqmp: take QMPBadPortError and parse_address from qemu.qmp

2022-01-10 Thread John Snow
Shift these definitions over from the qmp package to the async qmp
package.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/qemu/aqmp/aqmp_tui.py |  3 +--
 python/qemu/aqmp/legacy.py   | 30 ++
 python/qemu/qmp/__init__.py  | 26 --
 3 files changed, 27 insertions(+), 32 deletions(-)

diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py
index f1e926dd75..184a3e4690 100644
--- a/python/qemu/aqmp/aqmp_tui.py
+++ b/python/qemu/aqmp/aqmp_tui.py
@@ -35,9 +35,8 @@
 import urwid
 import urwid_readline
 
-from qemu.qmp import QEMUMonitorProtocol, QMPBadPortError
-
 from .error import ProtocolError
+from .legacy import QEMUMonitorProtocol, QMPBadPortError
 from .message import DeserializationError, Message, UnexpectedTypeError
 from .protocol import ConnectError, Runstate
 from .qmp_client import ExecInterruptedError, QMPClient
diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py
index 0890f95b16..76b09671cc 100644
--- a/python/qemu/aqmp/legacy.py
+++ b/python/qemu/aqmp/legacy.py
@@ -22,9 +22,6 @@
 from .qmp_client import QMPClient
 
 
-# (Temporarily) Re-export QMPBadPortError
-QMPBadPortError = qemu.qmp.QMPBadPortError
-
 #: QMPMessage is an entire QMP message of any kind.
 QMPMessage = Dict[str, Any]
 
@@ -45,6 +42,12 @@
 # pylint: disable=missing-docstring
 
 
+class QMPBadPortError(QMPError):
+"""
+Unable to parse socket address: Port was non-numerical.
+"""
+
+
 class QEMUMonitorProtocol(qemu.qmp.QEMUMonitorProtocol):
 def __init__(self, address: SocketAddrT,
  server: bool = False,
@@ -72,7 +75,26 @@ def _get_greeting(self) -> Optional[QMPMessage]:
 return None
 
 # __enter__ and __exit__ need no changes
-# parse_address needs no changes
+
+@classmethod
+def parse_address(cls, address: str) -> SocketAddrT:
+"""
+Parse a string into a QMP address.
+
+Figure out if the argument is in the port:host form.
+If it's not, it's probably a file path.
+"""
+components = address.split(':')
+if len(components) == 2:
+try:
+port = int(components[1])
+except ValueError:
+msg = f"Bad port: '{components[1]}' in '{address}'."
+raise QMPBadPortError(msg) from None
+return (components[0], port)
+
+# Treat as filepath.
+return address
 
 def connect(self, negotiate: bool = True) -> Optional[QMPMessage]:
 self._aqmp.await_greeting = negotiate
diff --git a/python/qemu/qmp/__init__.py b/python/qemu/qmp/__init__.py
index 358c0971d0..4e08641154 100644
--- a/python/qemu/qmp/__init__.py
+++ b/python/qemu/qmp/__init__.py
@@ -102,12 +102,6 @@ def __init__(self, reply: QMPMessage):
 self.reply = reply
 
 
-class QMPBadPortError(QMPError):
-"""
-Unable to parse socket address: Port was non-numerical.
-"""
-
-
 class QEMUMonitorProtocol:
 """
 Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP) and then
@@ -237,26 +231,6 @@ def __exit__(self,
 # Implement context manager exit function.
 self.close()
 
-@classmethod
-def parse_address(cls, address: str) -> SocketAddrT:
-"""
-Parse a string into a QMP address.
-
-Figure out if the argument is in the port:host form.
-If it's not, it's probably a file path.
-"""
-components = address.split(':')
-if len(components) == 2:
-try:
-port = int(components[1])
-except ValueError:
-msg = f"Bad port: '{components[1]}' in '{address}'."
-raise QMPBadPortError(msg) from None
-return (components[0], port)
-
-# Treat as filepath.
-return address
-
 def connect(self, negotiate: bool = True) -> Optional[QMPMessage]:
 """
 Connect to the QMP Monitor and perform capabilities negotiation.
-- 
2.31.1




[PATCH v3 24/31] python: temporarily silence pylint duplicate-code warnings

2022-01-10 Thread John Snow
The next several commits copy some code from qemu.qmp to qemu.aqmp, then
delete qemu.qmp. In the interim, to prevent test failures, the duplicate
code detection needs to be silenced to prevent bisect problems with CI
testing.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 python/setup.cfg | 1 +
 1 file changed, 1 insertion(+)

diff --git a/python/setup.cfg b/python/setup.cfg
index 168a79c867..510df23698 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -115,6 +115,7 @@ ignore_missing_imports = True
 disable=consider-using-f-string,
 too-many-function-args,  # mypy handles this with less false positives.
 no-member,  # mypy also handles this better.
+duplicate-code,  # To be removed by the end of this patch series.
 
 [pylint.basic]
 # Good variable names which should always be accepted, separated by a comma.
-- 
2.31.1




[PATCH v3 22/31] iotests/mirror-top-perms: switch to AQMP

2022-01-10 Thread John Snow
Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 

---

Note: I still need to adjust the logging. The problem now is that the
logging messages include the PID of the test process, so they need to be
filtered out. I'll investigate that for a follow-up.

I could just add yet another filtering function somewhere, but I think
it's getting out of hand with how many filters and loggers there are, so
I want to give it a slightly more serious treatment instead of a
hackjob.

Signed-off-by: John Snow 
---
 tests/qemu-iotests/tests/mirror-top-perms | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/tests/qemu-iotests/tests/mirror-top-perms 
b/tests/qemu-iotests/tests/mirror-top-perms
index 0a51a613f3..f394931a00 100755
--- a/tests/qemu-iotests/tests/mirror-top-perms
+++ b/tests/qemu-iotests/tests/mirror-top-perms
@@ -23,7 +23,6 @@ import os
 
 from qemu.aqmp import ConnectError
 from qemu.machine import machine
-from qemu.qmp import QMPConnectError
 
 import iotests
 from iotests import change_log_level, qemu_img
@@ -101,13 +100,13 @@ class TestMirrorTopPerms(iotests.QMPTestCase):
 self.vm_b.add_device('virtio-blk,drive=drive0,share-rw=on')
 try:
 # Silence AQMP errors temporarily.
-# TODO: Remove this and just allow the errors to be logged when
-# AQMP fully replaces QMP.
+# TODO: Remove change_log_level and allow the errors to be logged.
+#   This necessitates a PID filter on *all* logging output.
 with change_log_level('qemu.aqmp'):
 self.vm_b.launch()
 print('ERROR: VM B launched successfully, '
   'this should not have happened')
-except (QMPConnectError, ConnectError):
+except ConnectError:
 assert 'Is another process using the image' in self.vm_b.get_log()
 
 result = self.vm.qmp('block-job-cancel',
-- 
2.31.1




[PATCH v3 19/31] scripts/cpu-x86-uarch-abi: switch to AQMP

2022-01-10 Thread John Snow
Signed-off-by: John Snow 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 scripts/cpu-x86-uarch-abi.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/cpu-x86-uarch-abi.py b/scripts/cpu-x86-uarch-abi.py
index 8963d90f0b..c262d2f027 100644
--- a/scripts/cpu-x86-uarch-abi.py
+++ b/scripts/cpu-x86-uarch-abi.py
@@ -6,7 +6,7 @@
 # compatibility levels for each CPU model.
 #
 
-from qemu import qmp
+from qemu.aqmp.legacy import QEMUMonitorProtocol
 import sys
 
 if len(sys.argv) != 2:
@@ -66,7 +66,7 @@
 
 
 sock = sys.argv[1]
-shell = qmp.QEMUMonitorProtocol(sock)
+shell = QEMUMonitorProtocol(sock)
 shell.connect()
 
 models = shell.cmd("query-cpu-definitions")
-- 
2.31.1




[PATCH v3 29/31] python: re-enable pylint duplicate-code warnings

2022-01-10 Thread John Snow
With the old library gone, there's nothing duplicated in the tree, so
the warning suppression can be removed.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/setup.cfg | 1 -
 1 file changed, 1 deletion(-)

diff --git a/python/setup.cfg b/python/setup.cfg
index 5140a5b322..c341e922c2 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -114,7 +114,6 @@ ignore_missing_imports = True
 disable=consider-using-f-string,
 too-many-function-args,  # mypy handles this with less false positives.
 no-member,  # mypy also handles this better.
-duplicate-code,  # To be removed by the end of this patch series.
 
 [pylint.basic]
 # Good variable names which should always be accepted, separated by a comma.
-- 
2.31.1




[PATCH v3 21/31] scripts/bench-block-job: switch to AQMP

2022-01-10 Thread John Snow
For this commit, we only need to remove accommodations for the
synchronous QMP library.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 scripts/simplebench/bench_block_job.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/scripts/simplebench/bench_block_job.py 
b/scripts/simplebench/bench_block_job.py
index a403c35b08..af9d1646a4 100755
--- a/scripts/simplebench/bench_block_job.py
+++ b/scripts/simplebench/bench_block_job.py
@@ -27,7 +27,6 @@
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
 from qemu.machine import QEMUMachine
-from qemu.qmp import QMPConnectError
 from qemu.aqmp import ConnectError
 
 
@@ -50,7 +49,7 @@ def bench_block_job(cmd, cmd_args, qemu_args):
 vm.launch()
 except OSError as e:
 return {'error': 'popen failed: ' + str(e)}
-except (QMPConnectError, ConnectError, socket.timeout):
+except (ConnectError, socket.timeout):
 return {'error': 'qemu failed: ' + str(vm.get_log())}
 
 try:
-- 
2.31.1




[PATCH v3 31/31] python: rename 'aqmp-tui' to 'qmp-tui'

2022-01-10 Thread John Snow
This is the last vestige of the "aqmp" moniker surviving in the tree; remove it.

Signed-off-by: John Snow 
---
 python/qemu/qmp/{aqmp_tui.py => qmp_tui.py} | 12 ++--
 python/setup.cfg|  6 +++---
 2 files changed, 9 insertions(+), 9 deletions(-)
 rename python/qemu/qmp/{aqmp_tui.py => qmp_tui.py} (98%)

diff --git a/python/qemu/qmp/aqmp_tui.py b/python/qemu/qmp/qmp_tui.py
similarity index 98%
rename from python/qemu/qmp/aqmp_tui.py
rename to python/qemu/qmp/qmp_tui.py
index 184a3e4690..17dc94e7c3 100644
--- a/python/qemu/qmp/aqmp_tui.py
+++ b/python/qemu/qmp/qmp_tui.py
@@ -6,13 +6,13 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later.  See the COPYING file in the top-level directory.
 """
-AQMP TUI
+QMP TUI
 
-AQMP TUI is an asynchronous interface built on top the of the AQMP library.
+QMP TUI is an asynchronous interface built on top the of the QMP library.
 It is the successor of QMP-shell and is bought-in as a replacement for it.
 
-Example Usage: aqmp-tui 
-Full Usage: aqmp-tui --help
+Example Usage: qmp-tui 
+Full Usage: qmp-tui --help
 """
 
 import argparse
@@ -129,7 +129,7 @@ def has_handler_type(logger: logging.Logger,
 
 class App(QMPClient):
 """
-Implements the AQMP TUI.
+Implements the QMP TUI.
 
 Initializes the widgets and starts the urwid event loop.
 
@@ -612,7 +612,7 @@ def main() -> None:
 Driver of the whole script, parses arguments, initialize the TUI and
 the logger.
 """
-parser = argparse.ArgumentParser(description='AQMP TUI')
+parser = argparse.ArgumentParser(description='QMP TUI')
 parser.add_argument('qmp_server', help='Address of the QMP server. '
 'Format ')
 parser.add_argument('--num-retries', type=int, default=10,
diff --git a/python/setup.cfg b/python/setup.cfg
index 911ae02de7..4614521dea 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -51,7 +51,7 @@ devel =
 fuse =
 fusepy >= 2.0.4
 
-# AQMP TUI dependencies
+# QMP TUI dependencies
 tui =
 urwid >= 2.1.2
 urwid-readline >= 0.13
@@ -67,7 +67,7 @@ console_scripts =
 qom-fuse = qemu.utils.qom_fuse:QOMFuse.entry_point [fuse]
 qemu-ga-client = qemu.utils.qemu_ga_client:main
 qmp-shell = qemu.qmp.qmp_shell:main
-aqmp-tui = qemu.qmp.aqmp_tui:main [tui]
+qmp-tui = qemu.qmp.qmp_tui:main [tui]
 
 [flake8]
 extend-ignore = E722  # Prefer pylint's bare-except checks to flake8's
@@ -83,7 +83,7 @@ namespace_packages = True
 # fusepy has no type stubs:
 allow_subclassing_any = True
 
-[mypy-qemu.qmp.aqmp_tui]
+[mypy-qemu.qmp.qmp_tui]
 # urwid and urwid_readline have no type stubs:
 allow_subclassing_any = True
 
-- 
2.31.1




[PATCH v3 18/31] scripts/cpu-x86-uarch-abi: fix CLI parsing

2022-01-10 Thread John Snow
Signed-off-by: John Snow 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 scripts/cpu-x86-uarch-abi.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/scripts/cpu-x86-uarch-abi.py b/scripts/cpu-x86-uarch-abi.py
index 08acc52a81..8963d90f0b 100644
--- a/scripts/cpu-x86-uarch-abi.py
+++ b/scripts/cpu-x86-uarch-abi.py
@@ -9,7 +9,7 @@
 from qemu import qmp
 import sys
 
-if len(sys.argv) != 1:
+if len(sys.argv) != 2:
 print("syntax: %s QMP-SOCK\n\n" % __file__ +
   "Where QMP-SOCK points to a QEMU process such as\n\n" +
   " # qemu-system-x86_64 -qmp unix:/tmp/qmp,server,nowait " +
@@ -66,7 +66,6 @@
 
 
 sock = sys.argv[1]
-cmd = sys.argv[2]
 shell = qmp.QEMUMonitorProtocol(sock)
 shell.connect()
 
-- 
2.31.1




[PATCH v3 12/31] python/qmp: switch qemu-ga-client to AQMP

2022-01-10 Thread John Snow
Async QMP always raises a "ConnectError" on any connection error which
houses the cause in a second exception. We can check if this root cause
was python's ConnectionError to determine a fairly similar condition to
the original error check here.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/qemu/qmp/qemu_ga_client.py | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/python/qemu/qmp/qemu_ga_client.py 
b/python/qemu/qmp/qemu_ga_client.py
index b3e1d98c9e..15ed430c61 100644
--- a/python/qemu/qmp/qemu_ga_client.py
+++ b/python/qemu/qmp/qemu_ga_client.py
@@ -37,8 +37,8 @@
 # the COPYING file in the top-level directory.
 
 import argparse
+import asyncio
 import base64
-import errno
 import os
 import random
 import sys
@@ -50,8 +50,8 @@
 Sequence,
 )
 
-from qemu import qmp
-from qemu.qmp import SocketAddrT
+from qemu.aqmp import ConnectError, SocketAddrT
+from qemu.aqmp.legacy import QEMUMonitorProtocol
 
 
 # This script has not seen many patches or careful attention in quite
@@ -61,7 +61,7 @@
 # pylint: disable=missing-docstring
 
 
-class QemuGuestAgent(qmp.QEMUMonitorProtocol):
+class QemuGuestAgent(QEMUMonitorProtocol):
 def __getattr__(self, name: str) -> Callable[..., Any]:
 def wrapper(**kwds: object) -> object:
 return self.command('guest-' + name.replace('_', '-'), **kwds)
@@ -149,7 +149,7 @@ def ping(self, timeout: Optional[float]) -> bool:
 self.qga.settimeout(timeout)
 try:
 self.qga.ping()
-except TimeoutError:
+except asyncio.TimeoutError:
 return False
 return True
 
@@ -172,7 +172,7 @@ def suspend(self, mode: str) -> None:
 try:
 getattr(self.qga, 'suspend' + '_' + mode)()
 # On error exception will raise
-except TimeoutError:
+except asyncio.TimeoutError:
 # On success command will timed out
 return
 
@@ -182,7 +182,7 @@ def shutdown(self, mode: str = 'powerdown') -> None:
 
 try:
 self.qga.shutdown(mode=mode)
-except TimeoutError:
+except asyncio.TimeoutError:
 pass
 
 
@@ -277,7 +277,7 @@ def _cmd_reboot(client: QemuGuestAgentClient, args: 
Sequence[str]) -> None:
 
 def send_command(address: str, cmd: str, args: Sequence[str]) -> None:
 if not os.path.exists(address):
-print('%s not found' % address)
+print(f"'{address}' not found. (Is QEMU running?)")
 sys.exit(1)
 
 if cmd not in commands:
@@ -287,10 +287,10 @@ def send_command(address: str, cmd: str, args: 
Sequence[str]) -> None:
 
 try:
 client = QemuGuestAgentClient(address)
-except OSError as err:
+except ConnectError as err:
 print(err)
-if err.errno == errno.ECONNREFUSED:
-print('Hint: qemu is not running?')
+if isinstance(err.exc, ConnectionError):
+print('(Is QEMU running?)')
 sys.exit(1)
 
 if cmd == 'fsfreeze' and args[0] == 'freeze':
-- 
2.31.1




[PATCH v3 20/31] scripts/render-block-graph: switch to AQMP

2022-01-10 Thread John Snow
Creating an instance of qemu.aqmp.ExecuteError is too involved here, so
just drop the specificity down to a generic QMPError.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 scripts/render_block_graph.py | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py
index da6acf050d..97778927f3 100755
--- a/scripts/render_block_graph.py
+++ b/scripts/render_block_graph.py
@@ -25,10 +25,8 @@
 from graphviz import Digraph
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python'))
-from qemu.qmp import (
-QEMUMonitorProtocol,
-QMPResponseError,
-)
+from qemu.aqmp import QMPError
+from qemu.aqmp.legacy import QEMUMonitorProtocol
 
 
 def perm(arr):
@@ -105,7 +103,7 @@ def command(self, cmd):
 reply = json.loads(subprocess.check_output(ar))
 
 if 'error' in reply:
-raise QMPResponseError(reply)
+raise QMPError(reply)
 
 return reply['return']
 
-- 
2.31.1




[PATCH v3 17/31] python/machine: permanently switch to AQMP

2022-01-10 Thread John Snow
Remove the QEMU_PYTHON_LEGACY_QMP environment variable, making the
switch permanent. Update Exceptions and import paths as necessary.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/qemu/machine/machine.py | 18 +++---
 python/qemu/machine/qtest.py   |  2 +-
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index 67ab06ca2b..21fb4a4f30 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -40,21 +40,16 @@
 TypeVar,
 )
 
-from qemu.qmp import (  # pylint: disable=import-error
+from qemu.aqmp import SocketAddrT
+from qemu.aqmp.legacy import (
+QEMUMonitorProtocol,
 QMPMessage,
 QMPReturnValue,
-SocketAddrT,
 )
 
 from . import console_socket
 
 
-if os.environ.get('QEMU_PYTHON_LEGACY_QMP'):
-from qemu.qmp import QEMUMonitorProtocol
-else:
-from qemu.aqmp.legacy import QEMUMonitorProtocol
-
-
 LOG = logging.getLogger(__name__)
 
 
@@ -710,8 +705,9 @@ def events_wait(self,
 :param timeout: Optional timeout, in seconds.
 See QEMUMonitorProtocol.pull_event.
 
-:raise QMPTimeoutError: If timeout was non-zero and no matching events
-were found.
+:raise asyncio.TimeoutError:
+If timeout was non-zero and no matching events were found.
+
 :return: A QMP event matching the filter criteria.
  If timeout was 0 and no event matched, None.
 """
@@ -734,7 +730,7 @@ def _match(event: QMPMessage) -> bool:
 event = self._qmp.pull_event(wait=timeout)
 if event is None:
 # NB: None is only returned when timeout is false-ish.
-# Timeouts raise QMPTimeoutError instead!
+# Timeouts raise asyncio.TimeoutError instead!
 break
 if _match(event):
 return event
diff --git a/python/qemu/machine/qtest.py b/python/qemu/machine/qtest.py
index f2f9aaa5e5..13e0aaff84 100644
--- a/python/qemu/machine/qtest.py
+++ b/python/qemu/machine/qtest.py
@@ -26,7 +26,7 @@
 TextIO,
 )
 
-from qemu.qmp import SocketAddrT  # pylint: disable=import-error
+from qemu.aqmp import SocketAddrT
 
 from .machine import QEMUMachine
 
-- 
2.31.1




[PATCH v3 08/31] python/aqmp: copy type definitions from qmp

2022-01-10 Thread John Snow
Copy the remaining type definitions from QMP into the qemu.aqmp.legacy
module. Now, users that require the legacy interface don't need to
import anything else but qemu.aqmp.legacy wrapper.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 python/qemu/aqmp/legacy.py   | 22 --
 python/qemu/aqmp/protocol.py | 16 ++--
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py
index 2ccb136b02..9431fe9330 100644
--- a/python/qemu/aqmp/legacy.py
+++ b/python/qemu/aqmp/legacy.py
@@ -6,7 +6,9 @@
 
 import asyncio
 from typing import (
+Any,
 Awaitable,
+Dict,
 List,
 Optional,
 TypeVar,
@@ -14,13 +16,29 @@
 )
 
 import qemu.qmp
-from qemu.qmp import QMPMessage, QMPReturnValue, SocketAddrT
 
 from .error import AQMPError
-from .protocol import Runstate
+from .protocol import Runstate, SocketAddrT
 from .qmp_client import QMPClient
 
 
+#: QMPMessage is an entire QMP message of any kind.
+QMPMessage = Dict[str, Any]
+
+#: QMPReturnValue is the 'return' value of a command.
+QMPReturnValue = object
+
+#: QMPObject is any object in a QMP message.
+QMPObject = Dict[str, object]
+
+# QMPMessage can be outgoing commands or incoming events/returns.
+# QMPReturnValue is usually a dict/json object, but due to QAPI's
+# 'returns-whitelist', it can actually be anything.
+#
+# {'return': {}} is a QMPMessage,
+# {} is the QMPReturnValue.
+
+
 # pylint: disable=missing-docstring
 
 
diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/aqmp/protocol.py
index c4fbe35a0e..5b4f2f0d0a 100644
--- a/python/qemu/aqmp/protocol.py
+++ b/python/qemu/aqmp/protocol.py
@@ -46,6 +46,10 @@
 _U = TypeVar('_U')
 _TaskFN = Callable[[], Awaitable[None]]  # aka ``async def func() -> None``
 
+InternetAddrT = Tuple[str, int]
+UnixAddrT = str
+SocketAddrT = Union[UnixAddrT, InternetAddrT]
+
 
 class Runstate(Enum):
 """Protocol session runstate."""
@@ -257,7 +261,7 @@ async def runstate_changed(self) -> Runstate:
 
 @upper_half
 @require(Runstate.IDLE)
-async def accept(self, address: Union[str, Tuple[str, int]],
+async def accept(self, address: SocketAddrT,
  ssl: Optional[SSLContext] = None) -> None:
 """
 Accept a connection and begin processing message queues.
@@ -275,7 +279,7 @@ async def accept(self, address: Union[str, Tuple[str, int]],
 
 @upper_half
 @require(Runstate.IDLE)
-async def connect(self, address: Union[str, Tuple[str, int]],
+async def connect(self, address: SocketAddrT,
   ssl: Optional[SSLContext] = None) -> None:
 """
 Connect to the server and begin processing message queues.
@@ -337,7 +341,7 @@ def _set_state(self, state: Runstate) -> None:
 
 @upper_half
 async def _new_session(self,
-   address: Union[str, Tuple[str, int]],
+   address: SocketAddrT,
ssl: Optional[SSLContext] = None,
accept: bool = False) -> None:
 """
@@ -397,7 +401,7 @@ async def _new_session(self,
 @upper_half
 async def _establish_connection(
 self,
-address: Union[str, Tuple[str, int]],
+address: SocketAddrT,
 ssl: Optional[SSLContext] = None,
 accept: bool = False
 ) -> None:
@@ -424,7 +428,7 @@ async def _establish_connection(
 await self._do_connect(address, ssl)
 
 @upper_half
-async def _do_accept(self, address: Union[str, Tuple[str, int]],
+async def _do_accept(self, address: SocketAddrT,
  ssl: Optional[SSLContext] = None) -> None:
 """
 Acting as the transport server, accept a single connection.
@@ -482,7 +486,7 @@ async def _client_connected_cb(reader: asyncio.StreamReader,
 self.logger.debug("Connection accepted.")
 
 @upper_half
-async def _do_connect(self, address: Union[str, Tuple[str, int]],
+async def _do_connect(self, address: SocketAddrT,
   ssl: Optional[SSLContext] = None) -> None:
 """
 Acting as the transport client, initiate a connection to a server.
-- 
2.31.1




[PATCH v3 13/31] python/qmp: switch qom tools to AQMP

2022-01-10 Thread John Snow
Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/qemu/qmp/qom.py|  5 +++--
 python/qemu/qmp/qom_common.py |  3 ++-
 python/qemu/qmp/qom_fuse.py   | 11 ++-
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/python/qemu/qmp/qom.py b/python/qemu/qmp/qom.py
index 8ff28a8343..bb5d1a78f5 100644
--- a/python/qemu/qmp/qom.py
+++ b/python/qemu/qmp/qom.py
@@ -32,7 +32,8 @@
 
 import argparse
 
-from . import QMPResponseError
+from qemu.aqmp import ExecuteError
+
 from .qom_common import QOMCommand
 
 
@@ -233,7 +234,7 @@ def _list_node(self, path: str) -> None:
 rsp = self.qmp.command('qom-get', path=path,
property=item.name)
 print(f"  {item.name}: {rsp} ({item.type})")
-except QMPResponseError as err:
+except ExecuteError as err:
 print(f"  {item.name}:  ({item.type})")
 print('')
 for item in items:
diff --git a/python/qemu/qmp/qom_common.py b/python/qemu/qmp/qom_common.py
index 2e4c741f77..e034a6f247 100644
--- a/python/qemu/qmp/qom_common.py
+++ b/python/qemu/qmp/qom_common.py
@@ -27,7 +27,8 @@
 TypeVar,
 )
 
-from . import QEMUMonitorProtocol, QMPError
+from qemu.aqmp import QMPError
+from qemu.aqmp.legacy import QEMUMonitorProtocol
 
 
 class ObjectPropertyInfo:
diff --git a/python/qemu/qmp/qom_fuse.py b/python/qemu/qmp/qom_fuse.py
index 43f4671fdb..653a76b93b 100644
--- a/python/qemu/qmp/qom_fuse.py
+++ b/python/qemu/qmp/qom_fuse.py
@@ -48,7 +48,8 @@
 import fuse
 from fuse import FUSE, FuseOSError, Operations
 
-from . import QMPResponseError
+from qemu.aqmp import ExecuteError
+
 from .qom_common import QOMCommand
 
 
@@ -99,7 +100,7 @@ def is_object(self, path: str) -> bool:
 try:
 self.qom_list(path)
 return True
-except QMPResponseError:
+except ExecuteError:
 return False
 
 def is_property(self, path: str) -> bool:
@@ -112,7 +113,7 @@ def is_property(self, path: str) -> bool:
 if item.name == prop:
 return True
 return False
-except QMPResponseError:
+except ExecuteError:
 return False
 
 def is_link(self, path: str) -> bool:
@@ -125,7 +126,7 @@ def is_link(self, path: str) -> bool:
 if item.name == prop and item.link:
 return True
 return False
-except QMPResponseError:
+except ExecuteError:
 return False
 
 def read(self, path: str, size: int, offset: int, fh: IO[bytes]) -> bytes:
@@ -138,7 +139,7 @@ def read(self, path: str, size: int, offset: int, fh: 
IO[bytes]) -> bytes:
 try:
 data = str(self.qmp.command('qom-get', path=path, property=prop))
 data += '\n'  # make values shell friendly
-except QMPResponseError as err:
+except ExecuteError as err:
 raise FuseOSError(EPERM) from err
 
 if offset > len(data):
-- 
2.31.1




[PATCH v3 14/31] python/qmp: switch qmp-shell to AQMP

2022-01-10 Thread John Snow
We have a replacement for async QMP, but it doesn't have feature parity
yet. For now, then, port the old tool onto the new backend.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 python/qemu/aqmp/legacy.py   |  3 +++
 python/qemu/qmp/qmp_shell.py | 31 +--
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py
index 27df22818a..0890f95b16 100644
--- a/python/qemu/aqmp/legacy.py
+++ b/python/qemu/aqmp/legacy.py
@@ -22,6 +22,9 @@
 from .qmp_client import QMPClient
 
 
+# (Temporarily) Re-export QMPBadPortError
+QMPBadPortError = qemu.qmp.QMPBadPortError
+
 #: QMPMessage is an entire QMP message of any kind.
 QMPMessage = Dict[str, Any]
 
diff --git a/python/qemu/qmp/qmp_shell.py b/python/qemu/qmp/qmp_shell.py
index e7d7eb18f1..d11bf54b00 100644
--- a/python/qemu/qmp/qmp_shell.py
+++ b/python/qemu/qmp/qmp_shell.py
@@ -95,8 +95,13 @@
 Sequence,
 )
 
-from qemu import qmp
-from qemu.qmp import QMPMessage
+from qemu.aqmp import ConnectError, QMPError, SocketAddrT
+from qemu.aqmp.legacy import (
+QEMUMonitorProtocol,
+QMPBadPortError,
+QMPMessage,
+QMPObject,
+)
 
 
 LOG = logging.getLogger(__name__)
@@ -125,7 +130,7 @@ def complete(self, text: str, state: int) -> Optional[str]:
 return None
 
 
-class QMPShellError(qmp.QMPError):
+class QMPShellError(QMPError):
 """
 QMP Shell Base error class.
 """
@@ -153,7 +158,7 @@ def visit_Name(cls,  # pylint: disable=invalid-name
 return node
 
 
-class QMPShell(qmp.QEMUMonitorProtocol):
+class QMPShell(QEMUMonitorProtocol):
 """
 QMPShell provides a basic readline-based QMP shell.
 
@@ -161,7 +166,7 @@ class QMPShell(qmp.QEMUMonitorProtocol):
 :param pretty: Pretty-print QMP messages.
 :param verbose: Echo outgoing QMP messages to console.
 """
-def __init__(self, address: qmp.SocketAddrT,
+def __init__(self, address: SocketAddrT,
  pretty: bool = False, verbose: bool = False):
 super().__init__(address)
 self._greeting: Optional[QMPMessage] = None
@@ -237,7 +242,7 @@ def _parse_value(cls, val: str) -> object:
 
 def _cli_expr(self,
   tokens: Sequence[str],
-  parent: qmp.QMPObject) -> None:
+  parent: QMPObject) -> None:
 for arg in tokens:
 (key, sep, val) = arg.partition('=')
 if sep != '=':
@@ -403,7 +408,7 @@ class HMPShell(QMPShell):
 :param pretty: Pretty-print QMP messages.
 :param verbose: Echo outgoing QMP messages to console.
 """
-def __init__(self, address: qmp.SocketAddrT,
+def __init__(self, address: SocketAddrT,
  pretty: bool = False, verbose: bool = False):
 super().__init__(address, pretty, verbose)
 self._cpu_index = 0
@@ -512,19 +517,17 @@ def main() -> None:
 
 try:
 address = shell_class.parse_address(args.qmp_server)
-except qmp.QMPBadPortError:
+except QMPBadPortError:
 parser.error(f"Bad port number: {args.qmp_server}")
 return  # pycharm doesn't know error() is noreturn
 
 with shell_class(address, args.pretty, args.verbose) as qemu:
 try:
 qemu.connect(negotiate=not args.skip_negotiation)
-except qmp.QMPConnectError:
-die("Didn't get QMP greeting message")
-except qmp.QMPCapabilitiesError:
-die("Couldn't negotiate capabilities")
-except OSError as err:
-die(f"Couldn't connect to {args.qmp_server}: {err!s}")
+except ConnectError as err:
+if isinstance(err.exc, OSError):
+die(f"Couldn't connect to {args.qmp_server}: {err!s}")
+die(str(err))
 
 for _ in qemu.repl():
 pass
-- 
2.31.1




[PATCH v3 16/31] python: move qmp-shell under the AQMP package

2022-01-10 Thread John Snow
Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/README.rst  | 2 +-
 python/qemu/{qmp => aqmp}/qmp_shell.py | 0
 python/setup.cfg   | 2 +-
 scripts/qmp/qmp-shell  | 2 +-
 4 files changed, 3 insertions(+), 3 deletions(-)
 rename python/qemu/{qmp => aqmp}/qmp_shell.py (100%)

diff --git a/python/README.rst b/python/README.rst
index 9c1fceaee7..fcf74f69ea 100644
--- a/python/README.rst
+++ b/python/README.rst
@@ -59,7 +59,7 @@ Package installation also normally provides executable 
console scripts,
 so that tools like ``qmp-shell`` are always available via $PATH. To
 invoke them without installation, you can invoke e.g.:
 
-``> PYTHONPATH=~/src/qemu/python python3 -m qemu.qmp.qmp_shell``
+``> PYTHONPATH=~/src/qemu/python python3 -m qemu.aqmp.qmp_shell``
 
 The mappings between console script name and python module path can be
 found in ``setup.cfg``.
diff --git a/python/qemu/qmp/qmp_shell.py b/python/qemu/aqmp/qmp_shell.py
similarity index 100%
rename from python/qemu/qmp/qmp_shell.py
rename to python/qemu/aqmp/qmp_shell.py
diff --git a/python/setup.cfg b/python/setup.cfg
index 78421411d2..168a79c867 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -67,7 +67,7 @@ console_scripts =
 qom-tree = qemu.utils.qom:QOMTree.entry_point
 qom-fuse = qemu.utils.qom_fuse:QOMFuse.entry_point [fuse]
 qemu-ga-client = qemu.utils.qemu_ga_client:main
-qmp-shell = qemu.qmp.qmp_shell:main
+qmp-shell = qemu.aqmp.qmp_shell:main
 aqmp-tui = qemu.aqmp.aqmp_tui:main [tui]
 
 [flake8]
diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index 4a20f97db7..31b19d73e2 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -4,7 +4,7 @@ import os
 import sys
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp import qmp_shell
+from qemu.aqmp import qmp_shell
 
 
 if __name__ == '__main__':
-- 
2.31.1




[PATCH v3 06/31] python/aqmp: add __del__ method to legacy interface

2022-01-10 Thread John Snow
asyncio can complain *very* loudly if you forget to back out of things
gracefully before the garbage collector starts destroying objects that
contain live references to asyncio Tasks.

The usual fix is just to remember to call aqmp.disconnect(), but for the
sake of the legacy wrapper and quick, one-off scripts where a graceful
shutdown is not necessarily of paramount imporance, add a courtesy
cleanup that will trigger prior to seeing screenfuls of confusing
asyncio tracebacks.

Note that we can't *always* save you from yourself; depending on when
the GC runs, you might just seriously be out of luck. The best we can do
in this case is to gently remind you to clean up after yourself.

(Still much better than multiple pages of incomprehensible python
warnings for the crime of forgetting to put your toys away.)

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/qemu/aqmp/legacy.py | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py
index 9e7b9fb80b..2ccb136b02 100644
--- a/python/qemu/aqmp/legacy.py
+++ b/python/qemu/aqmp/legacy.py
@@ -16,6 +16,8 @@
 import qemu.qmp
 from qemu.qmp import QMPMessage, QMPReturnValue, SocketAddrT
 
+from .error import AQMPError
+from .protocol import Runstate
 from .qmp_client import QMPClient
 
 
@@ -136,3 +138,19 @@ def settimeout(self, timeout: Optional[float]) -> None:
 
 def send_fd_scm(self, fd: int) -> None:
 self._aqmp.send_fd_scm(fd)
+
+def __del__(self) -> None:
+if self._aqmp.runstate == Runstate.IDLE:
+return
+
+if not self._aloop.is_running():
+self.close()
+else:
+# Garbage collection ran while the event loop was running.
+# Nothing we can do about it now, but if we don't raise our
+# own error, the user will be treated to a lot of traceback
+# they might not understand.
+raise AQMPError(
+"QEMUMonitorProtocol.close()"
+" was not called before object was garbage collected"
+)
-- 
2.31.1




[PATCH v3 10/31] python/aqmp: rename AQMPError to QMPError

2022-01-10 Thread John Snow
This is in preparation for renaming qemu.aqmp to qemu.qmp. I should have
done this from this from the very beginning, but it's a convenient time
to make sure this churn is taken care of.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 python/qemu/aqmp/__init__.py   |  6 +++---
 python/qemu/aqmp/error.py  | 12 ++--
 python/qemu/aqmp/events.py |  4 ++--
 python/qemu/aqmp/legacy.py |  4 ++--
 python/qemu/aqmp/protocol.py   |  8 
 python/qemu/aqmp/qmp_client.py |  8 
 6 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/python/qemu/aqmp/__init__.py b/python/qemu/aqmp/__init__.py
index 05f467c141..4c22c38079 100644
--- a/python/qemu/aqmp/__init__.py
+++ b/python/qemu/aqmp/__init__.py
@@ -6,7 +6,7 @@
 QEMU Guest Agent, and the QEMU Storage Daemon.
 
 `QMPClient` provides the main functionality of this package. All errors
-raised by this library derive from `AQMPError`, see `aqmp.error` for
+raised by this library derive from `QMPError`, see `aqmp.error` for
 additional detail. See `aqmp.events` for an in-depth tutorial on
 managing QMP events.
 """
@@ -23,7 +23,7 @@
 
 import logging
 
-from .error import AQMPError
+from .error import QMPError
 from .events import EventListener
 from .message import Message
 from .protocol import (
@@ -48,7 +48,7 @@
 'Runstate',
 
 # Exceptions, most generic to most explicit
-'AQMPError',
+'QMPError',
 'StateError',
 'ConnectError',
 'ExecuteError',
diff --git a/python/qemu/aqmp/error.py b/python/qemu/aqmp/error.py
index 781f49b008..24ba4d5054 100644
--- a/python/qemu/aqmp/error.py
+++ b/python/qemu/aqmp/error.py
@@ -1,21 +1,21 @@
 """
-AQMP Error Classes
+QMP Error Classes
 
 This package seeks to provide semantic error classes that are intended
 to be used directly by clients when they would like to handle particular
 semantic failures (e.g. "failed to connect") without needing to know the
 enumeration of possible reasons for that failure.
 
-AQMPError serves as the ancestor for all exceptions raised by this
+QMPError serves as the ancestor for all exceptions raised by this
 package, and is suitable for use in handling semantic errors from this
 library. In most cases, individual public methods will attempt to catch
 and re-encapsulate various exceptions to provide a semantic
 error-handling interface.
 
-.. admonition:: AQMP Exception Hierarchy Reference
+.. admonition:: QMP Exception Hierarchy Reference
 
  |   `Exception`
- |+-- `AQMPError`
+ |+-- `QMPError`
  | +-- `ConnectError`
  | +-- `StateError`
  | +-- `ExecInterruptedError`
@@ -31,11 +31,11 @@
 """
 
 
-class AQMPError(Exception):
+class QMPError(Exception):
 """Abstract error class for all errors originating from this package."""
 
 
-class ProtocolError(AQMPError):
+class ProtocolError(QMPError):
 """
 Abstract error class for protocol failures.
 
diff --git a/python/qemu/aqmp/events.py b/python/qemu/aqmp/events.py
index 5f7150c78d..f3d4e2b5e8 100644
--- a/python/qemu/aqmp/events.py
+++ b/python/qemu/aqmp/events.py
@@ -443,7 +443,7 @@ def accept(self, event) -> bool:
 Union,
 )
 
-from .error import AQMPError
+from .error import QMPError
 from .message import Message
 
 
@@ -451,7 +451,7 @@ def accept(self, event) -> bool:
 EventFilter = Callable[[Message], bool]
 
 
-class ListenerError(AQMPError):
+class ListenerError(QMPError):
 """
 Generic error class for `EventListener`-related problems.
 """
diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py
index 9431fe9330..27df22818a 100644
--- a/python/qemu/aqmp/legacy.py
+++ b/python/qemu/aqmp/legacy.py
@@ -17,7 +17,7 @@
 
 import qemu.qmp
 
-from .error import AQMPError
+from .error import QMPError
 from .protocol import Runstate, SocketAddrT
 from .qmp_client import QMPClient
 
@@ -168,7 +168,7 @@ def __del__(self) -> None:
 # Nothing we can do about it now, but if we don't raise our
 # own error, the user will be treated to a lot of traceback
 # they might not understand.
-raise AQMPError(
+raise QMPError(
 "QEMUMonitorProtocol.close()"
 " was not called before object was garbage collected"
 )
diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/aqmp/protocol.py
index 5b4f2f0d0a..50e973c2f2 100644
--- a/python/qemu/aqmp/protocol.py
+++ b/python/qemu/aqmp/protocol.py
@@ -29,7 +29,7 @@
 cast,
 )
 
-from .error import AQMPError
+from .error import QMPError
 from .util import (
 bottom_half,
 create_task,
@@ -65,7 +65,7 @@ class Runstate(Enum):
 DISCONNECTING = 3
 
 
-class ConnectError(AQMPError):
+class ConnectError(QMPError):
 """
 Raised when the initial connection process has failed.
 
@@ -90,7 +90,7 @@ def __str__(self) -> str:
 return f"{self.error_message}: {cause}"
 
 
-class StateError(AQMPError):
+class StateError(QMPError):
 """
 An 

[PATCH v3 15/31] python: move qmp utilities to python/qemu/utils

2022-01-10 Thread John Snow
In order to upload a QMP package to PyPI, I want to remove any scripts
that I am not 100% confident I want to support upstream, beyond our
castle walls.

Move most of our QMP utilities into the utils package so we can split
them out from the PyPI upload.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 python/qemu/{qmp => utils}/qemu_ga_client.py |  0
 python/qemu/{qmp => utils}/qom.py|  0
 python/qemu/{qmp => utils}/qom_common.py |  0
 python/qemu/{qmp => utils}/qom_fuse.py   |  0
 python/setup.cfg | 16 
 scripts/qmp/qemu-ga-client   |  2 +-
 scripts/qmp/qom-fuse |  2 +-
 scripts/qmp/qom-get  |  2 +-
 scripts/qmp/qom-list |  2 +-
 scripts/qmp/qom-set  |  2 +-
 scripts/qmp/qom-tree |  2 +-
 11 files changed, 14 insertions(+), 14 deletions(-)
 rename python/qemu/{qmp => utils}/qemu_ga_client.py (100%)
 rename python/qemu/{qmp => utils}/qom.py (100%)
 rename python/qemu/{qmp => utils}/qom_common.py (100%)
 rename python/qemu/{qmp => utils}/qom_fuse.py (100%)

diff --git a/python/qemu/qmp/qemu_ga_client.py 
b/python/qemu/utils/qemu_ga_client.py
similarity index 100%
rename from python/qemu/qmp/qemu_ga_client.py
rename to python/qemu/utils/qemu_ga_client.py
diff --git a/python/qemu/qmp/qom.py b/python/qemu/utils/qom.py
similarity index 100%
rename from python/qemu/qmp/qom.py
rename to python/qemu/utils/qom.py
diff --git a/python/qemu/qmp/qom_common.py b/python/qemu/utils/qom_common.py
similarity index 100%
rename from python/qemu/qmp/qom_common.py
rename to python/qemu/utils/qom_common.py
diff --git a/python/qemu/qmp/qom_fuse.py b/python/qemu/utils/qom_fuse.py
similarity index 100%
rename from python/qemu/qmp/qom_fuse.py
rename to python/qemu/utils/qom_fuse.py
diff --git a/python/setup.cfg b/python/setup.cfg
index 417e937839..78421411d2 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -60,13 +60,13 @@ tui =
 
 [options.entry_points]
 console_scripts =
-qom = qemu.qmp.qom:main
-qom-set = qemu.qmp.qom:QOMSet.entry_point
-qom-get = qemu.qmp.qom:QOMGet.entry_point
-qom-list = qemu.qmp.qom:QOMList.entry_point
-qom-tree = qemu.qmp.qom:QOMTree.entry_point
-qom-fuse = qemu.qmp.qom_fuse:QOMFuse.entry_point [fuse]
-qemu-ga-client = qemu.qmp.qemu_ga_client:main
+qom = qemu.utils.qom:main
+qom-set = qemu.utils.qom:QOMSet.entry_point
+qom-get = qemu.utils.qom:QOMGet.entry_point
+qom-list = qemu.utils.qom:QOMList.entry_point
+qom-tree = qemu.utils.qom:QOMTree.entry_point
+qom-fuse = qemu.utils.qom_fuse:QOMFuse.entry_point [fuse]
+qemu-ga-client = qemu.utils.qemu_ga_client:main
 qmp-shell = qemu.qmp.qmp_shell:main
 aqmp-tui = qemu.aqmp.aqmp_tui:main [tui]
 
@@ -80,7 +80,7 @@ python_version = 3.6
 warn_unused_configs = True
 namespace_packages = True
 
-[mypy-qemu.qmp.qom_fuse]
+[mypy-qemu.utils.qom_fuse]
 # fusepy has no type stubs:
 allow_subclassing_any = True
 
diff --git a/scripts/qmp/qemu-ga-client b/scripts/qmp/qemu-ga-client
index 102fd2cad9..56edd0234a 100755
--- a/scripts/qmp/qemu-ga-client
+++ b/scripts/qmp/qemu-ga-client
@@ -4,7 +4,7 @@ import os
 import sys
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp import qemu_ga_client
+from qemu.utils import qemu_ga_client
 
 
 if __name__ == '__main__':
diff --git a/scripts/qmp/qom-fuse b/scripts/qmp/qom-fuse
index a58c8ef979..d453807b27 100755
--- a/scripts/qmp/qom-fuse
+++ b/scripts/qmp/qom-fuse
@@ -4,7 +4,7 @@ import os
 import sys
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp.qom_fuse import QOMFuse
+from qemu.utils.qom_fuse import QOMFuse
 
 
 if __name__ == '__main__':
diff --git a/scripts/qmp/qom-get b/scripts/qmp/qom-get
index e4f3e0c013..04ebe052e8 100755
--- a/scripts/qmp/qom-get
+++ b/scripts/qmp/qom-get
@@ -4,7 +4,7 @@ import os
 import sys
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp.qom import QOMGet
+from qemu.utils.qom import QOMGet
 
 
 if __name__ == '__main__':
diff --git a/scripts/qmp/qom-list b/scripts/qmp/qom-list
index 7a071a54e1..853b85a8d3 100755
--- a/scripts/qmp/qom-list
+++ b/scripts/qmp/qom-list
@@ -4,7 +4,7 @@ import os
 import sys
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp.qom import QOMList
+from qemu.utils.qom import QOMList
 
 
 if __name__ == '__main__':
diff --git a/scripts/qmp/qom-set b/scripts/qmp/qom-set
index 9ca9e2ba10..06820feec4 100755
--- a/scripts/qmp/qom-set
+++ b/scripts/qmp/qom-set
@@ -4,7 +4,7 @@ import os
 import sys
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp.qom import QOMSet
+from qemu.utils.qom import QOMSet
 
 
 if __name__ == '__main__':
diff --git 

[PATCH v3 05/31] python/aqmp: fix docstring typo

2022-01-10 Thread John Snow
Reported-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: John Snow 
---
 python/qemu/aqmp/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/python/qemu/aqmp/__init__.py b/python/qemu/aqmp/__init__.py
index 880d5b6fa7..173556404d 100644
--- a/python/qemu/aqmp/__init__.py
+++ b/python/qemu/aqmp/__init__.py
@@ -6,7 +6,7 @@
 QEMU Guest Agent, and the QEMU Storage Daemon.
 
 `QMPClient` provides the main functionality of this package. All errors
-raised by this library dervive from `AQMPError`, see `aqmp.error` for
+raised by this library derive from `AQMPError`, see `aqmp.error` for
 additional detail. See `aqmp.events` for an in-depth tutorial on
 managing QMP events.
 """
-- 
2.31.1




[PATCH v3 04/31] simplebench: Fix Python syntax error (reported by LGTM)

2022-01-10 Thread John Snow
From: Stefan Weil 

Fixes: b2fcb0c5754c2554b8406376e99a75e9e0a6b7bd
Signed-off-by: Stefan Weil 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: John Snow 
Message-id: 20220107153019.504124-1...@weilnetz.de
Signed-off-by: John Snow 
---
 scripts/simplebench/bench-example.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/simplebench/bench-example.py 
b/scripts/simplebench/bench-example.py
index 4864435f39..fc370691e0 100644
--- a/scripts/simplebench/bench-example.py
+++ b/scripts/simplebench/bench-example.py
@@ -25,7 +25,7 @@
 
 def bench_func(env, case):
 """ Handle one "cell" of benchmarking table. """
-return bench_block_copy(env['qemu_binary'], env['cmd'], {}
+return bench_block_copy(env['qemu_binary'], env['cmd'], {},
 case['source'], case['target'])
 
 
-- 
2.31.1




[PATCH v3 07/31] python/aqmp: handle asyncio.TimeoutError on execute()

2022-01-10 Thread John Snow
This exception can be injected into any await statement. If we are
canceled via timeout, we want to clear the pending execution record on
our way out.

Signed-off-by: John Snow 
Reviewed-by: Beraldo Leal 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 python/qemu/aqmp/qmp_client.py | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/python/qemu/aqmp/qmp_client.py b/python/qemu/aqmp/qmp_client.py
index 8105e29fa8..6a985ffe30 100644
--- a/python/qemu/aqmp/qmp_client.py
+++ b/python/qemu/aqmp/qmp_client.py
@@ -435,7 +435,11 @@ async def _issue(self, msg: Message) -> Union[None, str]:
 msg_id = msg['id']
 
 self._pending[msg_id] = asyncio.Queue(maxsize=1)
-await self._outgoing.put(msg)
+try:
+await self._outgoing.put(msg)
+except:
+del self._pending[msg_id]
+raise
 
 return msg_id
 
@@ -452,9 +456,9 @@ async def _reply(self, msg_id: Union[str, None]) -> Message:
 was lost, or some other problem.
 """
 queue = self._pending[msg_id]
-result = await queue.get()
 
 try:
+result = await queue.get()
 if isinstance(result, ExecInterruptedError):
 raise result
 return result
-- 
2.31.1




[PATCH v3 11/31] python/qemu-ga-client: don't use deprecated CLI syntax in usage comment

2022-01-10 Thread John Snow
Cleanup related to commit ccd3b3b8112b670f, "qemu-option: warn for
short-form boolean options".

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Daniel P. Berrangé 
---
 python/qemu/qmp/qemu_ga_client.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/python/qemu/qmp/qemu_ga_client.py 
b/python/qemu/qmp/qemu_ga_client.py
index 67ac0b4211..b3e1d98c9e 100644
--- a/python/qemu/qmp/qemu_ga_client.py
+++ b/python/qemu/qmp/qemu_ga_client.py
@@ -5,7 +5,7 @@
 
 Start QEMU with:
 
-# qemu [...] -chardev socket,path=/tmp/qga.sock,server,wait=off,id=qga0 \
+# qemu [...] -chardev socket,path=/tmp/qga.sock,server=on,wait=off,id=qga0 \
   -device virtio-serial \
   -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
 
-- 
2.31.1




[PATCH v3 00/31] Python: delete synchronous qemu.qmp package

2022-01-10 Thread John Snow
Based-on: <20220110232521.1922962-1-js...@redhat.com>
  (jsnow/python staging branch)
GitLab: https://gitlab.com/jsnow/qemu/-/commits/python-qmp-legacy-switch
CI: https://gitlab.com/jsnow/qemu/-/pipelines/445163212

Hi, this series is part of an effort to publish the qemu.qmp package on
PyPI. It is the first of three series to complete this work:

--> (1) Switch the new Async QMP library in to python/qemu/qmp
(2) Fork python/qemu/qmp out into its own repository,
with updated GitLab CI/CD targets to build packages.
(3) Update qemu.git to install qemu.qmp from PyPI,
and then delete python/qemu/qmp.

This series swaps out qemu.qmp for qemu.aqmp permanently, instead of
hiding it behind an environment variable toggle. This leaves us with
just one QMP library to worry about. It also implements the rename of
"qemu.aqmp" to "qemu.qmp".

I suspect the most potential disruption to iotest and avocado
maintainers, as those two subsystems rely on the QMP features the
most. Would appreciate at least an ACK from each of those camps if
you're willing to give benefit-of-the-doubt on the actual Python code.

V3:
 - Rebased on top of jsnow/python (For GitLab CI fixes)
 - Added a new patch 001 to fix a typo Vladimir found.
 - Tiny change in 006 due to the new patch 001
 - Reworded subject of patch 007
 - Changed import statement in patch 013 (Vladimir)
 - Rebase-related changes in patch 021
 - Removed 'aqmp' from internal variable names in 026
 - Added new patch to rename aqmp-tui to qmp-tui in 027

V2:
 - Integrate the renaming of qemu.aqmp to qemu.qmp in this series
 - Minor bits and pieces.

John Snow (30):
  python/aqmp: use absolute import statement
  Python/aqmp: fix type definitions for mypy 0.920
  python: update type hints for mypy 0.930
  python/aqmp: fix docstring typo
  python/aqmp: add __del__ method to legacy interface
  python/aqmp: handle asyncio.TimeoutError on execute()
  python/aqmp: copy type definitions from qmp
  python/aqmp: add SocketAddrT to package root
  python/aqmp: rename AQMPError to QMPError
  python/qemu-ga-client: don't use deprecated CLI syntax in usage
comment
  python/qmp: switch qemu-ga-client to AQMP
  python/qmp: switch qom tools to AQMP
  python/qmp: switch qmp-shell to AQMP
  python: move qmp utilities to python/qemu/utils
  python: move qmp-shell under the AQMP package
  python/machine: permanently switch to AQMP
  scripts/cpu-x86-uarch-abi: fix CLI parsing
  scripts/cpu-x86-uarch-abi: switch to AQMP
  scripts/render-block-graph: switch to AQMP
  scripts/bench-block-job: switch to AQMP
  iotests/mirror-top-perms: switch to AQMP
  iotests: switch to AQMP
  python: temporarily silence pylint duplicate-code warnings
  python/aqmp: take QMPBadPortError and parse_address from qemu.qmp
  python/aqmp: fully separate from qmp.QEMUMonitorProtocol
  python/aqmp: copy qmp docstrings to qemu.aqmp.legacy
  python: remove the old QMP package
  python: re-enable pylint duplicate-code warnings
  python: rename qemu.aqmp to qemu.qmp
  python: rename 'aqmp-tui' to 'qmp-tui'

Stefan Weil (1):
  simplebench: Fix Python syntax error (reported by LGTM)

 python/qemu/qmp/README.rst|   9 -
 python/qemu/aqmp/__init__.py  |  51 --
 python/qemu/aqmp/legacy.py| 138 --
 python/qemu/aqmp/py.typed |   0
 python/qemu/machine/machine.py|  18 +-
 python/qemu/machine/qtest.py  |   2 +-
 python/qemu/qmp/__init__.py   | 441 ++
 python/qemu/{aqmp => qmp}/error.py|  12 +-
 python/qemu/{aqmp => qmp}/events.py   |   6 +-
 python/qemu/qmp/legacy.py | 319 +
 python/qemu/{aqmp => qmp}/message.py  |   0
 python/qemu/{aqmp => qmp}/models.py   |   0
 python/qemu/{aqmp => qmp}/protocol.py |  33 +-
 python/qemu/{aqmp => qmp}/qmp_client.py   |  32 +-
 python/qemu/qmp/qmp_shell.py  |  31 +-
 .../qemu/{aqmp/aqmp_tui.py => qmp/qmp_tui.py} |  14 +-
 python/qemu/{aqmp => qmp}/util.py |   0
 python/qemu/{qmp => utils}/qemu_ga_client.py  |  24 +-
 python/qemu/{qmp => utils}/qom.py |   5 +-
 python/qemu/{qmp => utils}/qom_common.py  |   9 +-
 python/qemu/{qmp => utils}/qom_fuse.py|  11 +-
 python/setup.cfg  |  23 +-
 python/tests/protocol.py  |  14 +-
 scripts/cpu-x86-uarch-abi.py  |   7 +-
 scripts/device-crash-test |   4 +-
 scripts/qmp/qemu-ga-client|   2 +-
 scripts/qmp/qom-fuse  |   2 +-
 scripts/qmp/qom-get   |   2 +-
 scripts/qmp/qom-list  |   2 +-
 scripts/qmp/qom-set   |   2 +-
 scripts/qmp/qom-tree  |   2 +-
 scripts/render_block_graph.py |   8 +-
 scripts/simplebench/bench-example.py  

[PATCH v3 03/31] python: update type hints for mypy 0.930

2022-01-10 Thread John Snow
Mypy 0.930, released Dec 22, changes the way argparse objects are
considered. Crafting a definition that works under Python 3.6 and an
older mypy alongside newer versions simultaneously is ... difficult,
so... eh. Stub it out with an 'Any' definition to get the CI moving
again.

Oh well.

Signed-off-by: John Snow 
Message-id: 20220110191349.1841027-4-js...@redhat.com
Signed-off-by: John Snow 
---
 python/qemu/qmp/qom_common.py | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/python/qemu/qmp/qom_common.py b/python/qemu/qmp/qom_common.py
index a59ae1a2a1..2e4c741f77 100644
--- a/python/qemu/qmp/qom_common.py
+++ b/python/qemu/qmp/qom_common.py
@@ -30,10 +30,6 @@
 from . import QEMUMonitorProtocol, QMPError
 
 
-# The following is needed only for a type alias.
-Subparsers = argparse._SubParsersAction  # pylint: disable=protected-access
-
-
 class ObjectPropertyInfo:
 """
 Represents the return type from e.g. qom-list.
@@ -89,7 +85,7 @@ def __init__(self, args: argparse.Namespace):
 self.qmp.connect()
 
 @classmethod
-def register(cls, subparsers: Subparsers) -> None:
+def register(cls, subparsers: Any) -> None:
 """
 Register this command with the argument parser.
 
-- 
2.31.1




[PATCH v3 09/31] python/aqmp: add SocketAddrT to package root

2022-01-10 Thread John Snow
It's a commonly needed definition, it can be re-exported by the root.

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Beraldo Leal 
---
 python/qemu/aqmp/__init__.py | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/python/qemu/aqmp/__init__.py b/python/qemu/aqmp/__init__.py
index 173556404d..05f467c141 100644
--- a/python/qemu/aqmp/__init__.py
+++ b/python/qemu/aqmp/__init__.py
@@ -26,7 +26,12 @@
 from .error import AQMPError
 from .events import EventListener
 from .message import Message
-from .protocol import ConnectError, Runstate, StateError
+from .protocol import (
+ConnectError,
+Runstate,
+SocketAddrT,
+StateError,
+)
 from .qmp_client import ExecInterruptedError, ExecuteError, QMPClient
 
 
@@ -48,4 +53,7 @@
 'ConnectError',
 'ExecuteError',
 'ExecInterruptedError',
+
+# Type aliases
+'SocketAddrT',
 )
-- 
2.31.1




[PATCH v3 02/31] Python/aqmp: fix type definitions for mypy 0.920

2022-01-10 Thread John Snow
0.920 (Released 2021-12-15) is not entirely happy with the
way that I was defining _FutureT:

qemu/aqmp/protocol.py:601: error: Item "object" of the upper bound
"Optional[Future[Any]]" of type variable "_FutureT" has no attribute
"done"

Update it with something a little mechanically simpler that works better
across a wider array of mypy versions.

Signed-off-by: John Snow 
Message-id: 20220110191349.1841027-3-js...@redhat.com
Signed-off-by: John Snow 
---
 python/qemu/aqmp/protocol.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/aqmp/protocol.py
index 5190b33b13..c4fbe35a0e 100644
--- a/python/qemu/aqmp/protocol.py
+++ b/python/qemu/aqmp/protocol.py
@@ -43,8 +43,8 @@
 
 
 T = TypeVar('T')
+_U = TypeVar('_U')
 _TaskFN = Callable[[], Awaitable[None]]  # aka ``async def func() -> None``
-_FutureT = TypeVar('_FutureT', bound=Optional['asyncio.Future[Any]'])
 
 
 class Runstate(Enum):
@@ -591,7 +591,8 @@ def _cleanup(self) -> None:
 """
 Fully reset this object to a clean state and return to `IDLE`.
 """
-def _paranoid_task_erase(task: _FutureT) -> Optional[_FutureT]:
+def _paranoid_task_erase(task: Optional['asyncio.Future[_U]']
+ ) -> Optional['asyncio.Future[_U]']:
 # Help to erase a task, ENSURING it is fully quiesced first.
 assert (task is None) or task.done()
 return None if (task and task.done()) else task
-- 
2.31.1




[PULL 2/4] Python/aqmp: fix type definitions for mypy 0.920

2022-01-10 Thread John Snow
0.920 (Released 2021-12-15) is not entirely happy with the
way that I was defining _FutureT:

qemu/aqmp/protocol.py:601: error: Item "object" of the upper bound
"Optional[Future[Any]]" of type variable "_FutureT" has no attribute
"done"

Update it with something a little mechanically simpler that works better
across a wider array of mypy versions.

Signed-off-by: John Snow 
Message-id: 20220110191349.1841027-3-js...@redhat.com
Signed-off-by: John Snow 
---
 python/qemu/aqmp/protocol.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/aqmp/protocol.py
index 5190b33b13..c4fbe35a0e 100644
--- a/python/qemu/aqmp/protocol.py
+++ b/python/qemu/aqmp/protocol.py
@@ -43,8 +43,8 @@
 
 
 T = TypeVar('T')
+_U = TypeVar('_U')
 _TaskFN = Callable[[], Awaitable[None]]  # aka ``async def func() -> None``
-_FutureT = TypeVar('_FutureT', bound=Optional['asyncio.Future[Any]'])
 
 
 class Runstate(Enum):
@@ -591,7 +591,8 @@ def _cleanup(self) -> None:
 """
 Fully reset this object to a clean state and return to `IDLE`.
 """
-def _paranoid_task_erase(task: _FutureT) -> Optional[_FutureT]:
+def _paranoid_task_erase(task: Optional['asyncio.Future[_U]']
+ ) -> Optional['asyncio.Future[_U]']:
 # Help to erase a task, ENSURING it is fully quiesced first.
 assert (task is None) or task.done()
 return None if (task and task.done()) else task
-- 
2.31.1




[PATCH v3 01/31] python/aqmp: use absolute import statement

2022-01-10 Thread John Snow
pylint's dependency astroid appears to have bugs in 2.9.1 and 2.9.2 (Dec
31 and Jan 3) that appear to erroneously expect the qemu namespace to
have an __init__.py file. astroid 2.9.3 (Jan 9) avoids that problem, but
appears to not understand a relative import within a namespace package.

Update the relative import - it was worth changing anyway, because these
packages will eventually be packaged and distributed separately.

Signed-off-by: John Snow 
Message-id: 20220110191349.1841027-2-js...@redhat.com
Signed-off-by: John Snow 
---
 python/qemu/aqmp/aqmp_tui.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py
index a2929f771c..f1e926dd75 100644
--- a/python/qemu/aqmp/aqmp_tui.py
+++ b/python/qemu/aqmp/aqmp_tui.py
@@ -35,7 +35,8 @@
 import urwid
 import urwid_readline
 
-from ..qmp import QEMUMonitorProtocol, QMPBadPortError
+from qemu.qmp import QEMUMonitorProtocol, QMPBadPortError
+
 from .error import ProtocolError
 from .message import DeserializationError, Message, UnexpectedTypeError
 from .protocol import ConnectError, Runstate
-- 
2.31.1




[PULL 1/4] python/aqmp: use absolute import statement

2022-01-10 Thread John Snow
pylint's dependency astroid appears to have bugs in 2.9.1 and 2.9.2 (Dec
31 and Jan 3) that appear to erroneously expect the qemu namespace to
have an __init__.py file. astroid 2.9.3 (Jan 9) avoids that problem, but
appears to not understand a relative import within a namespace package.

Update the relative import - it was worth changing anyway, because these
packages will eventually be packaged and distributed separately.

Signed-off-by: John Snow 
Reviewed-by: Beraldo Leal 
Message-id: 20220110191349.1841027-2-js...@redhat.com
Signed-off-by: John Snow 
---
 python/qemu/aqmp/aqmp_tui.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py
index a2929f771c..f1e926dd75 100644
--- a/python/qemu/aqmp/aqmp_tui.py
+++ b/python/qemu/aqmp/aqmp_tui.py
@@ -35,7 +35,8 @@
 import urwid
 import urwid_readline
 
-from ..qmp import QEMUMonitorProtocol, QMPBadPortError
+from qemu.qmp import QEMUMonitorProtocol, QMPBadPortError
+
 from .error import ProtocolError
 from .message import DeserializationError, Message, UnexpectedTypeError
 from .protocol import ConnectError, Runstate
-- 
2.31.1




[PULL 3/4] python: update type hints for mypy 0.930

2022-01-10 Thread John Snow
Mypy 0.930, released Dec 22, changes the way argparse objects are
considered. Crafting a definition that works under Python 3.6 and an
older mypy alongside newer versions simultaneously is ... difficult,
so... eh. Stub it out with an 'Any' definition to get the CI moving
again.

Oh well.

Signed-off-by: John Snow 
Reviewed-by: Beraldo Leal 
Message-id: 20220110191349.1841027-4-js...@redhat.com
Signed-off-by: John Snow 
---
 python/qemu/qmp/qom_common.py | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/python/qemu/qmp/qom_common.py b/python/qemu/qmp/qom_common.py
index a59ae1a2a1..2e4c741f77 100644
--- a/python/qemu/qmp/qom_common.py
+++ b/python/qemu/qmp/qom_common.py
@@ -30,10 +30,6 @@
 from . import QEMUMonitorProtocol, QMPError
 
 
-# The following is needed only for a type alias.
-Subparsers = argparse._SubParsersAction  # pylint: disable=protected-access
-
-
 class ObjectPropertyInfo:
 """
 Represents the return type from e.g. qom-list.
@@ -89,7 +85,7 @@ def __init__(self, args: argparse.Namespace):
 self.qmp.connect()
 
 @classmethod
-def register(cls, subparsers: Subparsers) -> None:
+def register(cls, subparsers: Any) -> None:
 """
 Register this command with the argument parser.
 
-- 
2.31.1




[PULL 4/4] simplebench: Fix Python syntax error (reported by LGTM)

2022-01-10 Thread John Snow
From: Stefan Weil 

Fixes: b2fcb0c5754c2554b8406376e99a75e9e0a6b7bd
Signed-off-by: Stefan Weil 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: John Snow 
Message-id: 20220107153019.504124-1...@weilnetz.de
Signed-off-by: John Snow 
---
 scripts/simplebench/bench-example.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/simplebench/bench-example.py 
b/scripts/simplebench/bench-example.py
index 4864435f39..fc370691e0 100644
--- a/scripts/simplebench/bench-example.py
+++ b/scripts/simplebench/bench-example.py
@@ -25,7 +25,7 @@
 
 def bench_func(env, case):
 """ Handle one "cell" of benchmarking table. """
-return bench_block_copy(env['qemu_binary'], env['cmd'], {}
+return bench_block_copy(env['qemu_binary'], env['cmd'], {},
 case['source'], case['target'])
 
 
-- 
2.31.1




[PULL 0/4] Python patches

2022-01-10 Thread John Snow
The following changes since commit de3f5223fa4cf8bfc5e3fe1fd495ddf468edcdf7:

  Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-7.0-pull-request' 
into staging (2022-01-10 14:43:03 +)

are available in the Git repository at:

  https://gitlab.com/jsnow/qemu.git tags/python-pull-request

for you to fetch changes up to 9ebfc5a583d8aa94bf1bc37c1f71559187fd809c:

  simplebench: Fix Python syntax error (reported by LGTM) (2022-01-10 18:23:10 
-0500)


Python pull request

Fixes for the tests that broke during vacation, plus a simple syntax fix
for a python script.



John Snow (3):
  python/aqmp: use absolute import statement
  Python/aqmp: fix type definitions for mypy 0.920
  python: update type hints for mypy 0.930

Stefan Weil (1):
  simplebench: Fix Python syntax error (reported by LGTM)

 python/qemu/aqmp/aqmp_tui.py | 3 ++-
 python/qemu/aqmp/protocol.py | 5 +++--
 python/qemu/qmp/qom_common.py| 6 +-
 scripts/simplebench/bench-example.py | 2 +-
 4 files changed, 7 insertions(+), 9 deletions(-)

-- 
2.31.1





Re: [PATCH 1/2] riscv: opentitan: fixup plic stride len

2022-01-10 Thread Wilfred Mallawa
On Mon, 2022-01-10 at 15:34 +0800, Bin Meng wrote:
> CAUTION: This email originated from outside of Western Digital. Do
> not click on links or open attachments unless you recognize the
> sender and know that the content is safe.
> 
> 
> On Mon, Jan 10, 2022 at 2:13 PM Alistair Francis
>  wrote:
> > 
> > From: Wilfred Mallawa 
> > 
> > The following change was made to rectify incorrectly set stride
> > length
> > on the PLIC. Where it should be 32bit and not 24bit (0x18). This
> > was
> 
> PLIC [1]
Thanks, will add this in.
> 
> > discovered whilst attempting to fix a bug where a timer_interrupt
> > was
> > not serviced on TockOS-OpenTitan.
> > 
> 
> [1]
> https://docs.opentitan.org/hw/top_earlgrey/ip_autogen/rv_plic/doc/
> 
> > Signed-off-by: Wilfred Mallawa 
> > ---
> >  hw/riscv/opentitan.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> 
> Reviewed-by: Bin Meng 



Re: [PATCH v4 02/12] target/riscv: Add target/riscv/kvm.c to place the public kvm interface

2022-01-10 Thread Alistair Francis
On Mon, Jan 10, 2022 at 11:48 AM Yifei Jiang via  wrote:
>
> Add target/riscv/kvm.c to place kvm_arch_* function needed by
> kvm/kvm-all.c. Meanwhile, add kvm support in meson.build file.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Mingwang Li 
> Reviewed-by: Alistair Francis 
> Reviewed-by: Anup Patel 
> ---
>  meson.build  |   2 +
>  target/riscv/kvm.c   | 133 +++
>  target/riscv/meson.build |   1 +
>  3 files changed, 136 insertions(+)
>  create mode 100644 target/riscv/kvm.c
>
> diff --git a/meson.build b/meson.build
> index 53065e96ec..7eaec31a3a 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -90,6 +90,8 @@ elif cpu in ['ppc', 'ppc64']
>kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
>  elif cpu in ['mips', 'mips64']
>kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 
> 'mips64el-softmmu']
> +elif cpu in ['riscv']
> +  kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
>  else
>kvm_targets = []
>  endif

Can you add this as a separate commit at the end of the series?

That way we have implemented KVM support before we enable it for users.

Alistair



Re: [PATCH v4 05/12] target/riscv: Implement kvm_arch_put_registers

2022-01-10 Thread Alistair Francis
On Mon, Jan 10, 2022 at 11:57 AM Yifei Jiang via  wrote:
>
> Put GPR CSR and FP registers to kvm by KVM_SET_ONE_REG ioctl
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Mingwang Li 
> Reviewed-by: Alistair Francis 
> Reviewed-by: Anup Patel 
> ---
>  target/riscv/kvm.c | 104 -
>  1 file changed, 103 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
> index 6d4df0ef6d..e695b91dc7 100644
> --- a/target/riscv/kvm.c
> +++ b/target/riscv/kvm.c
> @@ -73,6 +73,14 @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, 
> uint64_t type, uint64_t idx
>  } \
>  } while(0)
>
> +#define KVM_RISCV_SET_CSR(cs, env, csr, reg) \
> +do { \
> +int ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, csr), ); \
> +if (ret) { \
> +return ret; \
> +} \
> +} while(0)

This fails checkpatch. I know there is lots of QEMU code like this,
but it probably should be `while (0)` to keep checkpatch happy.

Please run checkpatch on all the patches.

Alistair



Re: [PATCH v11 06/10] ACPI ERST: build the ACPI ERST table

2022-01-10 Thread Eric DeVolder

Thanks for looking at this Michael, I've an inline response below.
eric

On 1/6/22 04:45, Michael S. Tsirkin wrote:

On Wed, Dec 15, 2021 at 10:38:11AM -0500, Eric DeVolder wrote:

This builds the ACPI ERST table to inform OSPM how to communicate
with the acpi-erst device.

Signed-off-by: Eric DeVolder 
---
  hw/acpi/erst.c | 188 +
  1 file changed, 188 insertions(+)

diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c
index bb6cad4..05177b3 100644
--- a/hw/acpi/erst.c
+++ b/hw/acpi/erst.c
@@ -59,6 +59,27 @@
  #define STATUS_RECORD_STORE_EMPTY 0x04
  #define STATUS_RECORD_NOT_FOUND   0x05
  
+/* ACPI 4.0: Table 17-19 Serialization Instructions */

+#define INST_READ_REGISTER 0x00
+#define INST_READ_REGISTER_VALUE   0x01
+#define INST_WRITE_REGISTER0x02
+#define INST_WRITE_REGISTER_VALUE  0x03
+#define INST_NOOP  0x04
+#define INST_LOAD_VAR1 0x05
+#define INST_LOAD_VAR2 0x06
+#define INST_STORE_VAR10x07
+#define INST_ADD   0x08
+#define INST_SUBTRACT  0x09
+#define INST_ADD_VALUE 0x0A
+#define INST_SUBTRACT_VALUE0x0B
+#define INST_STALL 0x0C
+#define INST_STALL_WHILE_TRUE  0x0D
+#define INST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E
+#define INST_GOTO  0x0F
+#define INST_SET_SRC_ADDRESS_BASE  0x10
+#define INST_SET_DST_ADDRESS_BASE  0x11
+#define INST_MOVE_DATA 0x12
+
  /* UEFI 2.1: Appendix N Common Platform Error Record */
  #define UEFI_CPER_RECORD_MIN_SIZE 128U
  #define UEFI_CPER_RECORD_LENGTH_OFFSET 20U
@@ -172,6 +193,173 @@ typedef struct {
  
  /***/

  /***/
+
+/* ACPI 4.0: 17.4.1.2 Serialization Instruction Entries */
+static void build_serialization_instruction_entry(GArray *table_data,
+uint8_t serialization_action,
+uint8_t instruction,
+uint8_t flags,
+uint8_t register_bit_width,
+uint64_t register_address,
+uint64_t value)
+{
+/* ACPI 4.0: Table 17-18 Serialization Instruction Entry */
+struct AcpiGenericAddress gas;
+uint64_t mask;
+
+/* Serialization Action */
+build_append_int_noprefix(table_data, serialization_action, 1);
+/* Instruction */
+build_append_int_noprefix(table_data, instruction , 1);
+/* Flags */
+build_append_int_noprefix(table_data, flags   , 1);
+/* Reserved */
+build_append_int_noprefix(table_data, 0   , 1);
+/* Register Region */
+gas.space_id = AML_SYSTEM_MEMORY;
+gas.bit_width = register_bit_width;
+gas.bit_offset = 0;
+gas.access_width = ctz32(register_bit_width) - 2;
+gas.address = register_address;
+build_append_gas_from_struct(table_data, );
+/* Value */
+build_append_int_noprefix(table_data, value  , 8);
+/* Mask */
+mask = (1ULL << (register_bit_width - 1) << 1) - 1;
+build_append_int_noprefix(table_data, mask  , 8);
+}
+
+/* ACPI 4.0: 17.4.1 Serialization Action Table */
+void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
+const char *oem_id, const char *oem_table_id)
+{
+GArray *table_instruction_data;
+unsigned action;
+pcibus_t bar0 = pci_get_bar_addr(PCI_DEVICE(erst_dev), 0);
+AcpiTable table = { .sig = "ERST", .rev = 1, .oem_id = oem_id,
+.oem_table_id = oem_table_id };
+
+trace_acpi_erst_pci_bar_0(bar0);
+
+/*
+ * Serialization Action Table
+ * The serialization action table must be generated first
+ * so that its size can be known in order to populate the
+ * Instruction Entry Count field.
+ */
+table_instruction_data = g_array_new(FALSE, FALSE, sizeof(char));
+
+/*
+ * Macros for use with construction of the action instructions
+ */
+#define build_read_register(action, width_in_bits, reg) \
+build_serialization_instruction_entry(table_instruction_data, \
+action, INST_READ_REGISTER, 0, width_in_bits, \
+bar0 + reg, 0)
+
+#define build_read_register_value(action, width_in_bits, reg, value) \
+build_serialization_instruction_entry(table_instruction_data, \
+action, INST_READ_REGISTER_VALUE, 0, width_in_bits, \
+bar0 + reg, value)
+
+#define build_write_register(action, width_in_bits, reg, value) \
+build_serialization_instruction_entry(table_instruction_data, \
+action, INST_WRITE_REGISTER, 0, width_in_bits, \
+bar0 + reg, value)
+
+#define build_write_register_value(action, width_in_bits, reg, value) \
+build_serialization_instruction_entry(table_instruction_data, \
+action, INST_WRITE_REGISTER_VALUE, 0, width_in_bits, \
+bar0 + reg, value)

Re: /usr/shared/qemu binaries

2022-01-10 Thread Liviu Ionescu



> On 11 Jan 2022, at 00:55, Alistair Francis  wrote:
> 
> they are referred to internally,

Ok, so things are a bit more complicated than I hoped.

I'll search for the names in the source code, and keep those referred 
internally.


Thank you,

Liviu




Re: [PATCH v4 11/11] hw/riscv: virt: Add PMU DT node to the device tree

2022-01-10 Thread Atish Kumar Patra
On Sun, Jan 9, 2022 at 11:55 PM Bin Meng  wrote:
>
> On Fri, Jan 7, 2022 at 10:27 AM Atish Patra  wrote:
> >
> > Qemu virt machine can support few cache events and cycle/instret counters.
> > It also supports counter overflow for these events.
> >
> > Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
> > capabilities. There are some dummy nodes added for testing as well.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  hw/riscv/virt.c| 38 ++
> >  target/riscv/pmu.c | 45 +
> >  target/riscv/pmu.h |  1 +
> >  3 files changed, 84 insertions(+)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index 3af074148ef4..99154199091c 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -28,6 +28,7 @@
> >  #include "hw/qdev-properties.h"
> >  #include "hw/char/serial.h"
> >  #include "target/riscv/cpu.h"
> > +#include "target/riscv/pmu.h"
> >  #include "hw/riscv/riscv_hart.h"
> >  #include "hw/riscv/virt.h"
> >  #include "hw/riscv/boot.h"
> > @@ -406,6 +407,33 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
> >  g_free(plic_cells);
> >  }
> >
> > +static void create_fdt_socket_pmu(RISCVVirtState *s,
> > +  int socket, uint32_t *phandle,
> > +  uint32_t *intc_phandles)
> > +{
> > +int cpu;
> > +char *pmu_name;
> > +uint32_t *pmu_cells;
> > +MachineState *mc = MACHINE(s);
> > +RISCVCPU hart = s->soc[socket].harts[0];
> > +
> > +pmu_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
> > +
> > +for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
> > +pmu_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
> > +pmu_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_PMU_OVF);
> > +}
> > +
> > +pmu_name = g_strdup_printf("/soc/pmu");
> > +qemu_fdt_add_subnode(mc->fdt, pmu_name);
> > +qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
> > +riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
> > +
> > +g_free(pmu_name);
> > +g_free(pmu_cells);
> > +}
> > +
> > +
> >  static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry 
> > *memmap,
> > bool is_32_bit, uint32_t *phandle,
> > uint32_t *irq_mmio_phandle,
> > @@ -417,12 +445,20 @@ static void create_fdt_sockets(RISCVVirtState *s, 
> > const MemMapEntry *memmap,
> >  uint32_t *intc_phandles;
> >  MachineState *mc = MACHINE(s);
> >  uint32_t xplic_phandles[MAX_NODES];
> > +RISCVCPU hart;
> >
> >  qemu_fdt_add_subnode(mc->fdt, "/cpus");
> >  qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency",
> >RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
> >  qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#size-cells", 0x0);
> >  qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#address-cells", 0x1);
> > +
> > +/* Add the node for isa extensions discovery */
> > +qemu_fdt_add_subnode(mc->fdt, "/cpus/riscv,isa-ext");
>
> Looks like the ongoing discussion does not support this idea
> https://lore.kernel.org/linux-riscv/20211224211632.1698523-1-ati...@rivosinc.com/
>

Yes. Palmer's comment arrived after I sent out the Qemu series. I will
fix that in the next
version once we have string parsing (riscv,isa) ready.

> > +hart = s->soc[0].harts[0];
> > +if (hart.cfg.ext_sscof) {
> > +qemu_fdt_setprop(mc->fdt, "/cpus/riscv,isa-ext", "sscofpmf", NULL, 
> > 0);
> > +}
> >  qemu_fdt_add_subnode(mc->fdt, "/cpus/cpu-map");
> >
> >  for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
> > @@ -445,6 +481,8 @@ static void create_fdt_sockets(RISCVVirtState *s, const 
> > MemMapEntry *memmap,
> >  create_fdt_socket_plic(s, memmap, socket, phandle,
> >  intc_phandles, xplic_phandles);
> >
> > +create_fdt_socket_pmu(s, socket, phandle, intc_phandles);
> > +
> >  g_free(intc_phandles);
> >  g_free(clust_name);
> >  }
> > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > index 15f161059fb7..b58a09c85616 100644
> > --- a/target/riscv/pmu.c
> > +++ b/target/riscv/pmu.c
> > @@ -19,11 +19,56 @@
> >  #include "qemu/osdep.h"
> >  #include "cpu.h"
> >  #include "pmu.h"
> > +#include "sysemu/device_tree.h"
> >
> >  #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
> >  #define MAKE_32BIT_MASK(shift, length) \
> >  (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
> >
> > +/**
> > + * To keep it simple, any event can be mapped to any programmable counters 
> > in
> > + * QEMU. The generic cycle & instruction count events can also be monitored
> > + * using programmable counters. In that case, mcycle & minstret must 
> > continue
> > + * to provide the correct value as well. Hetergenous PMU per hart is not
>
> typo of Heterogeneous
>
> > + * supported yet. 

[PATCH v12 6/9] ACPI ERST: build the ACPI ERST table

2022-01-10 Thread Eric DeVolder
This builds the ACPI ERST table to inform OSPM how to communicate
with the acpi-erst device.

Signed-off-by: Eric DeVolder 
---
 hw/acpi/erst.c | 188 +
 1 file changed, 188 insertions(+)

diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c
index bb6cad4..00dbd8be 100644
--- a/hw/acpi/erst.c
+++ b/hw/acpi/erst.c
@@ -59,6 +59,27 @@
 #define STATUS_RECORD_STORE_EMPTY 0x04
 #define STATUS_RECORD_NOT_FOUND   0x05
 
+/* ACPI 4.0: Table 17-19 Serialization Instructions */
+#define INST_READ_REGISTER 0x00
+#define INST_READ_REGISTER_VALUE   0x01
+#define INST_WRITE_REGISTER0x02
+#define INST_WRITE_REGISTER_VALUE  0x03
+#define INST_NOOP  0x04
+#define INST_LOAD_VAR1 0x05
+#define INST_LOAD_VAR2 0x06
+#define INST_STORE_VAR10x07
+#define INST_ADD   0x08
+#define INST_SUBTRACT  0x09
+#define INST_ADD_VALUE 0x0A
+#define INST_SUBTRACT_VALUE0x0B
+#define INST_STALL 0x0C
+#define INST_STALL_WHILE_TRUE  0x0D
+#define INST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E
+#define INST_GOTO  0x0F
+#define INST_SET_SRC_ADDRESS_BASE  0x10
+#define INST_SET_DST_ADDRESS_BASE  0x11
+#define INST_MOVE_DATA 0x12
+
 /* UEFI 2.1: Appendix N Common Platform Error Record */
 #define UEFI_CPER_RECORD_MIN_SIZE 128U
 #define UEFI_CPER_RECORD_LENGTH_OFFSET 20U
@@ -172,6 +193,173 @@ typedef struct {
 
 /***/
 /***/
+
+/* ACPI 4.0: 17.4.1.2 Serialization Instruction Entries */
+static void build_serialization_instruction_entry(GArray *table_data,
+uint8_t serialization_action,
+uint8_t instruction,
+uint8_t flags,
+uint8_t register_bit_width,
+uint64_t register_address,
+uint64_t value)
+{
+/* ACPI 4.0: Table 17-18 Serialization Instruction Entry */
+struct AcpiGenericAddress gas;
+uint64_t mask;
+
+/* Serialization Action */
+build_append_int_noprefix(table_data, serialization_action, 1);
+/* Instruction */
+build_append_int_noprefix(table_data, instruction , 1);
+/* Flags */
+build_append_int_noprefix(table_data, flags   , 1);
+/* Reserved */
+build_append_int_noprefix(table_data, 0   , 1);
+/* Register Region */
+gas.space_id = AML_SYSTEM_MEMORY;
+gas.bit_width = register_bit_width;
+gas.bit_offset = 0;
+gas.access_width = ctz32(register_bit_width) - 2;
+gas.address = register_address;
+build_append_gas_from_struct(table_data, );
+/* Value */
+build_append_int_noprefix(table_data, value  , 8);
+/* Mask */
+mask = (1ULL << (register_bit_width - 1) << 1) - 1;
+build_append_int_noprefix(table_data, mask  , 8);
+}
+
+/* ACPI 4.0: 17.4.1 Serialization Action Table */
+void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
+const char *oem_id, const char *oem_table_id)
+{
+GArray *table_instruction_data;
+unsigned action;
+pcibus_t bar0 = pci_get_bar_addr(PCI_DEVICE(erst_dev), 0);
+AcpiTable table = { .sig = "ERST", .rev = 1, .oem_id = oem_id,
+.oem_table_id = oem_table_id };
+
+trace_acpi_erst_pci_bar_0(bar0);
+
+/*
+ * Serialization Action Table
+ * The serialization action table must be generated first
+ * so that its size can be known in order to populate the
+ * Instruction Entry Count field.
+ */
+table_instruction_data = g_array_new(FALSE, FALSE, sizeof(char));
+
+/*
+ * Macros for use with construction of the action instructions
+ */
+#define BUILD_READ_REGISTER(width_in_bits, reg) \
+build_serialization_instruction_entry(table_instruction_data, \
+action, INST_READ_REGISTER, 0, width_in_bits, \
+bar0 + reg, 0)
+
+#define BUILD_READ_REGISTER_VALUE(width_in_bits, reg, value) \
+build_serialization_instruction_entry(table_instruction_data, \
+action, INST_READ_REGISTER_VALUE, 0, width_in_bits, \
+bar0 + reg, value)
+
+#define BUILD_WRITE_REGISTER(width_in_bits, reg, value) \
+build_serialization_instruction_entry(table_instruction_data, \
+action, INST_WRITE_REGISTER, 0, width_in_bits, \
+bar0 + reg, value)
+
+#define BUILD_WRITE_REGISTER_VALUE(width_in_bits, reg, value) \
+build_serialization_instruction_entry(table_instruction_data, \
+action, INST_WRITE_REGISTER_VALUE, 0, width_in_bits, \
+bar0 + reg, value)
+
+/* Serialization Instruction Entries */
+action = ACTION_BEGIN_WRITE_OPERATION;
+BUILD_WRITE_REGISTER_VALUE(32, ERST_ACTION_OFFSET, action);
+
+action = ACTION_BEGIN_READ_OPERATION;
+

[PATCH v12 5/9] ACPI ERST: support for ACPI ERST feature

2022-01-10 Thread Eric DeVolder
This implements a PCI device for ACPI ERST. This implements the
non-NVRAM "mode" of operation for ERST as it is supported by
Linux and Windows.

Signed-off-by: Eric DeVolder 
Reviewed-by: Ani Sinha 
---
 hw/acpi/Kconfig  |   6 +
 hw/acpi/erst.c   | 845 +++
 hw/acpi/meson.build  |   1 +
 hw/acpi/trace-events |  15 +
 4 files changed, 867 insertions(+)
 create mode 100644 hw/acpi/erst.c

diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index 622b0b5..19caebd 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -10,6 +10,7 @@ config ACPI_X86
 select ACPI_HMAT
 select ACPI_PIIX4
 select ACPI_PCIHP
+select ACPI_ERST
 
 config ACPI_X86_ICH
 bool
@@ -60,3 +61,8 @@ config ACPI_HW_REDUCED
 select ACPI
 select ACPI_MEMORY_HOTPLUG
 select ACPI_NVDIMM
+
+config ACPI_ERST
+bool
+default y
+depends on ACPI && PCI
diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c
new file mode 100644
index 000..bb6cad4
--- /dev/null
+++ b/hw/acpi/erst.c
@@ -0,0 +1,845 @@
+/*
+ * ACPI Error Record Serialization Table, ERST, Implementation
+ *
+ * ACPI ERST introduced in ACPI 4.0, June 16, 2009.
+ * ACPI Platform Error Interfaces : Error Serialization
+ *
+ * Copyright (c) 2021 Oracle and/or its affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include 
+#include 
+#include 
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-core.h"
+#include "exec/memory.h"
+#include "qom/object.h"
+#include "hw/pci/pci.h"
+#include "qom/object_interfaces.h"
+#include "qemu/error-report.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/acpi-defs.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/bios-linker-loader.h"
+#include "exec/address-spaces.h"
+#include "sysemu/hostmem.h"
+#include "hw/acpi/erst.h"
+#include "trace.h"
+
+/* ACPI 4.0: Table 17-16 Serialization Actions */
+#define ACTION_BEGIN_WRITE_OPERATION 0x0
+#define ACTION_BEGIN_READ_OPERATION  0x1
+#define ACTION_BEGIN_CLEAR_OPERATION 0x2
+#define ACTION_END_OPERATION 0x3
+#define ACTION_SET_RECORD_OFFSET 0x4
+#define ACTION_EXECUTE_OPERATION 0x5
+#define ACTION_CHECK_BUSY_STATUS 0x6
+#define ACTION_GET_COMMAND_STATUS0x7
+#define ACTION_GET_RECORD_IDENTIFIER 0x8
+#define ACTION_SET_RECORD_IDENTIFIER 0x9
+#define ACTION_GET_RECORD_COUNT  0xA
+#define ACTION_BEGIN_DUMMY_WRITE_OPERATION   0xB
+#define ACTION_RESERVED  0xC
+#define ACTION_GET_ERROR_LOG_ADDRESS_RANGE   0xD
+#define ACTION_GET_ERROR_LOG_ADDRESS_LENGTH  0xE
+#define ACTION_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES 0xF
+#define ACTION_GET_EXECUTE_OPERATION_TIMINGS 0x10 /* ACPI 6.3 */
+
+/* ACPI 4.0: Table 17-17 Command Status Definitions */
+#define STATUS_SUCCESS0x00
+#define STATUS_NOT_ENOUGH_SPACE   0x01
+#define STATUS_HARDWARE_NOT_AVAILABLE 0x02
+#define STATUS_FAILED 0x03
+#define STATUS_RECORD_STORE_EMPTY 0x04
+#define STATUS_RECORD_NOT_FOUND   0x05
+
+/* UEFI 2.1: Appendix N Common Platform Error Record */
+#define UEFI_CPER_RECORD_MIN_SIZE 128U
+#define UEFI_CPER_RECORD_LENGTH_OFFSET 20U
+#define UEFI_CPER_RECORD_ID_OFFSET 96U
+#define IS_UEFI_CPER_RECORD(ptr) \
+(((ptr)[0] == 'C') && \
+ ((ptr)[1] == 'P') && \
+ ((ptr)[2] == 'E') && \
+ ((ptr)[3] == 'R'))
+
+/*
+ * NOTE that when accessing CPER fields within a record, memcpy()
+ * is utilized to avoid a possible misaligned access on the host.
+ */
+
+/*
+ * This implementation is an ACTION (cmd) and VALUE (data)
+ * interface consisting of just two 64-bit registers.
+ */
+#define ERST_REG_SIZE (16UL)
+#define ERST_ACTION_OFFSET (0UL) /* action (cmd) */
+#define ERST_VALUE_OFFSET  (8UL) /* argument/value (data) */
+
+/*
+ * ERST_RECORD_SIZE is the buffer size for exchanging ERST
+ * record contents. Thus, it defines the maximum record size.
+ * As this is mapped through a PCI BAR, it must be a power of
+ * two and larger than UEFI_CPER_RECORD_MIN_SIZE.
+ * The backing storage is divided into fixed size "slots",
+ * each ERST_RECORD_SIZE in length, and each "slot"
+ * storing a single record. No attempt at optimizing storage
+ * through compression, compaction, etc is attempted.
+ * NOTE that slot 0 is reserved for the backing storage header.
+ * Depending upon the size of the backing storage, additional
+ * slots will be part of the slot 0 header in order to account
+ * for a record_id for each available remaining slot.
+ */
+/* 8KiB records, not too small, not too big */
+#define ERST_RECORD_SIZE (8192UL)
+
+#define ACPI_ERST_MEMDEV_PROP "memdev"
+#define ACPI_ERST_RECORD_SIZE_PROP "record_size"
+
+/*
+ * From the ACPI ERST spec sections:
+ * A record id of all 0s is used to indicate 'unspecified' record id.
+ * A record id of all 1s is used to indicate empty or end.
+ */
+#define 

[PATCH v12 4/9] ACPI ERST: header file for ERST

2022-01-10 Thread Eric DeVolder
This change introduces the public defintions for ACPI ERST.

Signed-off-by: Eric DeVolder 
Reviewed-by: Ani Sinha 
---
 include/hw/acpi/erst.h | 19 +++
 1 file changed, 19 insertions(+)
 create mode 100644 include/hw/acpi/erst.h

diff --git a/include/hw/acpi/erst.h b/include/hw/acpi/erst.h
new file mode 100644
index 000..9d63717
--- /dev/null
+++ b/include/hw/acpi/erst.h
@@ -0,0 +1,19 @@
+/*
+ * ACPI Error Record Serialization Table, ERST, Implementation
+ *
+ * ACPI ERST introduced in ACPI 4.0, June 16, 2009.
+ * ACPI Platform Error Interfaces : Error Serialization
+ *
+ * Copyright (c) 2021 Oracle and/or its affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_ACPI_ERST_H
+#define HW_ACPI_ERST_H
+
+void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
+const char *oem_id, const char *oem_table_id);
+
+#define TYPE_ACPI_ERST "acpi-erst"
+
+#endif
-- 
1.8.3.1




Re: /usr/shared/qemu binaries

2022-01-10 Thread Alistair Francis
On Mon, Jan 10, 2022 at 11:02 PM Liviu Ionescu  wrote:
>
>
>
> > On 10 Jan 2022, at 14:10, Alistair Francis  wrote:
> >
> > My guess would be keep *arm*/*aarch64*, keymaps, npcm7xx_bootrom.bin,
> > efi-* and linuxboot*/multiboot*. That should ensure that everything
> > works for you, but I'm just guessing here.
>
> Do you know if those files are referred internally by QEMU, or the user 
> should provide them in various command options explicitly?

I would expect them to just be referred to by QEMU internally.

>
> About the efi-*.rom files, are they usable on Arm machines too? I thought 
> that they are x86 specific.

They probably are x86 specific, but ARM can use EFI so
I'm not sure how that works.

>
> > If you want to boot Linux on RISC-V QEMU you will need OpenSBI. You
> > can either use these or build and supply your own binaries.
>
> I don't know what to say, my first thought was that if those files can be 
> supplied by the user, I'd rather not include them in the binary distribution.
>
> But if they are referred internally, and in certain configurations QEMU does 
> not start without them, I have to reconsider.

By default they are referred to internally, but if a user specifies
`-bios` when starting QEMU then they will not be used.

Alistair

>
>
> Regards,
>
> Liviu
>



[PATCH v12 9/9] ACPI ERST: bios-tables-test testcase

2022-01-10 Thread Eric DeVolder
This change implements the test suite checks for the ERST table.

Signed-off-by: Eric DeVolder 
Reviewed-by: Ani Sinha 
---
 tests/qtest/bios-tables-test.c | 54 ++
 1 file changed, 54 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index e6b72d9..266b215 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1446,6 +1446,57 @@ static void test_acpi_piix4_tcg_acpi_hmat(void)
 test_acpi_tcg_acpi_hmat(MACHINE_PC);
 }
 
+static void test_acpi_erst(const char *machine)
+{
+gchar *tmp_path = g_dir_make_tmp("qemu-test-erst.XX", NULL);
+gchar *params;
+test_data data;
+
+memset(, 0, sizeof(data));
+data.machine = machine;
+data.variant = ".acpierst";
+params = g_strdup_printf(
+" -object memory-backend-file,id=erstnvram,"
+"mem-path=%s,size=0x1,share=on"
+" -device acpi-erst,memdev=erstnvram", tmp_path);
+test_acpi_one(params, );
+free_test_data();
+g_free(params);
+g_assert(g_rmdir(tmp_path) == 0);
+g_free(tmp_path);
+}
+
+static void test_acpi_piix4_acpi_erst(void)
+{
+test_acpi_erst(MACHINE_PC);
+}
+
+static void test_acpi_q35_acpi_erst(void)
+{
+test_acpi_erst(MACHINE_Q35);
+}
+
+static void test_acpi_microvm_acpi_erst(void)
+{
+gchar *tmp_path = g_dir_make_tmp("qemu-test-erst.XX", NULL);
+gchar *params;
+test_data data;
+
+test_acpi_microvm_prepare();
+data.variant = ".pcie";
+data.tcg_only = true; /* need constant host-phys-bits */
+params = g_strdup_printf(" -machine microvm,"
+"acpi=on,ioapic2=off,rtc=off,pcie=on"
+" -object memory-backend-file,id=erstnvram,"
+   "mem-path=%s,size=0x1,share=on"
+" -device acpi-erst,memdev=erstnvram", tmp_path);
+test_acpi_one(params, );
+g_free(params);
+g_assert(g_rmdir(tmp_path) == 0);
+g_free(tmp_path);
+free_test_data();
+}
+
 static void test_acpi_virt_tcg(void)
 {
 test_data data = {
@@ -1675,6 +1726,8 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
 qtest_add_func("acpi/piix4/acpihmat", test_acpi_piix4_tcg_acpi_hmat);
 qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat);
+qtest_add_func("acpi/piix4/acpierst", test_acpi_piix4_acpi_erst);
+qtest_add_func("acpi/q35/acpierst", test_acpi_q35_acpi_erst);
 qtest_add_func("acpi/microvm", test_acpi_microvm_tcg);
 qtest_add_func("acpi/microvm/usb", test_acpi_microvm_usb_tcg);
 qtest_add_func("acpi/microvm/rtc", test_acpi_microvm_rtc_tcg);
@@ -1684,6 +1737,7 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/q35/ivrs", test_acpi_q35_tcg_ivrs);
 if (strcmp(arch, "x86_64") == 0) {
 qtest_add_func("acpi/microvm/pcie", 
test_acpi_microvm_pcie_tcg);
+qtest_add_func("acpi/microvm/acpierst", 
test_acpi_microvm_acpi_erst);
 }
 }
 if (has_kvm) {
-- 
1.8.3.1




[PATCH v12 1/9] ACPI ERST: bios-tables-test.c steps 1 and 2

2022-01-10 Thread Eric DeVolder
Following the guidelines in tests/qtest/bios-tables-test.c, this
change adds empty placeholder files per step 1 for the new ERST
table, and excludes resulting changed files in bios-tables-test-allowed-diff.h
per step 2.

Signed-off-by: Eric DeVolder 
Acked-by: Igor Mammedov 
---
 tests/data/acpi/microvm/ERST.pcie   | 0
 tests/data/acpi/pc/DSDT.acpierst| 0
 tests/data/acpi/pc/ERST.acpierst| 0
 tests/data/acpi/q35/DSDT.acpierst   | 0
 tests/data/acpi/q35/ERST.acpierst   | 0
 tests/qtest/bios-tables-test-allowed-diff.h | 5 +
 6 files changed, 5 insertions(+)
 create mode 100644 tests/data/acpi/microvm/ERST.pcie
 create mode 100644 tests/data/acpi/pc/DSDT.acpierst
 create mode 100644 tests/data/acpi/pc/ERST.acpierst
 create mode 100644 tests/data/acpi/q35/DSDT.acpierst
 create mode 100644 tests/data/acpi/q35/ERST.acpierst

diff --git a/tests/data/acpi/microvm/ERST.pcie 
b/tests/data/acpi/microvm/ERST.pcie
new file mode 100644
index 000..e69de29
diff --git a/tests/data/acpi/pc/DSDT.acpierst b/tests/data/acpi/pc/DSDT.acpierst
new file mode 100644
index 000..e69de29
diff --git a/tests/data/acpi/pc/ERST.acpierst b/tests/data/acpi/pc/ERST.acpierst
new file mode 100644
index 000..e69de29
diff --git a/tests/data/acpi/q35/DSDT.acpierst 
b/tests/data/acpi/q35/DSDT.acpierst
new file mode 100644
index 000..e69de29
diff --git a/tests/data/acpi/q35/ERST.acpierst 
b/tests/data/acpi/q35/ERST.acpierst
new file mode 100644
index 000..e69de29
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523..603db07 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/pc/DSDT.acpierst",
+"tests/data/acpi/pc/ERST.acpierst",
+"tests/data/acpi/q35/DSDT.acpierst",
+"tests/data/acpi/q35/ERST.acpierst",
+"tests/data/acpi/microvm/ERST.pcie",
-- 
1.8.3.1




[PATCH v12 7/9] ACPI ERST: create ACPI ERST table for pc/x86 machines

2022-01-10 Thread Eric DeVolder
This change exposes ACPI ERST support for x86 guests.

Signed-off-by: Eric DeVolder 
Reviewed-by: Ani Sinha 
---
 hw/i386/acpi-build.c   | 15 +++
 hw/i386/acpi-microvm.c | 15 +++
 include/hw/acpi/erst.h |  5 +
 3 files changed, 35 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ce823e8..ebd47aa 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -43,6 +43,7 @@
 #include "sysemu/tpm.h"
 #include "hw/acpi/tpm.h"
 #include "hw/acpi/vmgenid.h"
+#include "hw/acpi/erst.h"
 #include "sysemu/tpm_backend.h"
 #include "hw/rtc/mc146818rtc_regs.h"
 #include "migration/vmstate.h"
@@ -74,6 +75,8 @@
 #include "hw/acpi/hmat.h"
 #include "hw/acpi/viot.h"
 
+#include CONFIG_DEVICES
+
 /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
  * -M pc-i440fx-2.0.  Even if the actual amount of AML generated grows
  * a little bit, there should be plenty of free space since the DSDT
@@ -2575,6 +2578,18 @@ void acpi_build(AcpiBuildTables *tables, MachineState 
*machine)
 ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
 x86ms->oem_table_id);
 
+#ifdef CONFIG_ACPI_ERST
+{
+Object *erst_dev;
+erst_dev = find_erst_dev();
+if (erst_dev) {
+acpi_add_table(table_offsets, tables_blob);
+build_erst(tables_blob, tables->linker, erst_dev,
+   x86ms->oem_id, x86ms->oem_table_id);
+}
+}
+#endif
+
 vmgenid_dev = find_vmgenid_dev();
 if (vmgenid_dev) {
 acpi_add_table(table_offsets, tables_blob);
diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index 196d318..68ca7e7 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -30,6 +30,7 @@
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/acpi/utils.h"
+#include "hw/acpi/erst.h"
 #include "hw/i386/fw_cfg.h"
 #include "hw/i386/microvm.h"
 #include "hw/pci/pci.h"
@@ -40,6 +41,8 @@
 #include "acpi-common.h"
 #include "acpi-microvm.h"
 
+#include CONFIG_DEVICES
+
 static void acpi_dsdt_add_virtio(Aml *scope,
  MicrovmMachineState *mms)
 {
@@ -207,6 +210,18 @@ static void acpi_build_microvm(AcpiBuildTables *tables,
 ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
 x86ms->oem_table_id);
 
+#ifdef CONFIG_ACPI_ERST
+{
+Object *erst_dev;
+erst_dev = find_erst_dev();
+if (erst_dev) {
+acpi_add_table(table_offsets, tables_blob);
+build_erst(tables_blob, tables->linker, erst_dev,
+   x86ms->oem_id, x86ms->oem_table_id);
+}
+}
+#endif
+
 xsdt = tables_blob->len;
 build_xsdt(tables_blob, tables->linker, table_offsets, x86ms->oem_id,
x86ms->oem_table_id);
diff --git a/include/hw/acpi/erst.h b/include/hw/acpi/erst.h
index 9d63717..b747fe7 100644
--- a/include/hw/acpi/erst.h
+++ b/include/hw/acpi/erst.h
@@ -16,4 +16,9 @@ void build_erst(GArray *table_data, BIOSLinker *linker, 
Object *erst_dev,
 
 #define TYPE_ACPI_ERST "acpi-erst"
 
+/* returns NULL unless there is exactly one device */
+static inline Object *find_erst_dev(void)
+{
+return object_resolve_path_type("", TYPE_ACPI_ERST, NULL);
+}
 #endif
-- 
1.8.3.1




[PATCH v12 8/9] ACPI ERST: qtest for ERST

2022-01-10 Thread Eric DeVolder
This change provides a qtest that locates and then does a simple
interrogation of the ERST feature within the guest.

Signed-off-by: Eric DeVolder 
Reviewed-by: Ani Sinha 
---
 tests/qtest/erst-test.c | 172 
 tests/qtest/meson.build |   2 +
 2 files changed, 174 insertions(+)
 create mode 100644 tests/qtest/erst-test.c

diff --git a/tests/qtest/erst-test.c b/tests/qtest/erst-test.c
new file mode 100644
index 000..f9ad3c9
--- /dev/null
+++ b/tests/qtest/erst-test.c
@@ -0,0 +1,172 @@
+/*
+ * QTest testcase for acpi-erst
+ *
+ * Copyright (c) 2021 Oracle
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "libqos/libqos-pc.h"
+#include "libqos/libqtest.h"
+#include "qemu-common.h"
+
+#include "hw/pci/pci.h"
+
+static void save_fn(QPCIDevice *dev, int devfn, void *data)
+{
+QPCIDevice **pdev = (QPCIDevice **) data;
+
+*pdev = dev;
+}
+
+static QPCIDevice *get_erst_device(QPCIBus *pcibus)
+{
+QPCIDevice *dev;
+
+dev = NULL;
+qpci_device_foreach(pcibus,
+PCI_VENDOR_ID_REDHAT,
+PCI_DEVICE_ID_REDHAT_ACPI_ERST,
+save_fn, );
+g_assert(dev != NULL);
+
+return dev;
+}
+
+typedef struct _ERSTState {
+QOSState *qs;
+QPCIBar reg_bar, mem_bar;
+uint64_t reg_barsize, mem_barsize;
+QPCIDevice *dev;
+} ERSTState;
+
+#define ACTION 0
+#define VALUE 8
+
+static const char *reg2str(unsigned reg)
+{
+switch (reg) {
+case 0:
+return "ACTION";
+case 8:
+return "VALUE";
+default:
+return NULL;
+}
+}
+
+static inline uint32_t in_reg32(ERSTState *s, unsigned reg)
+{
+const char *name = reg2str(reg);
+uint32_t res;
+
+res = qpci_io_readl(s->dev, s->reg_bar, reg);
+g_test_message("*%s -> %08x", name, res);
+
+return res;
+}
+
+static inline uint64_t in_reg64(ERSTState *s, unsigned reg)
+{
+const char *name = reg2str(reg);
+uint64_t res;
+
+res = qpci_io_readq(s->dev, s->reg_bar, reg);
+g_test_message("*%s -> %016llx", name, (unsigned long long)res);
+
+return res;
+}
+
+static inline void out_reg32(ERSTState *s, unsigned reg, uint32_t v)
+{
+const char *name = reg2str(reg);
+
+g_test_message("%08x -> *%s", v, name);
+qpci_io_writel(s->dev, s->reg_bar, reg, v);
+}
+
+static inline void out_reg64(ERSTState *s, unsigned reg, uint64_t v)
+{
+const char *name = reg2str(reg);
+
+g_test_message("%016llx -> *%s", (unsigned long long)v, name);
+qpci_io_writeq(s->dev, s->reg_bar, reg, v);
+}
+
+static void cleanup_vm(ERSTState *s)
+{
+g_free(s->dev);
+qtest_shutdown(s->qs);
+}
+
+static void setup_vm_cmd(ERSTState *s, const char *cmd)
+{
+const char *arch = qtest_get_arch();
+
+if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+s->qs = qtest_pc_boot(cmd);
+} else {
+g_printerr("erst-test tests are only available on x86\n");
+exit(EXIT_FAILURE);
+}
+s->dev = get_erst_device(s->qs->pcibus);
+
+s->reg_bar = qpci_iomap(s->dev, 0, >reg_barsize);
+g_assert_cmpuint(s->reg_barsize, ==, 16);
+
+s->mem_bar = qpci_iomap(s->dev, 1, >mem_barsize);
+g_assert_cmpuint(s->mem_barsize, ==, 0x2000);
+
+qpci_device_enable(s->dev);
+}
+
+static void test_acpi_erst_basic(void)
+{
+ERSTState state;
+uint64_t log_address_range;
+uint64_t log_address_length;
+uint32_t log_address_attr;
+
+setup_vm_cmd(,
+"-object memory-backend-file,"
+"mem-path=acpi-erst.XX,"
+"size=64K,"
+"share=on,"
+"id=nvram "
+"-device acpi-erst,"
+"memdev=nvram");
+
+out_reg32(, ACTION, 0xD);
+log_address_range = in_reg64(, VALUE);
+out_reg32(, ACTION, 0xE);
+log_address_length = in_reg64(, VALUE);
+out_reg32(, ACTION, 0xF);
+log_address_attr = in_reg32(, VALUE);
+
+/* Check log_address_range is not 0, ~0 or base */
+g_assert_cmpuint(log_address_range, !=,  0ULL);
+g_assert_cmpuint(log_address_range, !=, ~0ULL);
+g_assert_cmpuint(log_address_range, !=, state.reg_bar.addr);
+g_assert_cmpuint(log_address_range, ==, state.mem_bar.addr);
+
+/* Check log_address_length is bar1_size */
+g_assert_cmpuint(log_address_length, ==, state.mem_barsize);
+
+/* Check log_address_attr is 0 */
+g_assert_cmpuint(log_address_attr, ==, 0);
+
+cleanup_vm();
+}
+
+int main(int argc, char **argv)
+{
+int ret;
+
+g_test_init(, , NULL);
+qtest_add_func("/acpi-erst/basic", test_acpi_erst_basic);
+ret = g_test_run();
+return ret;
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 37e1eaa..d2b4ed2 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -68,6 +68,7 @@ qtests_i386 = \
   (config_all_devices.has_key('CONFIG_RTL8139_PCI') ? ['rtl8139-test'] : []) + 
 

[PATCH v12 3/9] ACPI ERST: PCI device_id for ERST

2022-01-10 Thread Eric DeVolder
This change reserves the PCI device_id for the new ACPI ERST
device.

Signed-off-by: Eric DeVolder 
Acked-by: Igor Mammedov 
Acked-by: Ani Sinha 
---
 include/hw/pci/pci.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 483d5c7..19db80e 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -108,6 +108,7 @@ extern bool pci_available;
 #define PCI_DEVICE_ID_REDHAT_MDPY0x000f
 #define PCI_DEVICE_ID_REDHAT_NVME0x0010
 #define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011
+#define PCI_DEVICE_ID_REDHAT_ACPI_ERST   0x0012
 #define PCI_DEVICE_ID_REDHAT_QXL 0x0100
 
 #define FMT_PCIBUS  PRIx64
-- 
1.8.3.1




[PATCH v12 0/9] acpi: Error Record Serialization Table, ERST, support for QEMU

2022-01-10 Thread Eric DeVolder
This patchset introduces support for the ACPI Error Record
Serialization Table, ERST.

For background and implementation information, please see
docs/specs/acpi_erst.rst, which is patch 2/10.

Suggested-by: Konrad Wilk 
Signed-off-by: Eric DeVolder 

---
v12: 10jan2022
 - Converted macros in build_erst() to uppert to follow coding
   style, as pointed out by Michael Tsirkin.
 - And few items to help further simplify build_erst().

v11: 15dec2021
 - Simplified build_erst() via feedback from Michael Tsirkin
 - Addressed additional feedback from Ani Sinha

v10: 9dec2021
 - Addressed additional feedback from Ani Sinha

v9: 2dec2021
 - Addressed feedback from Ani Sinha

v8: 15oct2021
 - Added Kconfig option for ERST, per Ani Sinha
 - Fixed patch ordering, per Ani

v7: 7oct2021
 - style improvements, per Igor
 - use of endian accessors for storage header, per Igor
 - a number of optimizations and improvements, per Igor
 - updated spec for header, per Igor
 - updated spec for rst format, per Michael Tsirkin
 - updated spec for new record_size parameter
   Due to changes in the spec, I am not carrying the
   Acked-by from Ani Sinha.
 - changes for and testing of migration to systems with
   differing ERST_RECORD_SIZE

v6: 5aug2021
 - Fixed compile warning/error, per Michael Tsirkin
 - Fixed mingw32 build error, per Michael
 - Converted exchange buffer to MemoryBackend, per Igor
 - Migrated test to PCI, per Igor
 - Significantly reduced amount of copying, per Igor
 - Corrections/enhancements to acpi_erst.txt, per Igor
 - Many misc/other small items, per Igor

v5: 30jun2021
 - Create docs/specs/acpi_erst.txt, per Igor
 - Separate PCI BARs for registers and memory, per Igor
 - Convert debugging to use trace infrastructure, per Igor
 - Various other fixups, per Igor

v4: 11jun2021
 - Converted to a PCI device, per Igor.
 - Updated qtest.
 - Rearranged patches, per Igor.

v3: 28may2021
 - Converted to using a TYPE_MEMORY_BACKEND_FILE object rather than
   internal array with explicit file operations, per Igor.
 - Changed the way the qdev and base address are handled, allowing
   ERST to be disabled at run-time. Also aligns better with other
   existing code.

v2: 8feb2021
 - Added qtest/smoke test per Paolo Bonzini
 - Split patch into smaller chunks, per Igor Mammedov
 - Did away with use of ACPI packed structures, per Igor Mammedov

v1: 26oct2020
 - initial post

---
Eric DeVolder (9):
  ACPI ERST: bios-tables-test.c steps 1 and 2
  ACPI ERST: specification for ERST support
  ACPI ERST: PCI device_id for ERST
  ACPI ERST: header file for ERST
  ACPI ERST: support for ACPI ERST feature
  ACPI ERST: build the ACPI ERST table
  ACPI ERST: create ACPI ERST table for pc/x86 machines
  ACPI ERST: qtest for ERST
  ACPI ERST: bios-tables-test testcase

 docs/specs/acpi_erst.rst|  200 ++
 hw/acpi/Kconfig |6 +
 hw/acpi/erst.c  | 1033 +++
 hw/acpi/meson.build |1 +
 hw/acpi/trace-events|   15 +
 hw/i386/acpi-build.c|   15 +
 hw/i386/acpi-microvm.c  |   15 +
 include/hw/acpi/erst.h  |   24 +
 include/hw/pci/pci.h|1 +
 tests/data/acpi/microvm/ERST.pcie   |0
 tests/data/acpi/pc/DSDT.acpierst|0
 tests/data/acpi/pc/ERST.acpierst|0
 tests/data/acpi/q35/DSDT.acpierst   |0
 tests/data/acpi/q35/ERST.acpierst   |0
 tests/qtest/bios-tables-test-allowed-diff.h |5 +
 tests/qtest/bios-tables-test.c  |   54 ++
 tests/qtest/erst-test.c |  172 +
 tests/qtest/meson.build |2 +
 18 files changed, 1543 insertions(+)
 create mode 100644 docs/specs/acpi_erst.rst
 create mode 100644 hw/acpi/erst.c
 create mode 100644 include/hw/acpi/erst.h
 create mode 100644 tests/data/acpi/microvm/ERST.pcie
 create mode 100644 tests/data/acpi/pc/DSDT.acpierst
 create mode 100644 tests/data/acpi/pc/ERST.acpierst
 create mode 100644 tests/data/acpi/q35/DSDT.acpierst
 create mode 100644 tests/data/acpi/q35/ERST.acpierst
 create mode 100644 tests/qtest/erst-test.c

-- 
1.8.3.1




  1   2   3   4   >