RE: [RESEND RFC v1 2/2] hw/riscv/virt-acpi-build.c: Generate SPCR table

2024-01-10 Thread JeeHeng Sia


> -Original Message-
> From: Daniel Henrique Barboza 
> Sent: Friday, January 5, 2024 8:27 PM
> To: JeeHeng Sia ; qemu-...@nongnu.org; 
> qemu-devel@nongnu.org; qemu-ri...@nongnu.org
> Cc: m...@redhat.com; imamm...@redhat.com; anisi...@redhat.com; 
> peter.mayd...@linaro.org; shannon.zha...@gmail.com;
> suni...@ventanamicro.com; pal...@dabbelt.com; alistair.fran...@wdc.com; 
> bin.m...@windriver.com; liwei1...@gmail.com;
> zhiwei_...@linux.alibaba.com
> Subject: Re: [RESEND RFC v1 2/2] hw/riscv/virt-acpi-build.c: Generate SPCR 
> table
> 
> 
> 
> On 1/5/24 06:06, Sia Jee Heng wrote:
> > Generate Serial Port Console Redirection Table (SPCR) for RISC-V
> > virtual machine.
> >
> > Signed-off-by: Sia Jee Heng 
> > ---
> >   hw/riscv/virt-acpi-build.c | 39 ++
> >   1 file changed, 39 insertions(+)
> >
> > diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> > index d4a02579d6..388b3d1a84 100644
> > --- a/hw/riscv/virt-acpi-build.c
> > +++ b/hw/riscv/virt-acpi-build.c
> > @@ -174,6 +174,42 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
> > *uart_memmap,
> >   aml_append(scope, dev);
> >   }
> >
> > +/*
> > + * Serial Port Console Redirection Table (SPCR)
> > + * Rev: 1.07
> 
> Shouldn't it be "Rev: 2.0"? The function is calling the common build_spcr() 
> that
> specifies
I will give them a generic name for both the arch build_spcr() and the
common build_spcr(). The revision info should be passed to the common
build_spcr().
> 
> +AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = oem_id,
> +.oem_table_id = oem_table_id };
> 
> 
> 
> Code LGTM regardless of the "Rev: " comment value.
> 
> 
> Reviewed-by: Daniel Henrique Barboza 
> 
> 
> 
> 
> 
> > + */
> > +
> > +static void
> > +build_spcr_rev2(GArray *table_data, BIOSLinker *linker, RISCVVirtState *s)
> > +{
> > +AcpiSpcrData serial = {
> > +.interface_type = 0,   /* 16550 compatible */
> > +.base_addr.id = AML_AS_SYSTEM_MEMORY,
> > +.base_addr.width = 32,
> > +.base_addr.offset = 0,
> > +.base_addr.size = 1,
> > +.base_addr.addr = s->memmap[VIRT_UART0].base,
> > +.interrupt_type = (1 << 4),/* Bit[4] RISC-V PLIC/APLIC */
> > +.pc_interrupt = 0,
> > +.interrupt = UART0_IRQ,
> > +.baud_rate = 7,/* 15200 */
> > +.parity = 0,
> > +.stop_bits = 1,
> > +.flow_control = 0,
> > +.terminal_type = 3,/* ANSI */
> > +.language = 0, /* Language */
> > +.pci_device_id = 0x,   /* not a PCI device*/
> > +.pci_vendor_id = 0x,   /* not a PCI device*/
> > +.pci_bus = 0,
> > +.pci_device = 0,
> > +.pci_function = 0,
> > +.pci_flags = 0,
> > +.pci_segment = 0,
> > +};
> > +
> > +build_spcr(table_data, linker, &serial, s->oem_id, s->oem_table_id);
> > +}
> > +
> >   /* RHCT Node[N] starts at offset 56 */
> >   #define RHCT_NODE_ARRAY_OFFSET 56
> >
> > @@ -555,6 +591,9 @@ static void virt_acpi_build(RISCVVirtState *s, 
> > AcpiBuildTables *tables)
> >   acpi_add_table(table_offsets, tables_blob);
> >   build_rhct(tables_blob, tables->linker, s);
> >
> > +acpi_add_table(table_offsets, tables_blob);
> > +build_spcr_rev2(tables_blob, tables->linker, s);
> > +
> >   acpi_add_table(table_offsets, tables_blob);
> >   {
> >   AcpiMcfgInfo mcfg = {


RE: [RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location

2024-01-10 Thread JeeHeng Sia


> -Original Message-
> From: Daniel Henrique Barboza 
> Sent: Friday, January 5, 2024 8:19 PM
> To: JeeHeng Sia ; qemu-...@nongnu.org; 
> qemu-devel@nongnu.org; qemu-ri...@nongnu.org
> Cc: m...@redhat.com; imamm...@redhat.com; anisi...@redhat.com; 
> peter.mayd...@linaro.org; shannon.zha...@gmail.com;
> suni...@ventanamicro.com; pal...@dabbelt.com; alistair.fran...@wdc.com; 
> bin.m...@windriver.com; liwei1...@gmail.com;
> zhiwei_...@linux.alibaba.com
> Subject: Re: [RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR 
> creation to common location
> 
> 
> 
> On 1/5/24 06:06, Sia Jee Heng wrote:
> > RISC-V should also generate the SPCR in a manner similar to ARM.
> > Therefore, instead of replicating the code, relocate this function
> > to the common AML build.
> >
> > Signed-off-by: Sia Jee Heng 
> > ---
> >   hw/acpi/aml-build.c | 51 
> >   hw/arm/virt-acpi-build.c| 68 +++--
> >   include/hw/acpi/acpi-defs.h | 33 ++
> >   include/hw/acpi/aml-build.h |  4 +++
> >   4 files changed, 115 insertions(+), 41 deletions(-)
> >
> > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > index af66bde0f5..1efa534aa8 100644
> > --- a/hw/acpi/aml-build.c
> > +++ b/hw/acpi/aml-build.c
> > @@ -1994,6 +1994,57 @@ static void build_processor_hierarchy_node(GArray 
> > *tbl, uint32_t flags,
> >   }
> >   }
> >
> > +void build_spcr(GArray *table_data, BIOSLinker *linker,
> > +const AcpiSpcrData *f, const char *oem_id,
> > +const char *oem_table_id)
> > +{
> > +AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = oem_id,
> > +.oem_table_id = oem_table_id };
> > +
> > +acpi_table_begin(&table, table_data);
> > +/* Interface type */
> > +build_append_int_noprefix(table_data, f->interface_type, 1);
> > +/* Reserved */
> > +build_append_int_noprefix(table_data, 0, 3);
> > +/* Base Address */
> > +build_append_gas(table_data, f->base_addr.id, f->base_addr.width,
> > + f->base_addr.offset, f->base_addr.size,
> > + f->base_addr.addr);
> > +/* Interrupt type */
> > +build_append_int_noprefix(table_data, f->interrupt_type, 1);
> > +/* IRQ */
> > +build_append_int_noprefix(table_data, f->pc_interrupt, 1);
> > +/* Global System Interrupt */
> > +build_append_int_noprefix(table_data, f->interrupt, 4);
> > +/* Baud Rate */
> > +build_append_int_noprefix(table_data, f->baud_rate, 1);
> > +/* Parity */
> > +build_append_int_noprefix(table_data, f->parity, 1);
> > +/* Stop Bits */
> > +build_append_int_noprefix(table_data, f->stop_bits, 1);
> > +/* Flow Control */
> > +build_append_int_noprefix(table_data, f->flow_control, 1);
> > +/* Terminal Type */
> > +build_append_int_noprefix(table_data, f->terminal_type, 1);
> > +/* PCI Device ID  */
> > +build_append_int_noprefix(table_data, f->pci_device_id, 2);
> > +/* PCI Vendor ID */
> > +build_append_int_noprefix(table_data, f->pci_vendor_id, 2);
> > +/* PCI Bus Number */
> > +build_append_int_noprefix(table_data, f->pci_bus, 1);
> > +/* PCI Device Number */
> > +build_append_int_noprefix(table_data, f->pci_device, 1);
> > +/* PCI Function Number */
> > +build_append_int_noprefix(table_data, f->pci_function, 1);
> > +/* PCI Flags */
> > +build_append_int_noprefix(table_data, f->pci_flags, 4);
> > +/* PCI Segment */
> > +build_append_int_noprefix(table_data, f->pci_segment, 1);
> > +/* Reserved */
> > +build_append_int_noprefix(table_data, 0, 4);
> > +
> > +acpi_table_end(linker, &table);
> > +}
> >   /*
> >* ACPI spec, Revision 6.3
> >* 5.2.29 Processor Properties Topology Table (PPTT)
> > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > index 510ab0dcca..a31f736d1a 100644
> > --- a/hw/arm/virt-acpi-build.c
> > +++ b/hw/arm/virt-acpi-build.c
> > @@ -431,48 +431,34 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
> > VirtMachineState *vms)
> >* Rev: 1.07
> >*/
> >   static void
> > -build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> > +build_spcr_v2(GArray *table_data, BIOSLinker *linker, VirtMachineState 
> > *vms)
> 
> Nit: I don't understand the '_v2' in the name of this function. Is it just to 
> not collide
> with the now public build_spcr()? Or does it have to do with the SPCR table 
> being
> '.rev = 2'? Because if it's the latter, you can name the common helper 
> 'build_spcr_rev2'
> (since both ARM and RISC-V use SPCR rev 2), keep this local build_spcr() 
> initializing
> the AcpiSpcrData struct with ARM attributes and then call the common 
> build_spcr_rev2().
Sorry for the confusion. I will give them a generic name for both the arch 
build_spcr()
and the common build_spcr(). The revision info should be passed to the common
build_spcr().
> 
> 
> Code l

RE: [RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location

2024-01-10 Thread JeeHeng Sia



> -Original Message-
> From: Sunil V L 
> Sent: Monday, January 8, 2024 7:35 PM
> To: Daniel Henrique Barboza 
> Cc: JeeHeng Sia ; qemu-...@nongnu.org; 
> qemu-devel@nongnu.org; qemu-ri...@nongnu.org;
> m...@redhat.com; imamm...@redhat.com; anisi...@redhat.com; 
> peter.mayd...@linaro.org; shannon.zha...@gmail.com;
> pal...@dabbelt.com; alistair.fran...@wdc.com; bin.m...@windriver.com; 
> liwei1...@gmail.com; zhiwei_...@linux.alibaba.com
> Subject: Re: [RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR 
> creation to common location
> 
> On Fri, Jan 05, 2024 at 09:19:14AM -0300, Daniel Henrique Barboza wrote:
> >
> >
> > On 1/5/24 06:06, Sia Jee Heng wrote:
> > > RISC-V should also generate the SPCR in a manner similar to ARM.
> > > Therefore, instead of replicating the code, relocate this function
> > > to the common AML build.
> > >
> > > Signed-off-by: Sia Jee Heng 
> > > ---
> > >   hw/acpi/aml-build.c | 51 
> > >   hw/arm/virt-acpi-build.c| 68 +++--
> > >   include/hw/acpi/acpi-defs.h | 33 ++
> > >   include/hw/acpi/aml-build.h |  4 +++
> > >   4 files changed, 115 insertions(+), 41 deletions(-)
> > >
> > > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > > index af66bde0f5..1efa534aa8 100644
> > > --- a/hw/acpi/aml-build.c
> > > +++ b/hw/acpi/aml-build.c
> > > @@ -1994,6 +1994,57 @@ static void build_processor_hierarchy_node(GArray 
> > > *tbl, uint32_t flags,
> > >   }
> > >   }
> > > +void build_spcr(GArray *table_data, BIOSLinker *linker,
> > > +const AcpiSpcrData *f, const char *oem_id,
> > > +const char *oem_table_id)
> > > +{
> > > +AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = oem_id,
> > > +.oem_table_id = oem_table_id };
> > > +
> > > +acpi_table_begin(&table, table_data);
> > > +/* Interface type */
> > > +build_append_int_noprefix(table_data, f->interface_type, 1);
> > > +/* Reserved */
> > > +build_append_int_noprefix(table_data, 0, 3);
> > > +/* Base Address */
> > > +build_append_gas(table_data, f->base_addr.id, f->base_addr.width,
> > > + f->base_addr.offset, f->base_addr.size,
> > > + f->base_addr.addr);
> > > +/* Interrupt type */
> > > +build_append_int_noprefix(table_data, f->interrupt_type, 1);
> > > +/* IRQ */
> > > +build_append_int_noprefix(table_data, f->pc_interrupt, 1);
> > > +/* Global System Interrupt */
> > > +build_append_int_noprefix(table_data, f->interrupt, 4);
> > > +/* Baud Rate */
> > > +build_append_int_noprefix(table_data, f->baud_rate, 1);
> > > +/* Parity */
> > > +build_append_int_noprefix(table_data, f->parity, 1);
> > > +/* Stop Bits */
> > > +build_append_int_noprefix(table_data, f->stop_bits, 1);
> > > +/* Flow Control */
> > > +build_append_int_noprefix(table_data, f->flow_control, 1);
> > > +/* Terminal Type */
> > > +build_append_int_noprefix(table_data, f->terminal_type, 1);
> > > +/* PCI Device ID  */
> > > +build_append_int_noprefix(table_data, f->pci_device_id, 2);
> > > +/* PCI Vendor ID */
> > > +build_append_int_noprefix(table_data, f->pci_vendor_id, 2);
> > > +/* PCI Bus Number */
> > > +build_append_int_noprefix(table_data, f->pci_bus, 1);
> > > +/* PCI Device Number */
> > > +build_append_int_noprefix(table_data, f->pci_device, 1);
> > > +/* PCI Function Number */
> > > +build_append_int_noprefix(table_data, f->pci_function, 1);
> > > +/* PCI Flags */
> > > +build_append_int_noprefix(table_data, f->pci_flags, 4);
> > > +/* PCI Segment */
> > > +build_append_int_noprefix(table_data, f->pci_segment, 1);
> > > +/* Reserved */
> > > +build_append_int_noprefix(table_data, 0, 4);
> > > +
> > > +acpi_table_end(linker, &table);
> > > +}
> > >   /*
> > >* ACPI spec, Revision 6.3
> > >* 5.2.29 Processor Properties Topology Table (PPTT)
> > > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > > index 510ab0dcca..a31f736d1a 100644
> > > --- a/hw/arm/virt-acpi-build.c
> > > +++ b/hw/arm/virt-acpi-build.c
> > > @@ -431,48 +431,34 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
> > > VirtMachineState *vms)
> > >* Rev: 1.07
> > >*/
> > >   static void
> > > -build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> > > +build_spcr_v2(GArray *table_data, BIOSLinker *linker, VirtMachineState 
> > > *vms)
> >
> > Nit: I don't understand the '_v2' in the name of this function. Is it just 
> > to not collide
> > with the now public build_spcr()? Or does it have to do with the SPCR table 
> > being
> > '.rev = 2'? Because if it's the latter, you can name the common helper 
> > 'build_spcr_rev2'
> > (since both ARM and RISC-V use SPCR rev 2), keep this local build_spcr() 
> > initializing
> > the AcpiSpcrData struct with ARM 

Re: [PATCH 00/33] hw/cpu/arm: Remove one use of qemu_get_cpu() in A7/A15 MPCore priv

2024-01-10 Thread Markus Armbruster
Peter Xu  writes:

> On Wed, Jan 10, 2024 at 07:03:06AM +0100, Markus Armbruster wrote:
>> Peter Xu  writes:
>> 
>> > On Tue, Jan 09, 2024 at 10:22:31PM +0100, Philippe Mathieu-Daudé wrote:
>> >> Hi Fabiano,
>> >> 
>> >> On 9/1/24 21:21, Fabiano Rosas wrote:

[...]

>> >> > No one wants
>> >> > to be policing QOM hierarchy changes in every single series that shows
>> >> > up on the list.
>> >> > 
>> >> > Anyway, thanks for the pointers. I'll study that code a bit more, maybe
>> >> > I can come up with some way to handle these cases.
>> >> > 
>> >> > Hopefully between the analyze-migration test and the compat tests we'll
>> >> > catch the next bug of this kind before it gets merged.
>> >
>> > Things like that might be able to be detected via 
>> > vmstate-static-checker.py.
>> > But I'm not 100% sure, also its coverage is limited.
>> >
>> > For example, I don't think it can detect changes to objects that will only
>> > be created dynamically, e.g., I think sometimes we create objects after
>> > some guest behaviors (consider guest enables the device, then QEMU
>> > emulation creates some objects on demand of device setup?),
>> 
>> Feels nuts to me.
>> 
>> In real hardware, software enabling a device that is disabled by default
>> doesn't create the device.  The device is always there, it just happens
>> to be inactive unless enabled.  We should model the device just like
>> that.
>
> It doesn't need to be the device itself to be dynamically created, but some
> other sub-objects that do not require to exist until the device is enabled,
> or some specific function of that device is enabled.  It is logically doable.
>
> Is the example Cedric provided looks like some case like this?  I am not
> sure, that's also why I'm not sure the static checker would work here.  But
> logically it seems possible, e.g. with migration VMSD needed() facilities.
> Consider a device has a sub-function that requires a sub-object.  It may
> not need to migrate that object if that sub-feature is not even enabled.
> If that object is very large, it might be wise to do so if possible to not
> send chunks of junk during the VM downtime.
>
> But then after a 2nd thought I do agree it's probably not sensible, because
> even if the src may know whether the sub-object will be needed, there's
> probably no good way for the dest QEMU to know.  It can only know in
> something like a post_load() hook, but logically that can happen only after
> a full load of that device state, so might already be too late.
>
> Thanks,

If an object has state that needs to be migrated only sometimes, and
that part of the state is large enough to bother, we can put it in an
optional subsection, can't we?

Destination: if present, take it.  If absent, initialize to default.

Source: send unless (known to be) in default state.




Re: [RFC/PATCH v1 07/11] gunyah: Specify device-tree location

2024-01-10 Thread Srivatsa Vaddagiri
* Philippe Mathieu-Daud?  [2024-01-09 14:31:03]:

> Hi Srivatsa,
> 
> On 9/1/24 10:00, Srivatsa Vaddagiri wrote:
> > Specify the location of device-tree and its size, as Gunyah requires the
> > device-tree to be parsed before VM can begin its execution.
> > 
> > Signed-off-by: Srivatsa Vaddagiri 
> > ---
> >   MAINTAINERS   |  1 +
> >   accel/stubs/gunyah-stub.c |  5 +
> >   hw/arm/virt.c |  6 ++
> >   include/sysemu/gunyah.h   |  2 ++
> >   target/arm/gunyah.c   | 45 +++
> >   target/arm/meson.build|  3 +++
> >   6 files changed, 62 insertions(+)
> >   create mode 100644 target/arm/gunyah.c
> 
> (Please enable scripts/git.orderfile)

Sure will do so from the next version!

> 
> > diff --git a/include/sysemu/gunyah.h b/include/sysemu/gunyah.h
> > index 4f26938521..a73d17bfb9 100644
> > --- a/include/sysemu/gunyah.h
> > +++ b/include/sysemu/gunyah.h
> > @@ -27,4 +27,6 @@ typedef struct GUNYAHState GUNYAHState;
> >   DECLARE_INSTANCE_CHECKER(GUNYAHState, GUNYAH_STATE,
> >TYPE_GUNYAH_ACCEL)
> > +int gunyah_arm_set_dtb(__u64 dtb_start, __u64 dtb_size);
> I'm getting:
> 
> In file included from hw/intc/arm_gicv3_common.c:35:
> include/sysemu/gunyah.h:30:24: error: unknown type name '__u64'
> int gunyah_arm_set_dtb(__u64 dtb_start, __u64 dtb_size);
>^
> include/sysemu/gunyah.h:30:41: error: unknown type name '__u64'
> int gunyah_arm_set_dtb(__u64 dtb_start, __u64 dtb_size);
> ^
> 2 errors generated.

Hmm I don't get that error when compiling on Linux. I think uint64_t will work
better for all platforms where Qemu can get compiled?

- vatsa



Re: [PATCH 13/19] qapi/schema: fix typing for QAPISchemaVariants.tag_member

2024-01-10 Thread John Snow
On Wed, Jan 10, 2024 at 2:53 AM Markus Armbruster  wrote:
>
> John Snow  writes:
>
> > On Wed, Nov 22, 2023 at 11:02 AM John Snow  wrote:
> >>
> >> On Wed, Nov 22, 2023 at 9:05 AM Markus Armbruster  
> >> wrote:
> >> >
> >> > John Snow  writes:
> >> >
> >> > > There are two related changes here:
> >> > >
> >> > > (1) We need to perform type narrowing for resolving the type of
> >> > > tag_member during check(), and
> >> > >
> >> > > (2) tag_member is a delayed initialization field, but we can hide it
> >> > > behind a property that raises an Exception if it's called too
> >> > > early. This simplifies the typing in quite a few places and avoids
> >> > > needing to assert that the "tag_member is not None" at a dozen
> >> > > callsites, which can be confusing and suggest the wrong thing to a
> >> > > drive-by contributor.
> >> > >
> >> > > Signed-off-by: John Snow 
> >> >
> >> > Without looking closely: review of PATCH 10 applies, doesn't it?
> >> >
> >>
> >> Yep!
> >
> > Hm, actually, maybe not quite as cleanly.
> >
> > The problem is we *are* initializing that field immediately with
> > whatever we were passed in during __init__, which means the field is
> > indeed Optional. Later, during check(), we happen to eliminate that
> > usage of None.
>
> You're right.
>
> QAPISchemaVariants.__init__() takes @tag_name and @tag_member.  Exactly
> one of them must be None.  When creating a union's QAPISchemaVariants,
> it's tag_member, and when creating an alternate's, it's tag_name.
>
> Why?
>
> A union's tag is an ordinary member selected by name via
> 'discriminator': TAG_NAME.  We can't resolve the name at this time,
> because it may be buried arbitrarily deep in the base type chain.
>
> An alternate's tag is an implicitly created "member" of type 'QType'.
> "Member" in scare-quotes, because is special: it exists in C, but not on
> the wire, and not in introspection.
>
> Historical note: simple unions also had an implictly created tag member,
> and its type was the implicit enum type enumerating the branches.
>
> So _def_union_type() passes TAG_NAME to .__init__(), and
> _def_alternate_type() creates and passes the implicit tag member.
> Hardly elegant, but it works.
>
> > To remove the use of the @property trick here, we could:
> >
> > ... declare the field, then only initialize it if we were passed a
> > non-None value. But then check() would need to rely on something like
> > hasattr to check if it was set or not, which is maybe an unfortunate
> > code smell.
> > So I think you'd still wind up needing a ._tag_member field which is
> > Optional and always gets set during __init__, then setting a proper
> > .tag_member field during check().
> >
> > Or I could just leave this one as-is. Or something else. I think the
> > dirt has to get swept somewhere, because we don't *always* have enough
> > information to fully initialize it at __init__ time, it's a
> > conditional delayed initialization, unlike the others which are
> > unconditionally delayed.
>
> Yes.
>
> Here's a possible "something else":
>
> 1. Drop parameter .__init__() parameter @tag_member, and leave
> .tag_member unset there.
>
> 2. Set .tag_member in .check(): if .tag_name, look up that member (no
> change).  Else, it's an alternate; create the alternate's implicit tag
> member.
>
> Drawback: before, we create AST in just one place, namely
> QAPISchema._def_exprs().  Now we also create some in .check().

I suppose I don't have a concrete argument against this beyond "It
doesn't seem prettier than using the @property getter."

>
> Here's another "something else":
>
> 1. Fuse parameters .__init__() @tag_member and @tag_name.  The type
> becomes Union.  Store for .check().
>
> 2. Set .tag_member in .check(): if we stored a name, look up that
> member, else we must have stored an implicit member, so use that.
>
> 3. We check "is this a union?" like if self._tag_name.  Needs
> adjustment.
>
> Feels a bit awkward to me.

Yeah, a little. Mechanically simple, though, I think.

>
> We can also do nothing, as you said.  We don't *have* to express
> ".check() resolves unresolved tag member" in the type system.  We can
> just live with .tag_member remaining Optional.

This is the only option I'm sure I don't want - it's misleading to
users of the API for the purposes of new generators using a fully
realized schema object. I think it's important to remove Optional[]
where possible to avoid the question "When will this be set to None?"
if the answer is just "For your purposes, never."

It's an implementation detail of object initialization leaking out.

(Also, I just counted and leaving the field as Optional adds 22 new
type errors; that's a lot of callsites to bandage with new conditions.
nah.)

The *other* way to not do anything is to just leave the @property
solution in O:-)

>
> Differently awkward, I guess.
>
> Thoughts?

Partial to the getter, unless option 1 or 2 leads to simplification of
the check() code, which I haven't really e

Re: [RFC/PATCH v1 07/11] gunyah: Specify device-tree location

2024-01-10 Thread Srivatsa Vaddagiri
* Philippe Mathieu-Daud?  [2024-01-09 14:36:12]:

> > +#include "qemu/osdep.h"
> > +#include "qemu/error-report.h"
> > +#include "sysemu/gunyah.h"
> > +#include "sysemu/gunyah_int.h"
> > +#include "linux-headers/linux/gunyah.h"
> I'm getting on macOS:
> 
> In file included from ../../target/arm/gunyah.c:13:
> linux-headers/linux/gunyah.h:13:10: fatal error: 'linux/types.h' file not
> found
> #include 
>  ^~~
> 1 error generated.
> 
> Maybe we need the following change?
> 
> -- >8 --
> diff --git a/meson.build b/meson.build
> index 6ded60063e..fb20ca04d1 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -712,5 +712,5 @@ endif
> 
>  gunyah = not_found
> -if get_option('gunyah').allowed()
> +if get_option('gunyah').allowed() and host_os == 'linux'
>  accelerators += 'CONFIG_GUNYAH'
>  endif

Ok sure will include that change in my next version.

- vatsa



Re: [PATCH 00/33] hw/cpu/arm: Remove one use of qemu_get_cpu() in A7/A15 MPCore priv

2024-01-10 Thread Peter Xu
On Wed, Jan 10, 2024 at 09:09:51AM +0100, Markus Armbruster wrote:
> If an object has state that needs to be migrated only sometimes, and
> that part of the state is large enough to bother, we can put it in an
> optional subsection, can't we?
> 
> Destination: if present, take it.  If absent, initialize to default.
> 
> Source: send unless (known to be) in default state.

Hmm.. correct. I think I messed up VMSD's needed() hook with field_exists()
of the fields; my apologies.

The trick should be that VMSD's subsections is more flexible, due to the
fact that vmstate_subsection_load() has:

while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
...
sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
...
}

So it tolerates the case where the subsection doesn't exist, or out of
order subsections.

While field_exists() hook seems not that flexible, as it's implemented as
this in vmstate_load_state():

while (field->name) {
...
if (vmstate_field_exists(vmsd, field, opaque, version_id)) {
   ...
}
...
field++;
}

So that vmstate_field_exists() needs to be known even on dest before the
main vmsd got loaded, and it should always return the same value as the
source.  Also, the field has ordering requirements.

Then yes, subsection should work for dynamic objects.

Thanks,

-- 
Peter Xu




Re: [RFC PATCH v3 01/30] io: add and implement QIO_CHANNEL_FEATURE_SEEKABLE for channel file

2024-01-10 Thread Peter Xu
On Mon, Nov 27, 2023 at 05:25:43PM -0300, Fabiano Rosas wrote:
> From: Nikolay Borisov 
> 
> Add a generic QIOChannel feature SEEKABLE which would be used by the
> qemu_file* apis. For the time being this will be only implemented for
> file channels.
> 
> Signed-off-by: Nikolay Borisov 
> Signed-off-by: Fabiano Rosas 
> Reviewed-by: Daniel P. Berrangé 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v6 07/11] virtio-gpu: Handle resource blob commands

2024-01-10 Thread Pierre-Eric Pelloux-Prayer




Le 09/01/2024 à 17:50, Pierre-Eric Pelloux-Prayer a écrit :



Le 19/12/2023 à 08:53, Huang Rui a écrit :

From: Antonio Caggiano 

Support BLOB resources creation, mapping and unmapping by calling the
new stable virglrenderer 0.10 interface. Only enabled when available and
via the blob config. E.g. -device virtio-vga-gl,blob=true

Signed-off-by: Antonio Caggiano 
Signed-off-by: Dmitry Osipenko 
Signed-off-by: Xenia Ragiadakou 
Signed-off-by: Huang Rui 
---

Changes in v6:
- Use new struct virgl_gpu_resource.
- Unmap, unref and destroy the resource only after the memory region
   has been completely removed.
- In unref check whether the resource is still mapped.
- In unmap_blob check whether the resource has been already unmapped.
- Fix coding style

  hw/display/virtio-gpu-virgl.c | 274 +-
  hw/display/virtio-gpu.c   |   4 +-
  meson.build   |   4 +
  3 files changed, 276 insertions(+), 6 deletions(-)

diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index faab374336..5a3a292f79 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -17,6 +17,7 @@
  #include "trace.h"
  #include "hw/virtio/virtio.h"
  #include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-gpu-bswap.h"
  #include "ui/egl-helpers.h"
@@ -24,8 +25,62 @@
  struct virgl_gpu_resource {
  struct virtio_gpu_simple_resource res;
+    uint32_t ref;
+    VirtIOGPU *g;
+
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+    /* only blob resource needs this region to be mapped as guest mmio */
+    MemoryRegion *region;
+#endif
  };
+static void vres_get_ref(struct virgl_gpu_resource *vres)
+{
+    uint32_t ref;
+
+    ref = qatomic_fetch_inc(&vres->ref);
+    g_assert(ref < INT_MAX);
+}
+
+static void virgl_resource_destroy(struct virgl_gpu_resource *vres)
+{
+    struct virtio_gpu_simple_resource *res;
+    VirtIOGPU *g;
+
+    if (!vres) {
+    return;
+    }
+
+    g = vres->g;
+    res = &vres->res;
+    QTAILQ_REMOVE(&g->reslist, res, next);
+    virtio_gpu_cleanup_mapping(g, res);
+    g_free(vres);
+}
+
+static void virgl_resource_unref(struct virgl_gpu_resource *vres)
+{
+    struct virtio_gpu_simple_resource *res;
+
+    if (!vres) {
+    return;
+    }
+
+    res = &vres->res;
+    virgl_renderer_resource_detach_iov(res->resource_id, NULL, NULL);
+    virgl_renderer_resource_unref(res->resource_id);
+}
+
+static void vres_put_ref(struct virgl_gpu_resource *vres)
+{
+    g_assert(vres->ref > 0);
+
+    if (qatomic_fetch_dec(&vres->ref) == 1) {
+    virgl_resource_unref(vres);
+    virgl_resource_destroy(vres);
+    }
+}
+
  static struct virgl_gpu_resource *
  virgl_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
  {
@@ -59,6 +114,8 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
 c2d.width, c2d.height);
  vres = g_new0(struct virgl_gpu_resource, 1);
+    vres_get_ref(vres);
+    vres->g = g;
  vres->res.width = c2d.width;
  vres->res.height = c2d.height;
  vres->res.format = c2d.format;
@@ -91,6 +148,8 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
 c3d.width, c3d.height, c3d.depth);
  vres = g_new0(struct virgl_gpu_resource, 1);
+    vres_get_ref(vres);
+    vres->g = g;
  vres->res.width = c3d.width;
  vres->res.height = c3d.height;
  vres->res.format = c3d.format;
@@ -126,12 +185,21 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
  return;
  }
-    virgl_renderer_resource_detach_iov(unref.resource_id, NULL, NULL);
-    virgl_renderer_resource_unref(unref.resource_id);
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+    if (vres->region) {
+    VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
+    MemoryRegion *mr = vres->region;
+
+    warn_report("%s: blob resource %d not unmapped",
+    __func__, unref.resource_id);
+    vres->region = NULL;


Shouldn't there be a call to memory_region_unref(mr)?


+    memory_region_set_enabled(mr, false);
+    memory_region_del_subregion(&b->hostmem, mr);
+    object_unparent(OBJECT(mr));
+    }
+#endif /* HAVE_VIRGL_RESOURCE_BLOB */
-    QTAILQ_REMOVE(&g->reslist, &vres->res, next);
-    virtio_gpu_cleanup_mapping(g, &vres->res);
-    g_free(vres);
+    vres_put_ref(vres);
  }
  static void virgl_cmd_context_create(VirtIOGPU *g,
@@ -470,6 +538,191 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
  g_free(resp);
  }
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+
+static void virgl_resource_unmap(struct virgl_gpu_resource *vres)
+{
+    if (!vres) {
+    return;
+    }
+
+    virgl_renderer_resource_unmap(vres->res.resource_id);
+
+    vres_put_ref(vres);
+}
+
+static void virgl_resource_blob_async_unmap(void *obj)
+{
+    MemoryRegion *mr = MEMORY_REGION(obj);
+    struct virgl_gpu_resource *vres = mr->opaque;
+
+    virgl_resource_unmap(vres);
+
+    g_free(obj);
+}
+
+static void virgl_cmd_resource_create_blob(

[PULL 00/65] riscv-to-apply queue

2024-01-10 Thread Alistair Francis
The following changes since commit 9468484fe904ab4691de6d9c34616667f377ceac:

  Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into 
staging (2024-01-09 10:32:23 +)

are available in the Git repository at:

  https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240110

for you to fetch changes up to 71b76da33a1558bcd59100188f5753737ef6fa21:

  target/riscv: Ensure mideleg is set correctly on reset (2024-01-10 18:47:47 
+1000)


RISC-V PR for 9.0

* Make vector whole-register move (vmv) depend on vtype register
* Fix th.dcache.cval1 priviledge check
* Don't allow write mstatus_vs without RVV
* Use hwaddr instead of target_ulong for RV32
* Fix machine IDs QOM getters\
* Fix KVM reg id sizes
* ACPI: Enable AIA, PLIC and update RHCT
* Fix the interrupts-extended property format of PLIC
* Add support for Zacas extension
* Add amocas.[w,d,q] instructions
* Document acpi parameter of virt machine
* RVA22 profiles support
* Remove group setting of KVM AIA if the machine only has 1 socket
* Add RVV CSRs to KVM
* sifive_u: Update S-mode U-Boot image build instructions
* Upgrade OpenSBI from v1.3.1 to v1.4
* pmp: Ignore writes when RW=01 and MML=0
* Assert that the CSR numbers will be correct
* Don't adjust vscause for exceptions
* Ensure mideleg is set correctly on reset


Alistair Francis (3):
  target/riscv: Assert that the CSR numbers will be correct
  target/riscv: Don't adjust vscause for exceptions
  target/riscv: Ensure mideleg is set correctly on reset

Bin Meng (2):
  docs/system/riscv: sifive_u: Update S-mode U-Boot image build instructions
  roms/opensbi: Upgrade from v1.3.1 to v1.4

Daniel Henrique Barboza (36):
  target/riscv/cpu.c: fix machine IDs getters
  target/riscv/kvm: change KVM_REG_RISCV_FP_F to u32
  target/riscv/kvm: change KVM_REG_RISCV_FP_D to u64
  target/riscv/kvm: change timer regs size to u64
  target/riscv/kvm: add RISCV_CONFIG_REG()
  target/riscv/kvm: rename riscv_reg_id() to riscv_reg_id_ulong()
  target/riscv: create TYPE_RISCV_VENDOR_CPU
  target/riscv/tcg: do not use "!generic" CPU checks
  target/riscv/tcg: update priv_ver on user_set extensions
  target/riscv: add rv64i CPU
  target/riscv: add zicbop extension flag
  target/riscv/tcg: add 'zic64b' support
  riscv-qmp-cmds.c: expose named features in cpu_model_expansion
  target/riscv: add rva22u64 profile definition
  target/riscv/kvm: add 'rva22u64' flag as unavailable
  target/riscv/tcg: add user flag for profile support
  target/riscv/tcg: add MISA user options hash
  target/riscv/tcg: add riscv_cpu_write_misa_bit()
  target/riscv/tcg: handle profile MISA bits
  target/riscv/tcg: add hash table insert helpers
  target/riscv/tcg: honor user choice for G MISA bits
  target/riscv/tcg: validate profiles during finalize
  riscv-qmp-cmds.c: add profile flags in cpu-model-expansion
  target/riscv: add 'rva22u64' CPU
  target/riscv: implement svade
  target/riscv: add priv ver restriction to profiles
  target/riscv/cpu.c: finalize satp_mode earlier
  target/riscv/cpu.c: add riscv_cpu_is_32bit()
  target/riscv: add satp_mode profile support
  target/riscv: add 'parent' in profile description
  target/riscv: add RVA22S64 profile
  target/riscv: add rva22s64 cpu
  linux-headers: Update to Linux v6.7-rc5
  linux-headers: riscv: add ptrace.h
  target/riscv/kvm: do PR_RISCV_V_SET_CONTROL during realize()
  target/riscv/kvm: add RVV and Vector CSR regs

Heinrich Schuchardt (1):
  docs/system/riscv: document acpi parameter of virt machine

Ivan Klokov (2):
  target/riscv/pmp: Use hwaddr instead of target_ulong for RV32
  target/riscv: pmp: Ignore writes when RW=01 and MML=0

LIU Zhiwei (2):
  target/riscv: Fix th.dcache.cval1 priviledge check
  target/riscv: Not allow write mstatus_vs without RVV

Max Chou (2):
  target/riscv: Add vill check for whole vector register move instructions
  target/riscv: The whole vector register move instructions depend on vsew

Rob Bradford (1):
  disas/riscv: Add amocas.[w,d,q] instructions

Sunil V L (13):
  hw/arm/virt-acpi-build.c: Migrate fw_cfg creation to common location
  hw/arm/virt-acpi-build.c: Migrate virtio creation to common location
  hw/i386/acpi-microvm.c: Use common function to add virtio in DSDT
  hw/riscv: virt: Make few IMSIC macros and functions public
  hw/riscv/virt-acpi-build.c: Add AIA support in RINTC
  hw/riscv/virt-acpi-build.c: Add IMSIC in the MADT
  hw/riscv/virt-acpi-build.c: Add APLIC in the MADT
  hw/riscv/virt-acpi-build.c: Add CMO information in RHCT
  hw/riscv/virt-acpi-build.c: Add MMU node in RHCT
  

[PULL 04/65] target/riscv: Not allow write mstatus_vs without RVV

2024-01-10 Thread Alistair Francis
From: LIU Zhiwei 

If CPU does not implement the Vector extension, it usually means
mstatus vs hardwire to zero. So we should not allow write a
non-zero value to this field.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-ID: <20231215023313.1708-1-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c50a33397c..d8f751a0ae 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1328,11 +1328,14 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
 MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
 MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
-MSTATUS_TW | MSTATUS_VS;
+MSTATUS_TW;
 
 if (riscv_has_ext(env, RVF)) {
 mask |= MSTATUS_FS;
 }
+if (riscv_has_ext(env, RVV)) {
+mask |= MSTATUS_VS;
+}
 
 if (xl != MXL_RV32 || env->debugger) {
 if (riscv_has_ext(env, RVH)) {
-- 
2.43.0




[PULL 17/65] hw/riscv/virt-acpi-build.c: Add IMSIC in the MADT

2024-01-10 Thread Alistair Francis
From: Sunil V L 

Add IMSIC structure in MADT when IMSIC is configured.

Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Acked-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-7-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt-acpi-build.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 8f61fd63eb..32b5795f09 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -270,6 +270,19 @@ static void build_madt(GArray *table_data,
 MachineClass *mc = MACHINE_GET_CLASS(s);
 MachineState *ms = MACHINE(s);
 const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
+uint8_t  group_index_bits = imsic_num_bits(riscv_socket_count(ms));
+uint8_t  guest_index_bits = imsic_num_bits(s->aia_guests + 1);
+uint16_t imsic_max_hart_per_socket = 0;
+uint8_t  hart_index_bits;
+uint8_t  socket;
+
+for (socket = 0; socket < riscv_socket_count(ms); socket++) {
+if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
+imsic_max_hart_per_socket = s->soc[socket].num_harts;
+}
+}
+
+hart_index_bits = imsic_num_bits(imsic_max_hart_per_socket);
 
 AcpiTable table = { .sig = "APIC", .rev = 6, .oem_id = s->oem_id,
 .oem_table_id = s->oem_table_id };
@@ -284,6 +297,28 @@ static void build_madt(GArray *table_data,
 riscv_acpi_madt_add_rintc(i, arch_ids, table_data, s);
 }
 
+/* IMSIC */
+if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
+/* IMSIC */
+build_append_int_noprefix(table_data, 0x19, 1); /* Type */
+build_append_int_noprefix(table_data, 16, 1);   /* Length */
+build_append_int_noprefix(table_data, 1, 1);/* Version */
+build_append_int_noprefix(table_data, 0, 1);/* Reserved */
+build_append_int_noprefix(table_data, 0, 4);/* Flags */
+/* Number of supervisor mode Interrupt Identities */
+build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_MSIS, 2);
+/* Number of guest mode Interrupt Identities */
+build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_MSIS, 2);
+/* Guest Index Bits */
+build_append_int_noprefix(table_data, guest_index_bits, 1);
+/* Hart Index Bits */
+build_append_int_noprefix(table_data, hart_index_bits, 1);
+/* Group Index Bits */
+build_append_int_noprefix(table_data, group_index_bits, 1);
+/* Group Index Shift */
+build_append_int_noprefix(table_data, IMSIC_MMIO_GROUP_MIN_SHIFT, 1);
+}
+
 acpi_table_end(linker, &table);
 }
 
-- 
2.43.0




[PULL 20/65] hw/riscv/virt-acpi-build.c: Add MMU node in RHCT

2024-01-10 Thread Alistair Francis
From: Sunil V L 

MMU type information is available via MMU node in RHCT. Add this node in
RHCT.

Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Acked-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-10-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt-acpi-build.c | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 784bbffead..b7db57b28a 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -152,6 +152,8 @@ static void build_rhct(GArray *table_data,
 size_t len, aligned_len;
 uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0;
 RISCVCPU *cpu = &s->soc[0].harts[0];
+uint32_t mmu_offset = 0;
+uint8_t satp_mode_max;
 char *isa;
 
 AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id,
@@ -171,6 +173,10 @@ static void build_rhct(GArray *table_data,
 num_rhct_nodes++;
 }
 
+if (cpu->cfg.satp_mode.supported != 0) {
+num_rhct_nodes++;
+}
+
 /* Number of RHCT nodes*/
 build_append_int_noprefix(table_data, num_rhct_nodes, 4);
 
@@ -226,6 +232,26 @@ static void build_rhct(GArray *table_data,
 }
 }
 
+/* MMU node structure */
+if (cpu->cfg.satp_mode.supported != 0) {
+satp_mode_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
+mmu_offset = table_data->len - table.table_offset;
+build_append_int_noprefix(table_data, 2, 2);/* Type */
+build_append_int_noprefix(table_data, 8, 2);/* Length */
+build_append_int_noprefix(table_data, 0x1, 2);  /* Revision */
+build_append_int_noprefix(table_data, 0, 1);/* Reserved */
+/* MMU Type */
+if (satp_mode_max == VM_1_10_SV57) {
+build_append_int_noprefix(table_data, 2, 1);/* Sv57 */
+} else if (satp_mode_max == VM_1_10_SV48) {
+build_append_int_noprefix(table_data, 1, 1);/* Sv48 */
+} else if (satp_mode_max == VM_1_10_SV39) {
+build_append_int_noprefix(table_data, 0, 1);/* Sv39 */
+} else {
+assert(1);
+}
+}
+
 /* Hart Info Node */
 for (int i = 0; i < arch_ids->len; i++) {
 len = 16;
@@ -238,17 +264,25 @@ static void build_rhct(GArray *table_data,
 num_offsets++;
 }
 
+if (mmu_offset) {
+len += 4;
+num_offsets++;
+}
+
 build_append_int_noprefix(table_data, len, 2);
 build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
 /* Number of offsets */
 build_append_int_noprefix(table_data, num_offsets, 2);
 build_append_int_noprefix(table_data, i, 4);   /* ACPI Processor UID */
-
 /* Offsets */
 build_append_int_noprefix(table_data, isa_offset, 4);
 if (cmo_offset) {
 build_append_int_noprefix(table_data, cmo_offset, 4);
 }
+
+if (mmu_offset) {
+build_append_int_noprefix(table_data, mmu_offset, 4);
+}
 }
 
 acpi_table_end(linker, &table);
-- 
2.43.0




[PULL 07/65] target/riscv/kvm: change KVM_REG_RISCV_FP_F to u32

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

KVM_REG_RISCV_FP_F regs have u32 size according to the API, but by using
kvm_riscv_reg_id() in RISCV_FP_F_REG() we're returning u64 sizes when
running with TARGET_RISCV64. The most likely reason why no one noticed
this is because we're not implementing kvm_cpu_synchronize_state() in
RISC-V yet.

Create a new helper that returns a KVM ID with u32 size and use it in
RISCV_FP_F_REG().

Reported-by: Andrew Jones 
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Message-ID: <20231208183835.2411523-2-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 117e33cf90..375c8e7f33 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -72,6 +72,11 @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, 
uint64_t type,
 return id;
 }
 
+static uint64_t kvm_riscv_reg_id_u32(uint64_t type, uint64_t idx)
+{
+return KVM_REG_RISCV | KVM_REG_SIZE_U32 | type | idx;
+}
+
 #define RISCV_CORE_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \
  KVM_REG_RISCV_CORE_REG(name))
 
@@ -81,7 +86,7 @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t 
type,
 #define RISCV_TIMER_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_TIMER, 
\
  KVM_REG_RISCV_TIMER_REG(name))
 
-#define RISCV_FP_F_REG(env, idx)  kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_F, 
idx)
+#define RISCV_FP_F_REG(idx)  kvm_riscv_reg_id_u32(KVM_REG_RISCV_FP_F, idx)
 
 #define RISCV_FP_D_REG(env, idx)  kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, 
idx)
 
@@ -586,7 +591,7 @@ static int kvm_riscv_get_regs_fp(CPUState *cs)
 if (riscv_has_ext(env, RVF)) {
 uint32_t reg;
 for (i = 0; i < 32; i++) {
-ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(env, i), ®);
+ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(i), ®);
 if (ret) {
 return ret;
 }
@@ -620,7 +625,7 @@ static int kvm_riscv_put_regs_fp(CPUState *cs)
 uint32_t reg;
 for (i = 0; i < 32; i++) {
 reg = env->fpr[i];
-ret = kvm_set_one_reg(cs, RISCV_FP_F_REG(env, i), ®);
+ret = kvm_set_one_reg(cs, RISCV_FP_F_REG(i), ®);
 if (ret) {
 return ret;
 }
-- 
2.43.0




[PULL 08/65] target/riscv/kvm: change KVM_REG_RISCV_FP_D to u64

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

KVM_REG_RISCV_FP_D regs are always u64 size. Using kvm_riscv_reg_id() in
RISCV_FP_D_REG() ends up encoding the wrong size if we're running with
TARGET_RISCV32.

Create a new helper that returns a KVM ID with u64 size and use it with
RISCV_FP_D_REG().

Reported-by: Andrew Jones 
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Message-ID: <20231208183835.2411523-3-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 375c8e7f33..9370c72f9b 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -77,6 +77,11 @@ static uint64_t kvm_riscv_reg_id_u32(uint64_t type, uint64_t 
idx)
 return KVM_REG_RISCV | KVM_REG_SIZE_U32 | type | idx;
 }
 
+static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t idx)
+{
+return KVM_REG_RISCV | KVM_REG_SIZE_U64 | type | idx;
+}
+
 #define RISCV_CORE_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \
  KVM_REG_RISCV_CORE_REG(name))
 
@@ -88,7 +93,7 @@ static uint64_t kvm_riscv_reg_id_u32(uint64_t type, uint64_t 
idx)
 
 #define RISCV_FP_F_REG(idx)  kvm_riscv_reg_id_u32(KVM_REG_RISCV_FP_F, idx)
 
-#define RISCV_FP_D_REG(env, idx)  kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, 
idx)
+#define RISCV_FP_D_REG(idx)  kvm_riscv_reg_id_u64(KVM_REG_RISCV_FP_D, idx)
 
 #define KVM_RISCV_GET_CSR(cs, env, csr, reg) \
 do { \
@@ -579,7 +584,7 @@ static int kvm_riscv_get_regs_fp(CPUState *cs)
 if (riscv_has_ext(env, RVD)) {
 uint64_t reg;
 for (i = 0; i < 32; i++) {
-ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(env, i), ®);
+ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(i), ®);
 if (ret) {
 return ret;
 }
@@ -613,7 +618,7 @@ static int kvm_riscv_put_regs_fp(CPUState *cs)
 uint64_t reg;
 for (i = 0; i < 32; i++) {
 reg = env->fpr[i];
-ret = kvm_set_one_reg(cs, RISCV_FP_D_REG(env, i), ®);
+ret = kvm_set_one_reg(cs, RISCV_FP_D_REG(i), ®);
 if (ret) {
 return ret;
 }
-- 
2.43.0




[PULL 02/65] target/riscv: The whole vector register move instructions depend on vsew

2024-01-10 Thread Alistair Francis
From: Max Chou 

The RISC-V v spec 16.6 section says that the whole vector register move
instructions operate as if EEW=SEW. So it should depends on the vsew
field of vtype register.

Signed-off-by: Max Chou 
Acked-by: Richard Henderson 
Message-ID: <20231129170400.21251-3-max.c...@sifive.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 114ad87397..3871f0ea73 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3643,8 +3643,7 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) 
  \
 QEMU_IS_ALIGNED(a->rs2, LEN)) { \
 uint32_t maxsz = (s->cfg_ptr->vlen >> 3) * LEN; \
 if (s->vstart_eq_zero) {\
-/* EEW = 8 */   \
-tcg_gen_gvec_mov(MO_8, vreg_ofs(s, a->rd),  \
+tcg_gen_gvec_mov(s->sew, vreg_ofs(s, a->rd),\
  vreg_ofs(s, a->rs2), maxsz, maxsz);\
 mark_vs_dirty(s);   \
 } else {\
-- 
2.43.0




[PULL 14/65] hw/i386/acpi-microvm.c: Use common function to add virtio in DSDT

2024-01-10 Thread Alistair Francis
From: Sunil V L 

With common function to add virtio in DSDT created now, update microvm
code also to use it instead of duplicate code.

Suggested-by: Andrew Jones 
Signed-off-by: Sunil V L 
Acked-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-4-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/i386/acpi-microvm.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index 2909a73933..279da6b4aa 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -37,6 +37,7 @@
 #include "hw/pci/pci.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/usb/xhci.h"
+#include "hw/virtio/virtio-acpi.h"
 #include "hw/virtio/virtio-mmio.h"
 #include "hw/input/i8042.h"
 
@@ -77,19 +78,7 @@ static void acpi_dsdt_add_virtio(Aml *scope,
 uint32_t irq = mms->virtio_irq_base + index;
 hwaddr base = VIRTIO_MMIO_BASE + index * 512;
 hwaddr size = 512;
-
-Aml *dev = aml_device("VR%02u", (unsigned)index);
-aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005")));
-aml_append(dev, aml_name_decl("_UID", aml_int(index)));
-aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
-
-Aml *crs = aml_resource_template();
-aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE));
-aml_append(crs,
-   aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, &irq, 1));
-aml_append(dev, aml_name_decl("_CRS", crs));
-aml_append(scope, dev);
+virtio_acpi_dsdt_add(scope, base, size, irq, index, 1);
 }
 }
 }
-- 
2.43.0




[PULL 11/65] target/riscv/kvm: rename riscv_reg_id() to riscv_reg_id_ulong()

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

kvm_riscv_reg_id() returns an id encoded with an ulong size, i.e. an u32
size when running TARGET_RISCV32 and u64 when running TARGET_RISCV64.

Rename it to kvm_riscv_reg_id_ulong() to enhance code readability. It'll
be in line with the existing kvm_riscv_reg_id_() helpers.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Message-ID: <20231208183835.2411523-6-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 40 --
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 15573402be..a31df6e273 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -54,7 +54,7 @@ void riscv_kvm_aplic_request(void *opaque, int irq, int level)
 
 static bool cap_has_mp_state;
 
-static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
+static uint64_t kvm_riscv_reg_id_ulong(CPURISCVState *env, uint64_t type,
  uint64_t idx)
 {
 uint64_t id = KVM_REG_RISCV | type | idx;
@@ -82,15 +82,17 @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, 
uint64_t idx)
 return KVM_REG_RISCV | KVM_REG_SIZE_U64 | type | idx;
 }
 
-#define RISCV_CORE_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \
- KVM_REG_RISCV_CORE_REG(name))
+#define RISCV_CORE_REG(env, name) \
+kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CORE, \
+   KVM_REG_RISCV_CORE_REG(name))
 
-#define RISCV_CSR_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
- KVM_REG_RISCV_CSR_REG(name))
+#define RISCV_CSR_REG(env, name) \
+kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CSR, \
+   KVM_REG_RISCV_CSR_REG(name))
 
 #define RISCV_CONFIG_REG(env, name) \
-kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, \
- KVM_REG_RISCV_CONFIG_REG(name))
+kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CONFIG, \
+   KVM_REG_RISCV_CONFIG_REG(name))
 
 #define RISCV_TIMER_REG(name)  kvm_riscv_reg_id_u64(KVM_REG_RISCV_TIMER, \
  KVM_REG_RISCV_TIMER_REG(name))
@@ -216,8 +218,8 @@ static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, 
CPUState *cs)
 
 /* If we're here we're going to disable the MISA bit */
 reg = 0;
-id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
-  misa_cfg->kvm_reg_id);
+id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_ISA_EXT,
+misa_cfg->kvm_reg_id);
 ret = kvm_set_one_reg(cs, id, ®);
 if (ret != 0) {
 /*
@@ -378,8 +380,8 @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, 
CPUState *cs)
 continue;
 }
 
-id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
-  multi_ext_cfg->kvm_reg_id);
+id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_ISA_EXT,
+multi_ext_cfg->kvm_reg_id);
 reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
 ret = kvm_set_one_reg(cs, id, ®);
 if (ret != 0) {
@@ -509,7 +511,7 @@ static int kvm_riscv_get_regs_core(CPUState *cs)
 env->pc = reg;
 
 for (i = 1; i < 32; i++) {
-uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
+uint64_t id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CORE, i);
 ret = kvm_get_one_reg(cs, id, ®);
 if (ret) {
 return ret;
@@ -534,7 +536,7 @@ static int kvm_riscv_put_regs_core(CPUState *cs)
 }
 
 for (i = 1; i < 32; i++) {
-uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
+uint64_t id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CORE, i);
 reg = env->gpr[i];
 ret = kvm_set_one_reg(cs, id, ®);
 if (ret) {
@@ -810,8 +812,8 @@ static void kvm_riscv_read_cbomz_blksize(RISCVCPU *cpu, 
KVMScratchCPU *kvmcpu,
 struct kvm_one_reg reg;
 int ret;
 
-reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
-  cbomz_cfg->kvm_reg_id);
+reg.id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CONFIG,
+cbomz_cfg->kvm_reg_id);
 reg.addr = (uint64_t)kvmconfig_get_cfg_addr(cpu, cbomz_cfg);
 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
 if (ret != 0) {
@@ -832,8 +834,8 @@ static void kvm_riscv_read_multiext_legacy(RISCVCPU *cpu,
 KVMCPUConfig *multi_ext_cfg = &kvm_multi_ext_cfgs[i];
 struct kvm_one_reg reg;
 
-reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
-  multi_ext_cfg->kvm_reg_id);
+reg.id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_ISA_EXT,
+multi_ext_cfg->kvm_reg_id);
 reg.addr = (uint64_t)&val;
 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
 if (ret != 0)

[PULL 23/65] hw/riscv/virt-acpi-build.c: Add IO controllers and devices

2024-01-10 Thread Alistair Francis
From: Sunil V L 

Add basic IO controllers and devices like PCI, VirtIO and UART in the
ACPI namespace.

Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-13-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt-acpi-build.c | 79 --
 hw/riscv/Kconfig   |  1 +
 2 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index b7db57b28a..536e6b0243 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -27,15 +27,18 @@
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/aml-build.h"
+#include "hw/acpi/pci.h"
 #include "hw/acpi/utils.h"
+#include "hw/intc/riscv_aclint.h"
 #include "hw/nvram/fw_cfg_acpi.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/riscv/virt.h"
+#include "hw/riscv/numa.h"
+#include "hw/virtio/virtio-acpi.h"
+#include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "sysemu/reset.h"
-#include "migration/vmstate.h"
-#include "hw/riscv/virt.h"
-#include "hw/riscv/numa.h"
-#include "hw/intc/riscv_aclint.h"
 
 #define ACPI_BUILD_TABLE_SIZE 0x2
 #define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index))
@@ -132,6 +135,39 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState 
*s)
 }
 }
 
+static void
+acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
+uint32_t uart_irq)
+{
+Aml *dev = aml_device("COM0");
+aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(uart_memmap->base,
+ uart_memmap->size, AML_READ_WRITE));
+aml_append(crs,
+aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
+   AML_EXCLUSIVE, &uart_irq, 1));
+aml_append(dev, aml_name_decl("_CRS", crs));
+
+Aml *pkg = aml_package(2);
+aml_append(pkg, aml_string("clock-frequency"));
+aml_append(pkg, aml_int(3686400));
+
+Aml *UUID = aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301");
+
+Aml *pkg1 = aml_package(1);
+aml_append(pkg1, pkg);
+
+Aml *package = aml_package(2);
+aml_append(package, UUID);
+aml_append(package, pkg1);
+
+aml_append(dev, aml_name_decl("_DSD", package));
+aml_append(scope, dev);
+}
+
 /* RHCT Node[N] starts at offset 56 */
 #define RHCT_NODE_ARRAY_OFFSET 56
 
@@ -310,6 +346,8 @@ static void build_dsdt(GArray *table_data,
RISCVVirtState *s)
 {
 Aml *scope, *dsdt;
+MachineState *ms = MACHINE(s);
+uint8_t socket_count;
 const MemMapEntry *memmap = s->memmap;
 AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = s->oem_id,
 .oem_table_id = s->oem_table_id };
@@ -329,6 +367,29 @@ static void build_dsdt(GArray *table_data,
 
 fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]);
 
+socket_count = riscv_socket_count(ms);
+
+acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0], UART0_IRQ);
+
+if (socket_count == 1) {
+virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
+ memmap[VIRT_VIRTIO].size,
+ VIRTIO_IRQ, 0, VIRTIO_COUNT);
+acpi_dsdt_add_gpex_host(scope, PCIE_IRQ);
+} else if (socket_count == 2) {
+virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
+ memmap[VIRT_VIRTIO].size,
+ VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
+ VIRTIO_COUNT);
+acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES);
+} else {
+virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
+ memmap[VIRT_VIRTIO].size,
+ VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
+ VIRTIO_COUNT);
+acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 
2);
+}
+
 aml_append(dsdt, scope);
 
 /* copy AML table into ACPI tables blob and patch header there */
@@ -465,6 +526,16 @@ static void virt_acpi_build(RISCVVirtState *s, 
AcpiBuildTables *tables)
 acpi_add_table(table_offsets, tables_blob);
 build_rhct(tables_blob, tables->linker, s);
 
+acpi_add_table(table_offsets, tables_blob);
+{
+AcpiMcfgInfo mcfg = {
+   .base = s->memmap[VIRT_PCIE_MMIO].base,
+   .size = s->memmap[VIRT_PCIE_MMIO].size,
+};
+build_mcfg(tables_blob, tables->linker, &mcfg, s->oem_id,
+   s->oem_table_id);
+}
+
 /* XSDT is pointed to by RSDP */
 xsdt = tables_blob->len;
 build_xsdt(tables_blob, tables->linker, table_offsets, s->oem_id,
diff --git a/

[PULL 22/65] hw/riscv/virt: Update GPEX MMIO related properties

2024-01-10 Thread Alistair Francis
From: Sunil V L 

Update the GPEX host bridge properties related to MMIO ranges with
values set for the virt machine.

Suggested-by: Igor Mammedov 
Signed-off-by: Sunil V L 
Reviewed-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-12-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/virt.h |  1 +
 hw/riscv/virt.c | 47 -
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 5b03575ed3..f89790fd58 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -61,6 +61,7 @@ struct RISCVVirtState {
 char *oem_table_id;
 OnOffAuto acpi;
 const MemMapEntry *memmap;
+struct GPEXHost *gpex_host;
 };
 
 enum {
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 9e7629c51c..a7c4c3508e 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1054,21 +1054,45 @@ static void create_fdt(RISCVVirtState *s, const 
MemMapEntry *memmap)
 }
 
 static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
-  hwaddr ecam_base, hwaddr ecam_size,
-  hwaddr mmio_base, hwaddr mmio_size,
-  hwaddr high_mmio_base,
-  hwaddr high_mmio_size,
-  hwaddr pio_base,
-  DeviceState *irqchip)
+  DeviceState *irqchip,
+  RISCVVirtState *s)
 {
 DeviceState *dev;
 MemoryRegion *ecam_alias, *ecam_reg;
 MemoryRegion *mmio_alias, *high_mmio_alias, *mmio_reg;
+hwaddr ecam_base = s->memmap[VIRT_PCIE_ECAM].base;
+hwaddr ecam_size = s->memmap[VIRT_PCIE_ECAM].size;
+hwaddr mmio_base = s->memmap[VIRT_PCIE_MMIO].base;
+hwaddr mmio_size = s->memmap[VIRT_PCIE_MMIO].size;
+hwaddr high_mmio_base = virt_high_pcie_memmap.base;
+hwaddr high_mmio_size = virt_high_pcie_memmap.size;
+hwaddr pio_base = s->memmap[VIRT_PCIE_PIO].base;
+hwaddr pio_size = s->memmap[VIRT_PCIE_PIO].size;
 qemu_irq irq;
 int i;
 
 dev = qdev_new(TYPE_GPEX_HOST);
 
+/* Set GPEX object properties for the virt machine */
+object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_BASE,
+ecam_base, NULL);
+object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_SIZE,
+ecam_size, NULL);
+object_property_set_uint(OBJECT(GPEX_HOST(dev)),
+ PCI_HOST_BELOW_4G_MMIO_BASE,
+ mmio_base, NULL);
+object_property_set_int(OBJECT(GPEX_HOST(dev)), 
PCI_HOST_BELOW_4G_MMIO_SIZE,
+mmio_size, NULL);
+object_property_set_uint(OBJECT(GPEX_HOST(dev)),
+ PCI_HOST_ABOVE_4G_MMIO_BASE,
+ high_mmio_base, NULL);
+object_property_set_int(OBJECT(GPEX_HOST(dev)), 
PCI_HOST_ABOVE_4G_MMIO_SIZE,
+high_mmio_size, NULL);
+object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_BASE,
+pio_base, NULL);
+object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_SIZE,
+pio_size, NULL);
+
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 
 ecam_alias = g_new0(MemoryRegion, 1);
@@ -1099,6 +1123,7 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion 
*sys_mem,
 gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ + i);
 }
 
+GPEX_HOST(dev)->gpex_cfg.bus = PCI_HOST_BRIDGE(GPEX_HOST(dev))->bus;
 return dev;
 }
 
@@ -1494,15 +1519,7 @@ static void virt_machine_init(MachineState *machine)
 qdev_get_gpio_in(virtio_irqchip, VIRTIO_IRQ + i));
 }
 
-gpex_pcie_init(system_memory,
-   memmap[VIRT_PCIE_ECAM].base,
-   memmap[VIRT_PCIE_ECAM].size,
-   memmap[VIRT_PCIE_MMIO].base,
-   memmap[VIRT_PCIE_MMIO].size,
-   virt_high_pcie_memmap.base,
-   virt_high_pcie_memmap.size,
-   memmap[VIRT_PCIE_PIO].base,
-   pcie_irqchip);
+gpex_pcie_init(system_memory, pcie_irqchip, s);
 
 create_platform_bus(s, mmio_irqchip);
 
-- 
2.43.0




[PULL 13/65] hw/arm/virt-acpi-build.c: Migrate virtio creation to common location

2024-01-10 Thread Alistair Francis
From: Sunil V L 

RISC-V also needs to create the virtio in DSDT in the same way as ARM.
So, instead of duplicating the code, move this function to the device
specific file which is common across architectures.

Suggested-by: Igor Mammedov 
Signed-off-by: Sunil V L 
Reviewed-by: Alistair Francis 
Reviewed-by: Andrew Jones 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-3-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 include/hw/virtio/virtio-acpi.h | 16 
 hw/arm/virt-acpi-build.c| 32 
 hw/virtio/virtio-acpi.c | 33 +
 hw/virtio/meson.build   |  1 +
 4 files changed, 54 insertions(+), 28 deletions(-)
 create mode 100644 include/hw/virtio/virtio-acpi.h
 create mode 100644 hw/virtio/virtio-acpi.c

diff --git a/include/hw/virtio/virtio-acpi.h b/include/hw/virtio/virtio-acpi.h
new file mode 100644
index 00..844e102569
--- /dev/null
+++ b/include/hw/virtio/virtio-acpi.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * ACPI support for virtio
+ */
+
+#ifndef VIRTIO_ACPI_H
+#define VIRTIO_ACPI_H
+
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+
+void virtio_acpi_dsdt_add(Aml *scope, const hwaddr virtio_mmio_base,
+  const hwaddr virtio_mmio_size, uint32_t mmio_irq,
+  long int start_index, int num);
+
+#endif
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index b6edf9db00..a22a2f43a5 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -58,6 +58,7 @@
 #include "migration/vmstate.h"
 #include "hw/acpi/ghes.h"
 #include "hw/acpi/viot.h"
+#include "hw/virtio/virtio-acpi.h"
 
 #define ARM_SPI_BASE 32
 
@@ -118,32 +119,6 @@ static void acpi_dsdt_add_flash(Aml *scope, const 
MemMapEntry *flash_memmap)
 aml_append(scope, dev);
 }
 
-static void acpi_dsdt_add_virtio(Aml *scope,
- const MemMapEntry *virtio_mmio_memmap,
- uint32_t mmio_irq, int num)
-{
-hwaddr base = virtio_mmio_memmap->base;
-hwaddr size = virtio_mmio_memmap->size;
-int i;
-
-for (i = 0; i < num; i++) {
-uint32_t irq = mmio_irq + i;
-Aml *dev = aml_device("VR%02u", i);
-aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005")));
-aml_append(dev, aml_name_decl("_UID", aml_int(i)));
-aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
-
-Aml *crs = aml_resource_template();
-aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE));
-aml_append(crs,
-   aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, &irq, 1));
-aml_append(dev, aml_name_decl("_CRS", crs));
-aml_append(scope, dev);
-base += size;
-}
-}
-
 static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
   uint32_t irq, VirtMachineState *vms)
 {
@@ -850,8 +825,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
 }
 fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]);
-acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
-(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
+virtio_acpi_dsdt_add(scope, memmap[VIRT_MMIO].base, memmap[VIRT_MMIO].size,
+ (irqmap[VIRT_MMIO] + ARM_SPI_BASE),
+ 0, NUM_VIRTIO_TRANSPORTS);
 acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms);
 if (vms->acpi_dev) {
 build_ged_aml(scope, "\\_SB."GED_DEVICE,
diff --git a/hw/virtio/virtio-acpi.c b/hw/virtio/virtio-acpi.c
new file mode 100644
index 00..e18cb38bdb
--- /dev/null
+++ b/hw/virtio/virtio-acpi.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * virtio ACPI Support
+ *
+ */
+
+#include "hw/virtio/virtio-acpi.h"
+#include "hw/acpi/aml-build.h"
+
+void virtio_acpi_dsdt_add(Aml *scope, const hwaddr base, const hwaddr size,
+  uint32_t mmio_irq, long int start_index, int num)
+{
+hwaddr virtio_base = base;
+uint32_t irq = mmio_irq;
+long int i;
+
+for (i = start_index; i < start_index + num; i++) {
+Aml *dev = aml_device("VR%02u", (unsigned)i);
+aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005")));
+aml_append(dev, aml_name_decl("_UID", aml_int(i)));
+aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(virtio_base, size, AML_READ_WRITE));
+aml_append(crs,
+   aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
+ AML_EXCLUSIVE, &irq, 1));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+vi

[PULL 24/65] hw/riscv/virt-acpi-build.c: Add PLIC in MADT

2024-01-10 Thread Alistair Francis
From: Sunil V L 

Add PLIC structures for each socket in the MADT when system is
configured with PLIC as the external interrupt controller.

Signed-off-by: Haibo Xu 
Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Acked-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-14-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt-acpi-build.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 536e6b0243..26c7e4482d 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -94,6 +94,12 @@ static void riscv_acpi_madt_add_rintc(uint32_t uid,
   arch_ids->cpus[uid].props.node_id,
   local_cpu_id),
   4);
+} else if (s->aia_type == VIRT_AIA_TYPE_NONE) {
+build_append_int_noprefix(entry,
+  ACPI_BUILD_INTC_ID(
+  arch_ids->cpus[uid].props.node_id,
+  2 * local_cpu_id + 1),
+  4);
 } else {
 build_append_int_noprefix(entry, 0, 4);
 }
@@ -494,6 +500,29 @@ static void build_madt(GArray *table_data,
 build_append_int_noprefix(table_data,
   s->memmap[VIRT_APLIC_S].size, 4);
 }
+} else {
+/* PLICs */
+for (socket = 0; socket < riscv_socket_count(ms); socket++) {
+aplic_addr = s->memmap[VIRT_PLIC].base +
+ s->memmap[VIRT_PLIC].size * socket;
+gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
+build_append_int_noprefix(table_data, 0x1B, 1);   /* Type */
+build_append_int_noprefix(table_data, 36, 1); /* Length */
+build_append_int_noprefix(table_data, 1, 1);  /* Version */
+build_append_int_noprefix(table_data, socket, 1); /* PLIC ID */
+build_append_int_noprefix(table_data, 0, 8);  /* Hardware ID */
+/* Total External Interrupt Sources Supported */
+build_append_int_noprefix(table_data,
+  VIRT_IRQCHIP_NUM_SOURCES - 1, 2);
+build_append_int_noprefix(table_data, 0, 2); /* Max Priority */
+build_append_int_noprefix(table_data, 0, 4); /* Flags */
+/* PLIC Size */
+build_append_int_noprefix(table_data, s->memmap[VIRT_PLIC].size, 
4);
+/* PLIC Address */
+build_append_int_noprefix(table_data, aplic_addr, 8);
+/* Global System Interrupt Vector Base */
+build_append_int_noprefix(table_data, gsi_base, 4);
+}
 }
 
 acpi_table_end(linker, &table);
-- 
2.43.0




[PULL 26/65] target/riscv: Add support for Zacas extension

2024-01-10 Thread Alistair Francis
From: Weiwei Li 

Add support for amocas.w/d/q instructions which are part of the ratified
Zacas extension: https://github.com/riscv/riscv-zacas

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Signed-off-by: Rob Bradford 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20231207153842.32401-2-rbradf...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_cfg.h  |   1 +
 target/riscv/insn32.decode  |   6 +
 target/riscv/cpu.c  |   2 +
 target/riscv/tcg/tcg-cpu.c  |   5 +
 target/riscv/translate.c|   1 +
 target/riscv/insn_trans/trans_rvzacas.c.inc | 150 
 6 files changed, 165 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzacas.c.inc

diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index f4605fb190..d516de4a44 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -77,6 +77,7 @@ struct RISCVCPUConfig {
 bool ext_svnapot;
 bool ext_svpbmt;
 bool ext_zdinx;
+bool ext_zacas;
 bool ext_zawrs;
 bool ext_zfa;
 bool ext_zfbfmin;
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 33597fe2bb..f22df04cfd 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -1004,3 +1004,9 @@ vgmul_vv101000 1 . 10001 010 . 1110111 
@r2_vm_1
 vsm4k_vi11 1 . . 010 . 1110111 @r_vm_1
 vsm4r_vv101000 1 . 1 010 . 1110111 @r2_vm_1
 vsm4r_vs101001 1 . 1 010 . 1110111 @r2_vm_1
+
+# *** RV32 Zacas Standard Extension ***
+amocas_w00101 . . . . 010 . 010 @atom_st
+amocas_d00101 . . . . 011 . 010 @atom_st
+# *** RV64 Zacas Standard Extension ***
+amocas_q00101 . . . . 100 . 010 @atom_st
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 53b82cc581..21b0eddf6f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -87,6 +87,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
 ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm),
 ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
+ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas),
 ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
 ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
 ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
@@ -1297,6 +1298,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
 MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
 MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
 MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
+MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false),
 MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
 MULTI_EXT_CFG_BOOL("zfa", ext_zfa, true),
 MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 8a35683a34..29b5a88931 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -343,6 +343,11 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 return;
 }
 
+if ((cpu->cfg.ext_zacas) && !riscv_has_ext(env, RVA)) {
+error_setg(errp, "Zacas extension requires A extension");
+return;
+}
+
 if ((cpu->cfg.ext_zawrs) && !riscv_has_ext(env, RVA)) {
 error_setg(errp, "Zawrs extension requires A extension");
 return;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f0be79bb16..071fbad7ef 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1089,6 +1089,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvv.c.inc"
 #include "insn_trans/trans_rvb.c.inc"
 #include "insn_trans/trans_rvzicond.c.inc"
+#include "insn_trans/trans_rvzacas.c.inc"
 #include "insn_trans/trans_rvzawrs.c.inc"
 #include "insn_trans/trans_rvzicbo.c.inc"
 #include "insn_trans/trans_rvzfa.c.inc"
diff --git a/target/riscv/insn_trans/trans_rvzacas.c.inc 
b/target/riscv/insn_trans/trans_rvzacas.c.inc
new file mode 100644
index 00..5d274d4c08
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzacas.c.inc
@@ -0,0 +1,150 @@
+/*
+ * RISC-V translation routines for the RV64 Zacas Standard Extension.
+ *
+ * Copyright (c) 2020-2023 PLCT Lab
+ *
+ * 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 

[PULL 43/65] target/riscv/tcg: honor user choice for G MISA bits

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

RVG behaves like a profile: a single flag enables a set of bits. Right
now we're considering user choice when handling RVG and zicsr/zifencei
and ignoring user choice on MISA bits.

We'll add user warnings for profiles when the user disables its
mandatory extensions in the next patch. We'll do the same thing with RVG
now to keep consistency between RVG and profile handling.

First and foremost, create a new RVG only helper to avoid clogging
riscv_cpu_validate_set_extensions(). We do not want to annoy users with
RVG warnings like we did in the past (see 9b9741c38f), thus we'll only
warn if RVG was user set and the user disabled a RVG extension in the
command line.

For every RVG MISA bit (IMAFD), zicsr and zifencei, the logic then
becomes:

- if enabled, do nothing;
- if disabled and not user set, enable it;
- if disabled and user set, throw a warning that it's a RVG mandatory
  extension.

This same logic will be used for profiles in the next patch.

Note that this is a behavior change, where we would error out if the
user disabled either zicsr or zifencei. As long as users are explicitly
disabling things in the command line we'll let them have a go at it, at
least in this step. We'll error out later in the validation if needed.

Other notable changes from the previous RVG code:

- use riscv_cpu_write_misa_bit() instead of manually updating both
  env->misa_ext and env->misa_ext_mask;

- set zicsr and zifencei directly. We're already checking if they
  were user set and priv version will never fail for these
  extensions, making cpu_cfg_ext_auto_update() redundant.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-16-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 73 +-
 1 file changed, 48 insertions(+), 25 deletions(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index f1eeaa12b9..d2a42a347b 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -42,6 +42,12 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
  GUINT_TO_POINTER(ext_offset));
 }
 
+static bool cpu_misa_ext_is_user_set(uint32_t misa_bit)
+{
+return g_hash_table_contains(misa_ext_user_opts,
+ GUINT_TO_POINTER(misa_bit));
+}
+
 static void cpu_cfg_ext_add_user_opt(uint32_t ext_offset, bool value)
 {
 g_hash_table_insert(multi_ext_user_opts, GUINT_TO_POINTER(ext_offset),
@@ -357,6 +363,46 @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu)
   cpu->cfg.cboz_blocksize == 64;
 }
 
+static void riscv_cpu_validate_g(RISCVCPU *cpu)
+{
+const char *warn_msg = "RVG mandates disabled extension %s";
+uint32_t g_misa_bits[] = {RVI, RVM, RVA, RVF, RVD};
+bool send_warn = cpu_misa_ext_is_user_set(RVG);
+
+for (int i = 0; i < ARRAY_SIZE(g_misa_bits); i++) {
+uint32_t bit = g_misa_bits[i];
+
+if (riscv_has_ext(&cpu->env, bit)) {
+continue;
+}
+
+if (!cpu_misa_ext_is_user_set(bit)) {
+riscv_cpu_write_misa_bit(cpu, bit, true);
+continue;
+}
+
+if (send_warn) {
+warn_report(warn_msg, riscv_get_misa_ext_name(bit));
+}
+}
+
+if (!cpu->cfg.ext_zicsr) {
+if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicsr))) {
+cpu->cfg.ext_zicsr = true;
+} else if (send_warn) {
+warn_report(warn_msg, "zicsr");
+}
+}
+
+if (!cpu->cfg.ext_zifencei) {
+if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zifencei))) {
+cpu->cfg.ext_zifencei = true;
+} else if (send_warn) {
+warn_report(warn_msg, "zifencei");
+}
+}
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly.
@@ -366,31 +412,8 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 CPURISCVState *env = &cpu->env;
 Error *local_err = NULL;
 
-/* Do some ISA extension error checking */
-if (riscv_has_ext(env, RVG) &&
-!(riscv_has_ext(env, RVI) && riscv_has_ext(env, RVM) &&
-  riscv_has_ext(env, RVA) && riscv_has_ext(env, RVF) &&
-  riscv_has_ext(env, RVD) &&
-  cpu->cfg.ext_zicsr && cpu->cfg.ext_zifencei)) {
-
-if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicsr)) &&
-!cpu->cfg.ext_zicsr) {
-error_setg(errp, "RVG requires Zicsr but user set Zicsr to false");
-return;
-}
-
-if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zifencei)) &&
-!cpu->cfg.ext_zifencei) {
-error_setg(errp, "RVG requires Zifencei but user set "
-   "Zifencei to false");
-return;
-}
-
-cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zicsr), true);

[PULL 19/65] hw/riscv/virt-acpi-build.c: Add CMO information in RHCT

2024-01-10 Thread Alistair Francis
From: Sunil V L 

When CMO related extensions like Zicboz, Zicbom and Zicbop are enabled, the
block size for those extensions need to be communicated via CMO node in
RHCT. Add CMO node in RHCT if any of those CMO extensions are detected.

Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Acked-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-9-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt-acpi-build.c | 64 +-
 1 file changed, 56 insertions(+), 8 deletions(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index f50f022dc2..784bbffead 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -140,6 +140,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState 
*s)
  * 5.2.36 RISC-V Hart Capabilities Table (RHCT)
  * REF: https://github.com/riscv-non-isa/riscv-acpi/issues/16
  *  https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
+ *  https://drive.google.com/file/d/1sKbOa8m1UZw1JkquZYe3F1zQBN1xXsaf/view
  */
 static void build_rhct(GArray *table_data,
BIOSLinker *linker,
@@ -149,8 +150,8 @@ static void build_rhct(GArray *table_data,
 MachineState *ms = MACHINE(s);
 const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
 size_t len, aligned_len;
-uint32_t isa_offset, num_rhct_nodes;
-RISCVCPU *cpu;
+uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0;
+RISCVCPU *cpu = &s->soc[0].harts[0];
 char *isa;
 
 AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id,
@@ -166,6 +167,9 @@ static void build_rhct(GArray *table_data,
 
 /* ISA + N hart info */
 num_rhct_nodes = 1 + ms->smp.cpus;
+if (cpu->cfg.ext_zicbom || cpu->cfg.ext_zicboz) {
+num_rhct_nodes++;
+}
 
 /* Number of RHCT nodes*/
 build_append_int_noprefix(table_data, num_rhct_nodes, 4);
@@ -177,7 +181,6 @@ static void build_rhct(GArray *table_data,
 isa_offset = table_data->len - table.table_offset;
 build_append_int_noprefix(table_data, 0, 2);   /* Type 0 */
 
-cpu = &s->soc[0].harts[0];
 isa = riscv_isa_string(cpu);
 len = 8 + strlen(isa) + 1;
 aligned_len = (len % 2) ? (len + 1) : len;
@@ -193,14 +196,59 @@ static void build_rhct(GArray *table_data,
 build_append_int_noprefix(table_data, 0x0, 1);   /* Optional Padding */
 }
 
+/* CMO node */
+if (cpu->cfg.ext_zicbom || cpu->cfg.ext_zicboz) {
+cmo_offset = table_data->len - table.table_offset;
+build_append_int_noprefix(table_data, 1, 2);/* Type */
+build_append_int_noprefix(table_data, 10, 2);   /* Length */
+build_append_int_noprefix(table_data, 0x1, 2);  /* Revision */
+build_append_int_noprefix(table_data, 0, 1);/* Reserved */
+
+/* CBOM block size */
+if (cpu->cfg.cbom_blocksize) {
+build_append_int_noprefix(table_data,
+  __builtin_ctz(cpu->cfg.cbom_blocksize),
+  1);
+} else {
+build_append_int_noprefix(table_data, 0, 1);
+}
+
+/* CBOP block size */
+build_append_int_noprefix(table_data, 0, 1);
+
+/* CBOZ block size */
+if (cpu->cfg.cboz_blocksize) {
+build_append_int_noprefix(table_data,
+  __builtin_ctz(cpu->cfg.cboz_blocksize),
+  1);
+} else {
+build_append_int_noprefix(table_data, 0, 1);
+}
+}
+
 /* Hart Info Node */
 for (int i = 0; i < arch_ids->len; i++) {
+len = 16;
+int num_offsets = 1;
 build_append_int_noprefix(table_data, 0x, 2);  /* Type */
-build_append_int_noprefix(table_data, 16, 2);  /* Length */
-build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
-build_append_int_noprefix(table_data, 1, 2);/* Number of offsets */
-build_append_int_noprefix(table_data, i, 4);/* ACPI Processor UID 
*/
-build_append_int_noprefix(table_data, isa_offset, 4); /* Offsets[0] */
+
+/* Length */
+if (cmo_offset) {
+len += 4;
+num_offsets++;
+}
+
+build_append_int_noprefix(table_data, len, 2);
+build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
+/* Number of offsets */
+build_append_int_noprefix(table_data, num_offsets, 2);
+build_append_int_noprefix(table_data, i, 4);   /* ACPI Processor UID */
+
+/* Offsets */
+build_append_int_noprefix(table_data, isa_offset, 4);
+if (cmo_offset) {
+build_append_int_noprefix(table_data, cmo_offset, 4);
+}
 }
 
 acpi_table_end(linker, &table);
-- 
2.43.0




[PULL 15/65] hw/riscv: virt: Make few IMSIC macros and functions public

2024-01-10 Thread Alistair Francis
From: Sunil V L 

Some macros and static function related to IMSIC are defined in virt.c.
They are required in virt-acpi-build.c. So, make them public.

Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Reviewed-by: Andrew Jones 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-5-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/virt.h | 25 +
 hw/riscv/virt.c | 25 +
 2 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index e5c474b26e..5b03575ed3 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -23,6 +23,7 @@
 #include "hw/riscv/riscv_hart.h"
 #include "hw/sysbus.h"
 #include "hw/block/flash.h"
+#include "hw/intc/riscv_imsic.h"
 
 #define VIRT_CPUS_MAX_BITS 9
 #define VIRT_CPUS_MAX  (1 << VIRT_CPUS_MAX_BITS)
@@ -127,4 +128,28 @@ enum {
 
 bool virt_is_acpi_enabled(RISCVVirtState *s);
 void virt_acpi_setup(RISCVVirtState *vms);
+uint32_t imsic_num_bits(uint32_t count);
+
+/*
+ * The virt machine physical address space used by some of the devices
+ * namely ACLINT, PLIC, APLIC, and IMSIC depend on number of Sockets,
+ * number of CPUs, and number of IMSIC guest files.
+ *
+ * Various limits defined by VIRT_SOCKETS_MAX_BITS, VIRT_CPUS_MAX_BITS,
+ * and VIRT_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization
+ * of virt machine physical address space.
+ */
+
+#define VIRT_IMSIC_GROUP_MAX_SIZE  (1U << IMSIC_MMIO_GROUP_MIN_SHIFT)
+#if VIRT_IMSIC_GROUP_MAX_SIZE < \
+IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS)
+#error "Can't accomodate single IMSIC group in address space"
+#endif
+
+#define VIRT_IMSIC_MAX_SIZE(VIRT_SOCKETS_MAX * \
+VIRT_IMSIC_GROUP_MAX_SIZE)
+#if 0x400 < VIRT_IMSIC_MAX_SIZE
+#error "Can't accomodate all IMSIC groups in address space"
+#endif
+
 #endif
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index d2eac24156..9e7629c51c 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -38,7 +38,6 @@
 #include "kvm/kvm_riscv.h"
 #include "hw/intc/riscv_aclint.h"
 #include "hw/intc/riscv_aplic.h"
-#include "hw/intc/riscv_imsic.h"
 #include "hw/intc/sifive_plic.h"
 #include "hw/misc/sifive_test.h"
 #include "hw/platform-bus.h"
@@ -54,28 +53,6 @@
 #include "hw/acpi/aml-build.h"
 #include "qapi/qapi-visit-common.h"
 
-/*
- * The virt machine physical address space used by some of the devices
- * namely ACLINT, PLIC, APLIC, and IMSIC depend on number of Sockets,
- * number of CPUs, and number of IMSIC guest files.
- *
- * Various limits defined by VIRT_SOCKETS_MAX_BITS, VIRT_CPUS_MAX_BITS,
- * and VIRT_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization
- * of virt machine physical address space.
- */
-
-#define VIRT_IMSIC_GROUP_MAX_SIZE  (1U << IMSIC_MMIO_GROUP_MIN_SHIFT)
-#if VIRT_IMSIC_GROUP_MAX_SIZE < \
-IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS)
-#error "Can't accommodate single IMSIC group in address space"
-#endif
-
-#define VIRT_IMSIC_MAX_SIZE(VIRT_SOCKETS_MAX * \
-VIRT_IMSIC_GROUP_MAX_SIZE)
-#if 0x400 < VIRT_IMSIC_MAX_SIZE
-#error "Can't accommodate all IMSIC groups in address space"
-#endif
-
 /* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
 static bool virt_use_kvm_aia(RISCVVirtState *s)
 {
@@ -512,7 +489,7 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
 g_free(plic_cells);
 }
 
-static uint32_t imsic_num_bits(uint32_t count)
+uint32_t imsic_num_bits(uint32_t count)
 {
 uint32_t ret = 0;
 
-- 
2.43.0




[PULL 16/65] hw/riscv/virt-acpi-build.c: Add AIA support in RINTC

2024-01-10 Thread Alistair Francis
From: Sunil V L 

Update the RINTC structure in MADT with AIA related fields.

Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Reviewed-by: Andrew Jones 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-6-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt-acpi-build.c | 43 ++
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index fc04d1defa..8f61fd63eb 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -38,6 +38,7 @@
 #include "hw/intc/riscv_aclint.h"
 
 #define ACPI_BUILD_TABLE_SIZE 0x2
+#define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index))
 
 typedef struct AcpiBuildState {
 /* Copy of table in RAM (for patching) */
@@ -59,17 +60,50 @@ static void acpi_align_size(GArray *blob, unsigned align)
 
 static void riscv_acpi_madt_add_rintc(uint32_t uid,
   const CPUArchIdList *arch_ids,
-  GArray *entry)
+  GArray *entry,
+  RISCVVirtState *s)
 {
+uint8_t  guest_index_bits = imsic_num_bits(s->aia_guests + 1);
 uint64_t hart_id = arch_ids->cpus[uid].arch_id;
+uint32_t imsic_size, local_cpu_id, socket_id;
+uint64_t imsic_socket_addr, imsic_addr;
+MachineState *ms = MACHINE(s);
 
+socket_id = arch_ids->cpus[uid].props.node_id;
+local_cpu_id = (arch_ids->cpus[uid].arch_id -
+riscv_socket_first_hartid(ms, socket_id)) %
+riscv_socket_hart_count(ms, socket_id);
+imsic_socket_addr = s->memmap[VIRT_IMSIC_S].base +
+(socket_id * VIRT_IMSIC_GROUP_MAX_SIZE);
+imsic_size = IMSIC_HART_SIZE(guest_index_bits);
+imsic_addr = imsic_socket_addr + local_cpu_id * imsic_size;
 build_append_int_noprefix(entry, 0x18, 1);   /* Type */
-build_append_int_noprefix(entry, 20, 1); /* Length   */
+build_append_int_noprefix(entry, 36, 1); /* Length   */
 build_append_int_noprefix(entry, 1, 1);  /* Version  */
 build_append_int_noprefix(entry, 0, 1);  /* Reserved */
 build_append_int_noprefix(entry, 0x1, 4);/* Flags*/
 build_append_int_noprefix(entry, hart_id, 8);/* Hart ID  */
 build_append_int_noprefix(entry, uid, 4);/* ACPI Processor UID */
+/* External Interrupt Controller ID */
+if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
+build_append_int_noprefix(entry,
+  ACPI_BUILD_INTC_ID(
+  arch_ids->cpus[uid].props.node_id,
+  local_cpu_id),
+  4);
+} else {
+build_append_int_noprefix(entry, 0, 4);
+}
+
+if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
+/* IMSIC Base address */
+build_append_int_noprefix(entry, imsic_addr, 8);
+/* IMSIC Size */
+build_append_int_noprefix(entry, imsic_size, 4);
+} else {
+build_append_int_noprefix(entry, 0, 8);
+build_append_int_noprefix(entry, 0, 4);
+}
 }
 
 static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
@@ -88,7 +122,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
aml_int(arch_ids->cpus[i].arch_id)));
 
 /* build _MAT object */
-riscv_acpi_madt_add_rintc(i, arch_ids, madt_buf);
+riscv_acpi_madt_add_rintc(i, arch_ids, madt_buf, s);
 aml_append(dev, aml_name_decl("_MAT",
   aml_buffer(madt_buf->len,
   (uint8_t *)madt_buf->data)));
@@ -227,6 +261,7 @@ static void build_dsdt(GArray *table_data,
  * 5.2.12 Multiple APIC Description Table (MADT)
  * REF: https://github.com/riscv-non-isa/riscv-acpi/issues/15
  *  https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
+ *  https://drive.google.com/file/d/1oMGPyOD58JaPgMl1pKasT-VKsIKia7zR/view
  */
 static void build_madt(GArray *table_data,
BIOSLinker *linker,
@@ -246,7 +281,7 @@ static void build_madt(GArray *table_data,
 
 /* RISC-V Local INTC structures per HART */
 for (int i = 0; i < arch_ids->len; i++) {
-riscv_acpi_madt_add_rintc(i, arch_ids, table_data);
+riscv_acpi_madt_add_rintc(i, arch_ids, table_data, s);
 }
 
 acpi_table_end(linker, &table);
-- 
2.43.0




[PULL 09/65] target/riscv/kvm: change timer regs size to u64

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

KVM_REG_RISCV_TIMER regs are always u64 according to the KVM API, but at
this moment we'll return u32 regs if we're running a RISCV32 target.

Use the kvm_riscv_reg_id_u64() helper in RISCV_TIMER_REG() to fix it.

Reported-by: Andrew Jones 
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Message-ID: <20231208183835.2411523-4-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 9370c72f9b..b7871b2f8f 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -88,7 +88,7 @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t 
idx)
 #define RISCV_CSR_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
  KVM_REG_RISCV_CSR_REG(name))
 
-#define RISCV_TIMER_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_TIMER, 
\
+#define RISCV_TIMER_REG(name)  kvm_riscv_reg_id_u64(KVM_REG_RISCV_TIMER, \
  KVM_REG_RISCV_TIMER_REG(name))
 
 #define RISCV_FP_F_REG(idx)  kvm_riscv_reg_id_u32(KVM_REG_RISCV_FP_F, idx)
@@ -111,17 +111,17 @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, 
uint64_t idx)
 } \
 } while (0)
 
-#define KVM_RISCV_GET_TIMER(cs, env, name, reg) \
+#define KVM_RISCV_GET_TIMER(cs, name, reg) \
 do { \
-int ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, name), ®); \
+int ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(name), ®); \
 if (ret) { \
 abort(); \
 } \
 } while (0)
 
-#define KVM_RISCV_SET_TIMER(cs, env, name, reg) \
+#define KVM_RISCV_SET_TIMER(cs, name, reg) \
 do { \
-int ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, name), ®); \
+int ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(name), ®); \
 if (ret) { \
 abort(); \
 } \
@@ -649,10 +649,10 @@ static void kvm_riscv_get_regs_timer(CPUState *cs)
 return;
 }
 
-KVM_RISCV_GET_TIMER(cs, env, time, env->kvm_timer_time);
-KVM_RISCV_GET_TIMER(cs, env, compare, env->kvm_timer_compare);
-KVM_RISCV_GET_TIMER(cs, env, state, env->kvm_timer_state);
-KVM_RISCV_GET_TIMER(cs, env, frequency, env->kvm_timer_frequency);
+KVM_RISCV_GET_TIMER(cs, time, env->kvm_timer_time);
+KVM_RISCV_GET_TIMER(cs, compare, env->kvm_timer_compare);
+KVM_RISCV_GET_TIMER(cs, state, env->kvm_timer_state);
+KVM_RISCV_GET_TIMER(cs, frequency, env->kvm_timer_frequency);
 
 env->kvm_timer_dirty = true;
 }
@@ -666,8 +666,8 @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
 return;
 }
 
-KVM_RISCV_SET_TIMER(cs, env, time, env->kvm_timer_time);
-KVM_RISCV_SET_TIMER(cs, env, compare, env->kvm_timer_compare);
+KVM_RISCV_SET_TIMER(cs, time, env->kvm_timer_time);
+KVM_RISCV_SET_TIMER(cs, compare, env->kvm_timer_compare);
 
 /*
  * To set register of RISCV_TIMER_REG(state) will occur a error from KVM
@@ -676,7 +676,7 @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
  * TODO If KVM changes, adapt here.
  */
 if (env->kvm_timer_state) {
-KVM_RISCV_SET_TIMER(cs, env, state, env->kvm_timer_state);
+KVM_RISCV_SET_TIMER(cs, state, env->kvm_timer_state);
 }
 
 /*
@@ -685,7 +685,7 @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
  * during the migration.
  */
 if (migration_is_running(migrate_get_current()->state)) {
-KVM_RISCV_GET_TIMER(cs, env, frequency, reg);
+KVM_RISCV_GET_TIMER(cs, frequency, reg);
 if (reg != env->kvm_timer_frequency) {
 error_report("Dst Hosts timer frequency != Src Hosts");
 }
-- 
2.43.0




[PULL 10/65] target/riscv/kvm: add RISCV_CONFIG_REG()

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Create a RISCV_CONFIG_REG() macro, similar to what other regs use, to
hide away some of the boilerplate.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Message-ID: <20231208183835.2411523-5-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index b7871b2f8f..15573402be 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -88,6 +88,10 @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t 
idx)
 #define RISCV_CSR_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
  KVM_REG_RISCV_CSR_REG(name))
 
+#define RISCV_CONFIG_REG(env, name) \
+kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, \
+ KVM_REG_RISCV_CONFIG_REG(name))
+
 #define RISCV_TIMER_REG(name)  kvm_riscv_reg_id_u64(KVM_REG_RISCV_TIMER, \
  KVM_REG_RISCV_TIMER_REG(name))
 
@@ -756,24 +760,21 @@ static void kvm_riscv_init_machine_ids(RISCVCPU *cpu, 
KVMScratchCPU *kvmcpu)
 struct kvm_one_reg reg;
 int ret;
 
-reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
-  KVM_REG_RISCV_CONFIG_REG(mvendorid));
+reg.id = RISCV_CONFIG_REG(env, mvendorid);
 reg.addr = (uint64_t)&cpu->cfg.mvendorid;
 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
 if (ret != 0) {
 error_report("Unable to retrieve mvendorid from host, error %d", ret);
 }
 
-reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
-  KVM_REG_RISCV_CONFIG_REG(marchid));
+reg.id = RISCV_CONFIG_REG(env, marchid);
 reg.addr = (uint64_t)&cpu->cfg.marchid;
 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
 if (ret != 0) {
 error_report("Unable to retrieve marchid from host, error %d", ret);
 }
 
-reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
-  KVM_REG_RISCV_CONFIG_REG(mimpid));
+reg.id = RISCV_CONFIG_REG(env, mimpid);
 reg.addr = (uint64_t)&cpu->cfg.mimpid;
 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
 if (ret != 0) {
@@ -788,8 +789,7 @@ static void kvm_riscv_init_misa_ext_mask(RISCVCPU *cpu,
 struct kvm_one_reg reg;
 int ret;
 
-reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
-  KVM_REG_RISCV_CONFIG_REG(isa));
+reg.id = RISCV_CONFIG_REG(env, isa);
 reg.addr = (uint64_t)&env->misa_ext_mask;
 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
 
@@ -1092,8 +1092,7 @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, 
CPUState *cs)
 uint64_t id;
 int ret;
 
-id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
-  KVM_REG_RISCV_CONFIG_REG(mvendorid));
+id = RISCV_CONFIG_REG(env, mvendorid);
 /*
  * cfg.mvendorid is an uint32 but a target_ulong will
  * be written. Assign it to a target_ulong var to avoid
@@ -1105,15 +1104,13 @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, 
CPUState *cs)
 return ret;
 }
 
-id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
-  KVM_REG_RISCV_CONFIG_REG(marchid));
+id = RISCV_CONFIG_REG(env, marchid);
 ret = kvm_set_one_reg(cs, id, &cpu->cfg.marchid);
 if (ret != 0) {
 return ret;
 }
 
-id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
-  KVM_REG_RISCV_CONFIG_REG(mimpid));
+id = RISCV_CONFIG_REG(env, mimpid);
 ret = kvm_set_one_reg(cs, id, &cpu->cfg.mimpid);
 
 return ret;
-- 
2.43.0




[PULL 03/65] target/riscv: Fix th.dcache.cval1 priviledge check

2024-01-10 Thread Alistair Francis
From: LIU Zhiwei 

According to the specification, the th.dcache.cvall1 can be executed
under all priviledges.
The specification about xtheadcmo located in,
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadcmo/dcache_cval1.adoc

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Reviewed-by: Christoph Muellner 
Message-ID: <20231208094315.177-1-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_xthead.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_xthead.c.inc 
b/target/riscv/insn_trans/trans_xthead.c.inc
index 810d76665a..dbb6411239 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -296,7 +296,7 @@ NOP_PRIVCHECK(th_dcache_csw, REQUIRE_XTHEADCMO, 
REQUIRE_PRIV_MS)
 NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
 NOP_PRIVCHECK(th_dcache_isw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
 NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
-NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
+NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
 
 NOP_PRIVCHECK(th_icache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
 NOP_PRIVCHECK(th_icache_ialls, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
-- 
2.43.0




[PULL 41/65] target/riscv/tcg: handle profile MISA bits

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

The profile support is handling multi-letter extensions only. Let's add
support for MISA bits as well.

We'll go through every known MISA bit. If the profile doesn't declare
the bit as mandatory, ignore it. Otherwise, set the bit in env->misa_ext
and env->misa_ext_mask.

Now that we're setting profile MISA bits, one can use the rv64i CPU to boot
Linux using the following options:

-cpu rv64i,rva22u64=true,rv39=true,s=true,zifencei=true

In the near future, when rva22s64 (where, 's', 'zifencei' and sv39 are
mandatory), is implemented, rv64i will be able to boot Linux loading
rva22s64 and no additional flags.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-14-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index dd8f49b2a6..9fba3e8143 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -946,6 +946,27 @@ static void cpu_set_profile(Object *obj, Visitor *v, const 
char *name,
 profile->user_set = true;
 profile->enabled = value;
 
+for (i = 0; misa_bits[i] != 0; i++) {
+uint32_t bit = misa_bits[i];
+
+if  (!(profile->misa_ext & bit)) {
+continue;
+}
+
+if (bit == RVI && !profile->enabled) {
+/*
+ * Disabling profiles will not disable the base
+ * ISA RV64I.
+ */
+continue;
+}
+
+g_hash_table_insert(misa_ext_user_opts,
+GUINT_TO_POINTER(bit),
+(gpointer)value);
+riscv_cpu_write_misa_bit(cpu, bit, profile->enabled);
+}
+
 for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
 ext_offset = profile->ext_offsets[i];
 
-- 
2.43.0




[PULL 49/65] target/riscv/cpu.c: finalize satp_mode earlier

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Profiles will need to validate satp_mode during their own finalize
methods. This will occur inside riscv_tcg_cpu_finalize_features() for
TCG. Given that satp_mode does not have any pre-req from the accelerator
finalize() method, it's safe to finalize it earlier.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-22-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 563fd4f722..65f69a7dd3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1054,6 +1054,14 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 {
 Error *local_err = NULL;
 
+#ifndef CONFIG_USER_ONLY
+riscv_cpu_satp_mode_finalize(cpu, &local_err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+#endif
+
 /*
  * KVM accel does not have a specialized finalize()
  * callback because its extensions are validated
@@ -1066,14 +1074,6 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 return;
 }
 }
-
-#ifndef CONFIG_USER_ONLY
-riscv_cpu_satp_mode_finalize(cpu, &local_err);
-if (local_err != NULL) {
-error_propagate(errp, local_err);
-return;
-}
-#endif
 }
 
 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
-- 
2.43.0




[PULL 01/65] target/riscv: Add vill check for whole vector register move instructions

2024-01-10 Thread Alistair Francis
From: Max Chou 

The ratified version of RISC-V V spec section 16.6 says that
`The instructions operate as if EEW=SEW`.

So the whole vector register move instructions depend on the vtype
register that means the whole vector register move instructions should
raise an illegal-instruction exception when vtype.vill=1.

Signed-off-by: Max Chou 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20231129170400.21251-2-max.c...@sifive.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 78bd363310..114ad87397 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3631,13 +3631,14 @@ static bool trans_vcompress_vm(DisasContext *s, arg_r 
*a)
 }
 
 /*
- * Whole Vector Register Move Instructions ignore vtype and vl setting.
- * Thus, we don't need to check vill bit. (Section 16.6)
+ * Whole Vector Register Move Instructions depend on vtype register(vsew).
+ * Thus, we need to check vill bit. (Section 16.6)
  */
 #define GEN_VMV_WHOLE_TRANS(NAME, LEN) \
 static bool trans_##NAME(DisasContext *s, arg_##NAME * a)   \
 {   \
 if (require_rvv(s) &&   \
+vext_check_isa_ill(s) &&\
 QEMU_IS_ALIGNED(a->rd, LEN) &&  \
 QEMU_IS_ALIGNED(a->rs2, LEN)) { \
 uint32_t maxsz = (s->cfg_ptr->vlen >> 3) * LEN; \
-- 
2.43.0




[PULL 05/65] target/riscv/pmp: Use hwaddr instead of target_ulong for RV32

2024-01-10 Thread Alistair Francis
From: Ivan Klokov 

The Sv32 page-based virtual-memory scheme described in RISCV privileged
spec Section 5.3 supports 34-bit physical addresses for RV32, so the
PMP scheme must support addresses wider than XLEN for RV32. However,
PMP address register format is still 32 bit wide.

Signed-off-by: Ivan Klokov 
Reviewed-by: Alistair Francis 
Message-ID: <20231123091214.20312-1-ivan.klo...@syntacore.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.h |  8 
 target/riscv/pmp.c | 26 --
 2 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index 9af8614cd4..f5c10ce85c 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -53,8 +53,8 @@ typedef struct {
 } pmp_entry_t;
 
 typedef struct {
-target_ulong sa;
-target_ulong ea;
+hwaddr sa;
+hwaddr ea;
 } pmp_addr_t;
 
 typedef struct {
@@ -73,11 +73,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
 void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val);
 target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+bool pmp_hart_has_privs(CPURISCVState *env, hwaddr addr,
 target_ulong size, pmp_priv_t privs,
 pmp_priv_t *allowed_privs,
 target_ulong mode);
-target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr);
+target_ulong pmp_get_tlb_size(CPURISCVState *env, hwaddr addr);
 void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
 void pmp_update_rule_nums(CPURISCVState *env);
 uint32_t pmp_get_num_rules(CPURISCVState *env);
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 162e88a90a..dff9512c3f 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -150,8 +150,7 @@ void pmp_unlock_entries(CPURISCVState *env)
 }
 }
 
-static void pmp_decode_napot(target_ulong a, target_ulong *sa,
- target_ulong *ea)
+static void pmp_decode_napot(hwaddr a, hwaddr *sa, hwaddr *ea)
 {
 /*
  * ...aaa0   8-byte NAPOT range
@@ -173,8 +172,8 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t 
pmp_index)
 uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
 target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
 target_ulong prev_addr = 0u;
-target_ulong sa = 0u;
-target_ulong ea = 0u;
+hwaddr sa = 0u;
+hwaddr ea = 0u;
 
 if (pmp_index >= 1u) {
 prev_addr = env->pmp_state.pmp[pmp_index - 1].addr_reg;
@@ -227,8 +226,7 @@ void pmp_update_rule_nums(CPURISCVState *env)
 }
 }
 
-static int pmp_is_in_range(CPURISCVState *env, int pmp_index,
-   target_ulong addr)
+static int pmp_is_in_range(CPURISCVState *env, int pmp_index, hwaddr addr)
 {
 int result = 0;
 
@@ -305,14 +303,14 @@ static bool pmp_hart_has_privs_default(CPURISCVState 
*env, pmp_priv_t privs,
  * Return true if a pmp rule match or default match
  * Return false if no match
  */
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+bool pmp_hart_has_privs(CPURISCVState *env, hwaddr addr,
 target_ulong size, pmp_priv_t privs,
 pmp_priv_t *allowed_privs, target_ulong mode)
 {
 int i = 0;
 int pmp_size = 0;
-target_ulong s = 0;
-target_ulong e = 0;
+hwaddr s = 0;
+hwaddr e = 0;
 
 /* Short cut if no rules */
 if (0 == pmp_get_num_rules(env)) {
@@ -624,12 +622,12 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
  * To avoid this we return a size of 1 (which means no caching) if the PMP
  * region only covers partial of the TLB page.
  */
-target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr)
+target_ulong pmp_get_tlb_size(CPURISCVState *env, hwaddr addr)
 {
-target_ulong pmp_sa;
-target_ulong pmp_ea;
-target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
-target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
+hwaddr pmp_sa;
+hwaddr pmp_ea;
+hwaddr tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
+hwaddr tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
 int i;
 
 /*
-- 
2.43.0




[PULL 51/65] target/riscv: add satp_mode profile support

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

'satp_mode' is a requirement for supervisor profiles like RVA22S64.
User-mode/application profiles like RVA22U64 doesn't care.

Add 'satp_mode' to the profile description. If a profile requires it,
set it during cpu_set_profile(). We'll also check it during finalize()
to validate if the running config implements the profile.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Acked-by: Alistair Francis 
Message-ID: <20231218125334.37184-24-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 +
 target/riscv/cpu.c |  1 +
 target/riscv/tcg/tcg-cpu.c | 40 ++
 3 files changed, 42 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index a0f768e77d..136030434e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -82,6 +82,7 @@ typedef struct riscv_cpu_profile {
 bool enabled;
 bool user_set;
 int priv_spec;
+int satp_mode;
 const int32_t ext_offsets[];
 } RISCVCPUProfile;
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4d1fd7fd48..1aeb0fee1b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1542,6 +1542,7 @@ static RISCVCPUProfile RVA22U64 = {
 .name = "rva22u64",
 .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU,
 .priv_spec = RISCV_PROFILE_ATTR_UNUSED,
+.satp_mode = RISCV_PROFILE_ATTR_UNUSED,
 .ext_offsets = {
 CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
 CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 41eef87e6e..a0a3350e3e 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -771,6 +771,31 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 riscv_cpu_disable_priv_spec_isa_exts(cpu);
 }
 
+#ifndef CONFIG_USER_ONLY
+static bool riscv_cpu_validate_profile_satp(RISCVCPU *cpu,
+RISCVCPUProfile *profile,
+bool send_warn)
+{
+int satp_max = satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
+
+if (profile->satp_mode > satp_max) {
+if (send_warn) {
+bool is_32bit = riscv_cpu_is_32bit(cpu);
+const char *req_satp = satp_mode_str(profile->satp_mode, is_32bit);
+const char *cur_satp = satp_mode_str(satp_max, is_32bit);
+
+warn_report("Profile %s requires satp mode %s, "
+"but satp mode %s was set", profile->name,
+req_satp, cur_satp);
+}
+
+return false;
+}
+
+return true;
+}
+#endif
+
 static void riscv_cpu_validate_profile(RISCVCPU *cpu,
RISCVCPUProfile *profile)
 {
@@ -780,6 +805,13 @@ static void riscv_cpu_validate_profile(RISCVCPU *cpu,
 bool profile_impl = true;
 int i;
 
+#ifndef CONFIG_USER_ONLY
+if (profile->satp_mode != RISCV_PROFILE_ATTR_UNUSED) {
+profile_impl = riscv_cpu_validate_profile_satp(cpu, profile,
+   send_warn);
+}
+#endif
+
 if (profile->priv_spec != RISCV_PROFILE_ATTR_UNUSED &&
 profile->priv_spec != env->priv_ver) {
 profile_impl = false;
@@ -1084,6 +1116,14 @@ static void cpu_set_profile(Object *obj, Visitor *v, 
const char *name,
 cpu->env.priv_ver = profile->priv_spec;
 }
 
+#ifndef CONFIG_USER_ONLY
+if (profile->satp_mode != RISCV_PROFILE_ATTR_UNUSED) {
+const char *satp_prop = satp_mode_str(profile->satp_mode,
+  riscv_cpu_is_32bit(cpu));
+object_property_set_bool(obj, satp_prop, profile->enabled, NULL);
+}
+#endif
+
 for (i = 0; misa_bits[i] != 0; i++) {
 uint32_t bit = misa_bits[i];
 
-- 
2.43.0




[PULL 36/65] target/riscv: add rva22u64 profile definition

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

The rva22U64 profile, described in:

https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc#rva22-profiles

Contains a set of CPU extensions aimed for 64-bit userspace
applications. Enabling this set to be enabled via a single user flag
makes it convenient to enable a predictable set of features for the CPU,
giving users more predicability when running/testing their workloads.

QEMU implements all possible extensions of this profile. All the so
called 'synthetic extensions' described in the profile that are cache
related are ignored/assumed enabled (Za64rs, Zic64b, Ziccif, Ziccrse,
Ziccamoa, Zicclsm) since we do not implement a cache model.

An abstraction called RISCVCPUProfile is created to store the profile.
'ext_offsets' contains mandatory extensions that QEMU supports. Same
thing with the 'misa_ext' mask. Optional extensions must be enabled
manually in the command line if desired.

The design here is to use the common target/riscv/cpu.c file to store
the profile declaration and export it to the accelerator files. Each
accelerator is then responsible to expose it (or not) to users and how
to enable the extensions.

Next patches will implement the profile for TCG and KVM.

Signed-off-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Reviewed-by: Andrew Jones 
Message-ID: <20231218125334.37184-9-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 12 
 target/riscv/cpu.c | 32 
 2 files changed, 44 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index bfa42a0393..5af1666dc0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -76,6 +76,18 @@ const char *riscv_get_misa_ext_description(uint32_t bit);
 
 #define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop)
 
+typedef struct riscv_cpu_profile {
+const char *name;
+uint32_t misa_ext;
+bool enabled;
+bool user_set;
+const int32_t ext_offsets[];
+} RISCVCPUProfile;
+
+#define RISCV_PROFILE_EXT_LIST_END -1
+
+extern RISCVCPUProfile *riscv_profiles[];
+
 /* Privileged specification version */
 enum {
 PRIV_VERSION_1_10_0 = 0,
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 29fdd64298..199b581380 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1523,6 +1523,38 @@ Property riscv_cpu_options[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+/*
+ * RVA22U64 defines some 'named features' or 'synthetic extensions'
+ * that are cache related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa
+ * and Zicclsm. We do not implement caching in QEMU so we'll consider
+ * all these named features as always enabled.
+ *
+ * There's no riscv,isa update for them (nor for zic64b, despite it
+ * having a cfg offset) at this moment.
+ */
+static RISCVCPUProfile RVA22U64 = {
+.name = "rva22u64",
+.misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU,
+.ext_offsets = {
+CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
+CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
+CPU_CFG_OFFSET(ext_zbs), CPU_CFG_OFFSET(ext_zfhmin),
+CPU_CFG_OFFSET(ext_zkt), CPU_CFG_OFFSET(ext_zicntr),
+CPU_CFG_OFFSET(ext_zihpm), CPU_CFG_OFFSET(ext_zicbom),
+CPU_CFG_OFFSET(ext_zicbop), CPU_CFG_OFFSET(ext_zicboz),
+
+/* mandatory named features for this profile */
+CPU_CFG_OFFSET(zic64b),
+
+RISCV_PROFILE_EXT_LIST_END
+}
+};
+
+RISCVCPUProfile *riscv_profiles[] = {
+&RVA22U64,
+NULL,
+};
+
 static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
 
-- 
2.43.0




[PULL 31/65] target/riscv/tcg: update priv_ver on user_set extensions

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

We'll add a new bare CPU type that won't have any default priv_ver. This
means that the CPU will default to priv_ver = 0, i.e. 1.10.0.

At the same we'll allow these CPUs to enable extensions at will, but
then, if the extension has a priv_ver newer than 1.10, we'll end up
disabling it. Users will then need to manually set priv_ver to something
other than 1.10 to enable the extensions they want, which is not ideal.

Change the setter() of extensions to allow user enabled extensions to
bump the priv_ver of the CPU. This will make it convenient for users to
enable extensions for CPUs that doesn't set a default priv_ver.

This change does not affect any existing CPU: vendor CPUs does not allow
extensions to be enabled, and generic CPUs are already set to priv_ver
LATEST.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-4-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 7174abb7f5..e9f980805e 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -114,6 +114,26 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
 g_assert_not_reached();
 }
 
+static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env,
+uint32_t ext_offset)
+{
+int ext_priv_ver;
+
+if (env->priv_ver == PRIV_VERSION_LATEST) {
+return;
+}
+
+ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset);
+
+if (env->priv_ver < ext_priv_ver) {
+/*
+ * Note: the 'priv_spec' command line option, if present,
+ * will take precedence over this priv_ver bump.
+ */
+env->priv_ver = ext_priv_ver;
+}
+}
+
 static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset,
 bool value)
 {
@@ -762,6 +782,14 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
+if (misa_bit == RVH && env->priv_ver < PRIV_VERSION_1_12_0) {
+/*
+ * Note: the 'priv_spec' command line option, if present,
+ * will take precedence over this priv_ver bump.
+ */
+env->priv_ver = PRIV_VERSION_1_12_0;
+}
+
 env->misa_ext |= misa_bit;
 env->misa_ext_mask |= misa_bit;
 } else {
@@ -891,6 +919,10 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
+if (value) {
+cpu_bump_multi_ext_priv_ver(&cpu->env, multi_ext_cfg->offset);
+}
+
 isa_ext_update_enabled(cpu, multi_ext_cfg->offset, value);
 }
 
-- 
2.43.0




[PULL 33/65] target/riscv: add zicbop extension flag

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

QEMU already implements zicbom (Cache Block Management Operations) and
zicboz (Cache Block Zero Operations). Commit 59cb29d6a5 ("target/riscv:
add Zicbop cbo.prefetch{i, r, m} placeholder") added placeholders for
what would be the instructions for zicbop (Cache Block Prefetch
Operations), which are now no-ops.

The RVA22U64 profile mandates zicbop, which means that applications that
run with this profile might expect zicbop to be present in the riscv,isa
DT and might behave badly if it's absent.

Adding zicbop as an extension will make our future RVA22U64
implementation more in line with what userspace expects and, if/when
cache block prefetch operations became relevant to QEMU, we already have
the extension flag to turn then on/off as needed.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-6-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_cfg.h | 2 ++
 hw/riscv/virt.c| 5 +
 target/riscv/cpu.c | 3 +++
 3 files changed, 10 insertions(+)

diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index d516de4a44..2da8ac9582 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -65,6 +65,7 @@ struct RISCVCPUConfig {
 bool ext_zicntr;
 bool ext_zicsr;
 bool ext_zicbom;
+bool ext_zicbop;
 bool ext_zicboz;
 bool ext_zicond;
 bool ext_zihintntl;
@@ -143,6 +144,7 @@ struct RISCVCPUConfig {
 uint16_t vlen;
 uint16_t elen;
 uint16_t cbom_blocksize;
+uint16_t cbop_blocksize;
 uint16_t cboz_blocksize;
 bool mmu;
 bool pmp;
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4194ddcef1..f9fd1341fc 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -250,6 +250,11 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int 
socket,
   cpu_ptr->cfg.cboz_blocksize);
 }
 
+if (cpu_ptr->cfg.ext_zicbop) {
+qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cbop-block-size",
+  cpu_ptr->cfg.cbop_blocksize);
+}
+
 qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");
 qemu_fdt_setprop_string(ms->fdt, cpu_name, "status", "okay");
 qemu_fdt_setprop_cell(ms->fdt, cpu_name, "reg",
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 33d25d12a6..ce0a3ded04 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -78,6 +78,7 @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, 
RVV,
  */
 const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom),
+ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop),
 ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz),
 ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
 ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr),
@@ -1375,6 +1376,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
 MULTI_EXT_CFG_BOOL("zhinxmin", ext_zhinxmin, false),
 
 MULTI_EXT_CFG_BOOL("zicbom", ext_zicbom, true),
+MULTI_EXT_CFG_BOOL("zicbop", ext_zicbop, true),
 MULTI_EXT_CFG_BOOL("zicboz", ext_zicboz, true),
 
 MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false),
@@ -1509,6 +1511,7 @@ Property riscv_cpu_options[] = {
 DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
 
 DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
+DEFINE_PROP_UINT16("cbop_blocksize", RISCVCPU, cfg.cbop_blocksize, 64),
 DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
 
 DEFINE_PROP_END_OF_LIST(),
-- 
2.43.0




[PULL 35/65] riscv-qmp-cmds.c: expose named features in cpu_model_expansion

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Named features (zic64b the sole example at this moment) aren't expose to
users, thus we need another way to expose them.

Go through each named feature, get its boolean value, do the needed
conversions (bool to qbool, qbool to QObject) and add it to output dict.

Another adjustment is needed: named features are evaluated during
finalize(), so riscv_cpu_finalize_features() needs to be mandatory
regardless of whether we have an input dict or not. Otherwise zic64b
will always return 'false', which is incorrect: the default values of
cache blocksizes ([cbom/cbop/cboz]_blocksize) are set to 64, satisfying
the conditions for zic64b.

Here's an API usage example after this patch:

 $ ./build/qemu-system-riscv64 -S -M virt -display none
-qmp tcp:localhost:1234,server,wait=off

 $ ./scripts/qmp/qmp-shell localhost:1234
Welcome to the QMP low-level shell!
Connected to QEMU 8.1.50

(QEMU) query-cpu-model-expansion type=full model={"name":"rv64"}
{"return": {"model":
{"name": "rv64", "props": {... "zic64b": true, ...

zic64b is set to 'true', as expected, since all cache sizes are 64
bytes by default.

If we change one of the cache blocksizes, zic64b is returned as 'false':

(QEMU) query-cpu-model-expansion type=full 
model={"name":"rv64","props":{"cbom_blocksize":128}}
{"return": {"model":
{"name": "rv64", "props": {... "zic64b": false, ...

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-8-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/riscv-qmp-cmds.c | 30 +-
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index c5551d2cfe..35f2b21163 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -26,6 +26,7 @@
 
 #include "qapi/error.h"
 #include "qapi/qapi-commands-machine-target.h"
+#include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qobject-input-visitor.h"
@@ -98,6 +99,22 @@ static void riscv_obj_add_multiext_props(Object *obj, QDict 
*qdict_out,
 }
 }
 
+static void riscv_obj_add_named_feats_qdict(Object *obj, QDict *qdict_out)
+{
+const RISCVCPUMultiExtConfig *named_cfg;
+RISCVCPU *cpu = RISCV_CPU(obj);
+QObject *value;
+bool flag_val;
+
+for (int i = 0; riscv_cpu_named_features[i].name != NULL; i++) {
+named_cfg = &riscv_cpu_named_features[i];
+flag_val = isa_ext_is_enabled(cpu, named_cfg->offset);
+value = QOBJECT(qbool_from_bool(flag_val));
+
+qdict_put_obj(qdict_out, named_cfg->name, value);
+}
+}
+
 static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props,
const QDict *qdict_in,
Error **errp)
@@ -128,11 +145,6 @@ static void riscv_cpuobj_validate_qdict_in(Object *obj, 
QObject *props,
 goto err;
 }
 
-riscv_cpu_finalize_features(RISCV_CPU(obj), &local_err);
-if (local_err) {
-goto err;
-}
-
 visit_end_struct(visitor, NULL);
 
 err:
@@ -190,6 +202,13 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 }
 }
 
+riscv_cpu_finalize_features(RISCV_CPU(obj), &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+object_unref(obj);
+return NULL;
+}
+
 expansion_info = g_new0(CpuModelExpansionInfo, 1);
 expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
 expansion_info->model->name = g_strdup(model->name);
@@ -199,6 +218,7 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_extensions);
 riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_experimental_exts);
 riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_vendor_exts);
+riscv_obj_add_named_feats_qdict(obj, qdict_out);
 
 /* Add our CPU boolean options too */
 riscv_obj_add_qdict_prop(obj, qdict_out, "mmu");
-- 
2.43.0




[PULL 52/65] target/riscv: add 'parent' in profile description

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Certain S-mode profiles, like RVA22S64 and RVA23S64, mandate all the
mandatory extensions of their respective U-mode profiles. RVA22S64
includes all mandatory extensions of RVA22U64, and the same happens with
RVA23 profiles.

Add a 'parent' field to allow profiles to enable other profiles. This
will allow us to describe S-mode profiles by specifying their parent
U-mode profile, then adding just the S-mode specific extensions.

We're naming the field 'parent' to consider the possibility of other
uses (e.g. a s-mode profile including a previous s-mode profile) in the
future.

Suggested-by: Andrew Jones 
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-25-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 +
 target/riscv/cpu.c |  1 +
 target/riscv/tcg/tcg-cpu.c | 14 +-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 136030434e..5f3955c38d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -77,6 +77,7 @@ const char *riscv_get_misa_ext_description(uint32_t bit);
 #define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop)
 
 typedef struct riscv_cpu_profile {
+struct riscv_cpu_profile *parent;
 const char *name;
 uint32_t misa_ext;
 bool enabled;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1aeb0fee1b..616b091303 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1539,6 +1539,7 @@ Property riscv_cpu_options[] = {
  * having a cfg offset) at this moment.
  */
 static RISCVCPUProfile RVA22U64 = {
+.parent = NULL,
 .name = "rva22u64",
 .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU,
 .priv_spec = RISCV_PROFILE_ATTR_UNUSED,
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index a0a3350e3e..14133ff665 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -802,7 +802,7 @@ static void riscv_cpu_validate_profile(RISCVCPU *cpu,
 CPURISCVState *env = &cpu->env;
 const char *warn_msg = "Profile %s mandates disabled extension %s";
 bool send_warn = profile->user_set && profile->enabled;
-bool profile_impl = true;
+bool parent_enabled, profile_impl = true;
 int i;
 
 #ifndef CONFIG_USER_ONLY
@@ -855,6 +855,13 @@ static void riscv_cpu_validate_profile(RISCVCPU *cpu,
 }
 
 profile->enabled = profile_impl;
+
+if (profile->parent != NULL) {
+parent_enabled = object_property_get_bool(OBJECT(cpu),
+  profile->parent->name,
+  NULL);
+profile->enabled = profile->enabled && parent_enabled;
+}
 }
 
 static void riscv_cpu_validate_profiles(RISCVCPU *cpu)
@@ -1112,6 +1119,11 @@ static void cpu_set_profile(Object *obj, Visitor *v, 
const char *name,
 profile->user_set = true;
 profile->enabled = value;
 
+if (profile->parent != NULL) {
+object_property_set_bool(obj, profile->parent->name,
+ profile->enabled, NULL);
+}
+
 if (profile->enabled) {
 cpu->env.priv_ver = profile->priv_spec;
 }
-- 
2.43.0




[PULL 65/65] target/riscv: Ensure mideleg is set correctly on reset

2024-01-10 Thread Alistair Francis
From: Alistair Francis 

Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor is
enabled. We currently only set them on accesses to mideleg, but they
aren't correctly set on reset. Let's ensure they are always the correct
value.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1617
Signed-off-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20240108001328.280222-4-alistair.fran...@wdc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b32681f7f3..8cbfc7e781 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -931,6 +931,14 @@ static void riscv_cpu_reset_hold(Object *obj)
 /* mmte is supposed to have pm.current hardwired to 1 */
 env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT);
 
+/*
+ * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor
+ * extension is enabled.
+ */
+if (riscv_has_ext(env, RVH)) {
+env->mideleg |= HS_MODE_INTERRUPTS;
+}
+
 /*
  * Clear mseccfg and unlock all the PMP entries upon reset.
  * This is allowed as per the priv and smepmp specifications
-- 
2.43.0




[PULL 61/65] roms/opensbi: Upgrade from v1.3.1 to v1.4

2024-01-10 Thread Alistair Francis
From: Bin Meng 

Upgrade OpenSBI from v1.3.1 to v1.4 and the pre-built bios images.

The v1.4 release includes the following commits:

1a398d9 lib: sbi: Add Zicntr as a HART ISA extension
669089c lib: sbi: Add Zihpm as a HART ISA extension
72b9c8f lib: sbi: Alphabetically sort HART ISA extensions
5359fc6 lib: sbi: Rename hart_pmu_get_allowed_bits() function
976895c lib: sbi: Fix Priv spec version for [m|s]counteren and mcountinhibit 
CSRs
6053917 lib: sbi: Fix how print gets flags
35ef182 lib: sbi: print not fill '0' when left-aligned
40dac06 lib: sbi: Add '+' flags for print
458fa74 lib: sbi: Add ' ' '\'' flags for print
05cbb6e lib: sbi: implifying the parameters of printi
fe08281 lib: sbi: print add 'o' type
c6ee5ae lib: sbi: Fix printi
3b6fcdd lib: sbi: Simplify prints
cc89fa7 lib: sbi: Fix printc
ff43168 lib: sbi: Fix timing of clearing tbuf
a73982d lib: sbi: Fix missing '\0' when buffer szie equal 1
ea6533a lib: utils/gpio: Fix RV32 compile error for designware GPIO driver
c3b98c6 include: sbi: Add macro definitions for mseccfg CSR
1c099c4 lib: sbi: Add functions to manipulate PMP entries
6c202c5 include: sbi: Add Smepmp specific access flags for PMP entries
cbcfc7b lib: sbi: Add smepmp in hart extensions
d72f5f1 lib: utils: Add detection of Smepmp from ISA string in FDT
4a42a23 lib: sbi: Grant SU R/W/X permissions to whole memory
f3fdd04 lib: sbi: Change the order of PMP initialization
5dd8db5 lib: sbi: Add support for Smepmp
6e44ef6 lib: sbi: Add functions to map/unmap shared memory
0ad8660 lib: sbi: Map/Unmap debug console shared memory buffers
057eb10 lib: utils/gpio: Fix RV32 compile error for designware GPIO driver
0e2111e libfdt: fix SPDX license identifiers
e05a9cf lib: sbi: Update system suspend to spec
5e20d25 include: sbi: fix CSR define of mseccfg
44c5151 include: sbi_utils: Remove driver pointer from struct i2c_adapter
14a35b0 lib: utils/regmap: Add generic regmap access library
8e97275 lib: utils/regmap: Add simple FDT based regmap framework
f21d8f7 lib: utils/regmap: Add simple FDT based syscon regmap driver
4a344a9 lib: utils/reset: Add syscon based reboot and poweroff
c2e6027 lib: utils/reset: Remove SiFive Test reset driver
f536e0b gitignore: allow gitignore to ignore most dot file
c744ed7 lib: sbi_pmu: Enable noncontigous hpm event and counters
6259b2e lib: utils/fdt: Fix fdt_parse_isa_extensions() implementation
f46a564 lib: sbi: Fix typo for finding fixed event counter
94197a8 fw_base.S: Fix assembler error with clang 16+
c104c60 lib: sbi: Add support for smcntrpmf
7aabeee Makefile: Fix grep warning
e7e73aa platform: generic: allwinner: correct mhpmevent count
ee1f83c lib: sbi_pmu: remove mhpm_count field in hart feature
a9cffd6 firmware: payload: test: Change to SBI v2.0 DBCN ecalls
b20bd47 lib: sbi: improve the definition of SBI_IPI_EVENT_MAX
664692f lib: sbi_pmu: ensure update hpm counter before starting counting
c9a296d platform: generic: allwinner: fix OF process for T-HEAD c9xx pmu
901d3d7 lib: sbi_pmu: keep overflow interrupt of stopped hpm counter disabled
cacfba3 platform: Allow platforms to specify the size of tlb fifo
5bd9694 lib: sbi: alloc tlb fifo by sbi_malloc
130e65d lib: sbi: Implement SET_FS_DIRTY() to make sure the mstatus FS dirty is 
set
d1e4dff lib: sbi: Introduce HART index in sbi_scratch
e6125c3 lib: sbi: Remove sbi_platform_hart_index/invalid() functions
296e70d lib: sbi: Extend sbi_hartmask to support both hartid and hartindex
e632cd7 lib: sbi: Use sbi_scratch_last_hartindex() in remote TLB managment
78c667b lib: sbi: Prefer hartindex over hartid in IPI framework
22d6ff8 lib: sbi: Remove sbi_scratch_last_hartid() macro
112daa2 lib: sbi: Maximize the use of HART index in sbi_domain
9560fb3 include: sbi: Remove sbi_hartmask_for_each_hart() macro
b8fb96e include: sbi_domain: Fix permission test macros
bff27c1 lib: sbi: Factor-out Smepmp configuration as separate function
5240d31 lib: sbi: Don't clear mseccfg.MML bit in sbi_hart_smepmp_configure()
2b51a9d lib: sbi: Fix pmp_flags for Smepmp read-only shared region
73aea28 lib: sbi: Populate M-only Smepmp entries before setting mseccfg.MML
e8bc162 lib: utils/serial: Add shared regions for serial drivers
b7e9d34 lib: utils/regmap: Mark syscon region as shared read-write
3669153 platform: generic: thead: fix stale TLB entries for th1520/sg2042
de525ac firmware: Remove ALIGN in .rela.dyn in linker script
2a6d725 firmware: Remove handling of R_RISCV_{32,64}
6ed125a Makefile: Add --exclude-libs ALL to avoid .dynsym
e21901d doc: Fix fw_payload.md
a125423 lib: utils/serial: Ensure proper allocation of PMP entries for uart8250
d36709f lib: utils: timer/ipi: Update memregion flags for PLMT and PLICSW
8197c2f lib: sbi: fix sbi_domain_get_assigned_hartmask()
9da30f6 lib: utils/fdt: simplify dt_parse_isa_extensions
942aca2 lib: utils: Simplify SET_ISA_EXT_MAP()
f831b93 lib: sbi_pmu: check for index overflows
d891cae gpio/starfive: redundant readl() call
e8114c6 docs: platform: update platform_requirements.md
3632f2b lib: 

[PULL 48/65] target/riscv: add priv ver restriction to profiles

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Some profiles, like RVA22S64, has a priv_spec requirement.

Make this requirement explicit for all profiles. We'll validate this
requirement finalize() time and, in case the user chooses an
incompatible priv_spec while activating a profile, a warning will be
shown.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-21-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  2 ++
 target/riscv/cpu.c |  1 +
 target/riscv/tcg/tcg-cpu.c | 31 +++
 3 files changed, 34 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5af1666dc0..3d1c347b71 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -81,10 +81,12 @@ typedef struct riscv_cpu_profile {
 uint32_t misa_ext;
 bool enabled;
 bool user_set;
+int priv_spec;
 const int32_t ext_offsets[];
 } RISCVCPUProfile;
 
 #define RISCV_PROFILE_EXT_LIST_END -1
+#define RISCV_PROFILE_ATTR_UNUSED -1
 
 extern RISCVCPUProfile *riscv_profiles[];
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0ec0d89070..563fd4f722 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1536,6 +1536,7 @@ Property riscv_cpu_options[] = {
 static RISCVCPUProfile RVA22U64 = {
 .name = "rva22u64",
 .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU,
+.priv_spec = RISCV_PROFILE_ATTR_UNUSED,
 .ext_offsets = {
 CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause),
 CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb),
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index e90d929ac1..41eef87e6e 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -74,6 +74,20 @@ static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t 
bit,
 }
 }
 
+static const char *cpu_priv_ver_to_str(int priv_ver)
+{
+switch (priv_ver) {
+case PRIV_VERSION_1_10_0:
+return "v1.10.0";
+case PRIV_VERSION_1_11_0:
+return "v1.11.0";
+case PRIV_VERSION_1_12_0:
+return "v1.12.0";
+}
+
+g_assert_not_reached();
+}
+
 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
   const TranslationBlock *tb)
 {
@@ -760,11 +774,24 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 static void riscv_cpu_validate_profile(RISCVCPU *cpu,
RISCVCPUProfile *profile)
 {
+CPURISCVState *env = &cpu->env;
 const char *warn_msg = "Profile %s mandates disabled extension %s";
 bool send_warn = profile->user_set && profile->enabled;
 bool profile_impl = true;
 int i;
 
+if (profile->priv_spec != RISCV_PROFILE_ATTR_UNUSED &&
+profile->priv_spec != env->priv_ver) {
+profile_impl = false;
+
+if (send_warn) {
+warn_report("Profile %s requires priv spec %s, "
+"but priv ver %s was set", profile->name,
+cpu_priv_ver_to_str(profile->priv_spec),
+cpu_priv_ver_to_str(env->priv_ver));
+}
+}
+
 for (i = 0; misa_bits[i] != 0; i++) {
 uint32_t bit = misa_bits[i];
 
@@ -1053,6 +1080,10 @@ static void cpu_set_profile(Object *obj, Visitor *v, 
const char *name,
 profile->user_set = true;
 profile->enabled = value;
 
+if (profile->enabled) {
+cpu->env.priv_ver = profile->priv_spec;
+}
+
 for (i = 0; misa_bits[i] != 0; i++) {
 uint32_t bit = misa_bits[i];
 
-- 
2.43.0




[PULL 42/65] target/riscv/tcg: add hash table insert helpers

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Previous patches added several g_hash_table_insert() patterns. Add two
helpers, one for each user hash, to make the code cleaner.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-15-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 9fba3e8143..f1eeaa12b9 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -42,6 +42,18 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
  GUINT_TO_POINTER(ext_offset));
 }
 
+static void cpu_cfg_ext_add_user_opt(uint32_t ext_offset, bool value)
+{
+g_hash_table_insert(multi_ext_user_opts, GUINT_TO_POINTER(ext_offset),
+(gpointer)value);
+}
+
+static void cpu_misa_ext_add_user_opt(uint32_t bit, bool value)
+{
+g_hash_table_insert(misa_ext_user_opts, GUINT_TO_POINTER(bit),
+(gpointer)value);
+}
+
 static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit,
  bool enabled)
 {
@@ -822,9 +834,7 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
-g_hash_table_insert(misa_ext_user_opts,
-GUINT_TO_POINTER(misa_bit),
-(gpointer)value);
+cpu_misa_ext_add_user_opt(misa_bit, value);
 
 prev_val = env->misa_ext & misa_bit;
 
@@ -961,9 +971,7 @@ static void cpu_set_profile(Object *obj, Visitor *v, const 
char *name,
 continue;
 }
 
-g_hash_table_insert(misa_ext_user_opts,
-GUINT_TO_POINTER(bit),
-(gpointer)value);
+cpu_misa_ext_add_user_opt(bit, profile->enabled);
 riscv_cpu_write_misa_bit(cpu, bit, profile->enabled);
 }
 
@@ -978,9 +986,7 @@ static void cpu_set_profile(Object *obj, Visitor *v, const 
char *name,
 cpu_bump_multi_ext_priv_ver(&cpu->env, ext_offset);
 }
 
-g_hash_table_insert(multi_ext_user_opts,
-GUINT_TO_POINTER(ext_offset),
-(gpointer)profile->enabled);
+cpu_cfg_ext_add_user_opt(ext_offset, profile->enabled);
 isa_ext_update_enabled(cpu, ext_offset, profile->enabled);
 }
 }
@@ -1043,9 +1049,7 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor 
*v, const char *name,
 multi_ext_cfg->name, lower);
 }
 
-g_hash_table_insert(multi_ext_user_opts,
-GUINT_TO_POINTER(multi_ext_cfg->offset),
-(gpointer)value);
+cpu_cfg_ext_add_user_opt(multi_ext_cfg->offset, value);
 
 prev_val = isa_ext_is_enabled(cpu, multi_ext_cfg->offset);
 
-- 
2.43.0




[PULL 47/65] target/riscv: implement svade

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

'svade' is a RVA22S64 profile requirement, a profile we're going to add
shortly. It is a named feature (i.e. not a formal extension, not defined
in riscv,isa DT at this moment) defined in [1] as:

"Page-fault exceptions are raised when a page is accessed when A bit is
clear, or written when D bit is clear.".

As far as the spec goes, 'svade' is one of the two distinct modes of
handling PTE_A and PTE_D. The other way, i.e. update PTE_A/PTE_D when
they're cleared, is defined by the 'svadu' extension. Checking
cpu_helper.c, get_physical_address(), we can verify that QEMU is
compliant with that: we will update PTE_A/PTE_D if 'svadu' is enabled,
or throw a page-fault exception if 'svadu' isn't enabled.

So, as far as we're concerned, 'svade' translates to 'svadu must be
disabled'.

We'll implement it like 'zic64b': an internal flag that profiles can
enable. The flag will not be exposed to users.

[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-20-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_cfg.h | 1 +
 target/riscv/cpu.c | 1 +
 target/riscv/tcg/tcg-cpu.c | 5 +
 3 files changed, 7 insertions(+)

diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 350ea44e50..780ae6ef17 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -117,6 +117,7 @@ struct RISCVCPUConfig {
 bool ext_smepmp;
 bool rvv_ta_all_1s;
 bool rvv_ma_all_1s;
+bool svade;
 bool zic64b;
 
 uint32_t mvendorid;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index cd3c22e92b..0ec0d89070 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1444,6 +1444,7 @@ const RISCVCPUMultiExtConfig 
riscv_cpu_experimental_exts[] = {
 };
 
 const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
+MULTI_EXT_CFG_BOOL("svade", svade, true),
 MULTI_EXT_CFG_BOOL("zic64b", zic64b, true),
 
 DEFINE_PROP_END_OF_LIST(),
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index f2a9558737..e90d929ac1 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -188,6 +188,9 @@ static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, 
uint32_t feat_offset)
 cpu->cfg.cbop_blocksize = 64;
 cpu->cfg.cboz_blocksize = 64;
 break;
+case CPU_CFG_OFFSET(svade):
+cpu->cfg.ext_svadu = false;
+break;
 default:
 g_assert_not_reached();
 }
@@ -381,6 +384,8 @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu)
 cpu->cfg.zic64b = cpu->cfg.cbom_blocksize == 64 &&
   cpu->cfg.cbop_blocksize == 64 &&
   cpu->cfg.cboz_blocksize == 64;
+
+cpu->cfg.svade = !cpu->cfg.ext_svadu;
 }
 
 static void riscv_cpu_validate_g(RISCVCPU *cpu)
-- 
2.43.0




[PULL 59/65] target/riscv/kvm: add RVV and Vector CSR regs

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Add support for RVV and Vector CSR KVM regs vstart, vl and vtype.

Support for vregs[] requires KVM side changes and an extra reg (vlenb)
and will be added later.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-ID: <20231218204321.75757-5-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 74 ++
 1 file changed, 74 insertions(+)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index d7d6fb1af0..680a729cd8 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -105,6 +105,10 @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, 
uint64_t idx)
 
 #define RISCV_FP_D_REG(idx)  kvm_riscv_reg_id_u64(KVM_REG_RISCV_FP_D, idx)
 
+#define RISCV_VECTOR_CSR_REG(env, name) \
+kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_VECTOR, \
+   KVM_REG_RISCV_VECTOR_CSR_REG(name))
+
 #define KVM_RISCV_GET_CSR(cs, env, csr, reg) \
 do { \
 int _ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, csr), ®); \
@@ -158,6 +162,7 @@ static KVMCPUConfig kvm_misa_ext_cfgs[] = {
 KVM_MISA_CFG(RVH, KVM_RISCV_ISA_EXT_H),
 KVM_MISA_CFG(RVI, KVM_RISCV_ISA_EXT_I),
 KVM_MISA_CFG(RVM, KVM_RISCV_ISA_EXT_M),
+KVM_MISA_CFG(RVV, KVM_RISCV_ISA_EXT_V),
 };
 
 static void kvm_cpu_get_misa_ext_cfg(Object *obj, Visitor *v,
@@ -709,6 +714,65 @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
 env->kvm_timer_dirty = false;
 }
 
+static int kvm_riscv_get_regs_vector(CPUState *cs)
+{
+CPURISCVState *env = &RISCV_CPU(cs)->env;
+target_ulong reg;
+int ret = 0;
+
+if (!riscv_has_ext(env, RVV)) {
+return 0;
+}
+
+ret = kvm_get_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vstart), ®);
+if (ret) {
+return ret;
+}
+env->vstart = reg;
+
+ret = kvm_get_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vl), ®);
+if (ret) {
+return ret;
+}
+env->vl = reg;
+
+ret = kvm_get_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vtype), ®);
+if (ret) {
+return ret;
+}
+env->vtype = reg;
+
+return 0;
+}
+
+static int kvm_riscv_put_regs_vector(CPUState *cs)
+{
+CPURISCVState *env = &RISCV_CPU(cs)->env;
+target_ulong reg;
+int ret = 0;
+
+if (!riscv_has_ext(env, RVV)) {
+return 0;
+}
+
+reg = env->vstart;
+ret = kvm_set_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vstart), ®);
+if (ret) {
+return ret;
+}
+
+reg = env->vl;
+ret = kvm_set_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vl), ®);
+if (ret) {
+return ret;
+}
+
+reg = env->vtype;
+ret = kvm_set_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vtype), ®);
+
+return ret;
+}
+
 typedef struct KVMScratchCPU {
 int kvmfd;
 int vmfd;
@@ -1004,6 +1068,11 @@ int kvm_arch_get_registers(CPUState *cs)
 return ret;
 }
 
+ret = kvm_riscv_get_regs_vector(cs);
+if (ret) {
+return ret;
+}
+
 return ret;
 }
 
@@ -1044,6 +1113,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 return ret;
 }
 
+ret = kvm_riscv_put_regs_vector(cs);
+if (ret) {
+return ret;
+}
+
 if (KVM_PUT_RESET_STATE == level) {
 RISCVCPU *cpu = RISCV_CPU(cs);
 if (cs->cpu_index == 0) {
-- 
2.43.0




[PULL 45/65] riscv-qmp-cmds.c: add profile flags in cpu-model-expansion

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Expose all profile flags for all CPUs when executing
query-cpu-model-expansion. This will allow callers to quickly determine
if a certain profile is implemented by a given CPU. This includes vendor
CPUs - the fact that they don't have profile user flags doesn't mean
that they don't implement the profile.

After this change it's possible to quickly determine if our stock CPUs
implement the existing rva22u64 profile. Here's a few examples:

 $ ./build/qemu-system-riscv64 -S -M virt -display none
-qmp tcp:localhost:1234,server,wait=off

 $ ./scripts/qmp/qmp-shell localhost:1234
Welcome to the QMP low-level shell!
Connected to QEMU 8.1.50

- As expected, the 'max' CPU implements the rva22u64 profile.

(QEMU) query-cpu-model-expansion type=full model={"name":"max"}
{"return": {"model":
{"name": "rv64", "props": {... "rva22u64": true, ...

- rv64 is missing "zba", "zbb", "zbs", "zkt" and "zfhmin":

query-cpu-model-expansion type=full model={"name":"rv64"}
{"return": {"model":
{"name": "rv64", "props": {... "rva22u64": false, ...

query-cpu-model-expansion type=full model={"name":"rv64",
"props":{"zba":true,"zbb":true,"zbs":true,"zkt":true,"zfhmin":true}}
{"return": {"model":
{"name": "rv64", "props": {... "rva22u64": true, ...

We have no vendor CPUs that supports rva22u64 (veyron-v1 is the closest
- it is missing just 'zkt').

In short, aside from the 'max' CPU, we have no CPUs that supports
rva22u64 by default.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-18-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/riscv-qmp-cmds.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index 35f2b21163..c48b9cfa67 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -115,6 +115,19 @@ static void riscv_obj_add_named_feats_qdict(Object *obj, 
QDict *qdict_out)
 }
 }
 
+static void riscv_obj_add_profiles_qdict(Object *obj, QDict *qdict_out)
+{
+RISCVCPUProfile *profile;
+QObject *value;
+
+for (int i = 0; riscv_profiles[i] != NULL; i++) {
+profile = riscv_profiles[i];
+value = QOBJECT(qbool_from_bool(profile->enabled));
+
+qdict_put_obj(qdict_out, profile->name, value);
+}
+}
+
 static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props,
const QDict *qdict_in,
Error **errp)
@@ -219,6 +232,7 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_experimental_exts);
 riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_vendor_exts);
 riscv_obj_add_named_feats_qdict(obj, qdict_out);
+riscv_obj_add_profiles_qdict(obj, qdict_out);
 
 /* Add our CPU boolean options too */
 riscv_obj_add_qdict_prop(obj, qdict_out, "mmu");
-- 
2.43.0




[PULL 56/65] linux-headers: Update to Linux v6.7-rc5

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

We'll add a new RISC-V linux-header file, but first let's update all
headers.

Headers for 'asm-loongarch' were added in this update.

Signed-off-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Message-ID: <20231218204321.75757-2-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 include/standard-headers/drm/drm_fourcc.h |   2 +
 include/standard-headers/linux/pci_regs.h |  24 ++-
 include/standard-headers/linux/vhost_types.h  |   7 +
 .../standard-headers/linux/virtio_config.h|   5 +
 include/standard-headers/linux/virtio_pci.h   |  11 ++
 linux-headers/asm-arm64/kvm.h |  32 
 linux-headers/asm-generic/unistd.h|  14 +-
 linux-headers/asm-loongarch/bitsperlong.h |   1 +
 linux-headers/asm-loongarch/kvm.h | 108 +++
 linux-headers/asm-loongarch/mman.h|   1 +
 linux-headers/asm-loongarch/unistd.h  |   5 +
 linux-headers/asm-mips/unistd_n32.h   |   4 +
 linux-headers/asm-mips/unistd_n64.h   |   4 +
 linux-headers/asm-mips/unistd_o32.h   |   4 +
 linux-headers/asm-powerpc/unistd_32.h |   4 +
 linux-headers/asm-powerpc/unistd_64.h |   4 +
 linux-headers/asm-riscv/kvm.h |  12 ++
 linux-headers/asm-s390/unistd_32.h|   4 +
 linux-headers/asm-s390/unistd_64.h|   4 +
 linux-headers/asm-x86/unistd_32.h |   4 +
 linux-headers/asm-x86/unistd_64.h |   3 +
 linux-headers/asm-x86/unistd_x32.h|   3 +
 linux-headers/linux/iommufd.h | 180 +-
 linux-headers/linux/kvm.h |  11 ++
 linux-headers/linux/psp-sev.h |   1 +
 linux-headers/linux/stddef.h  |   9 +-
 linux-headers/linux/userfaultfd.h |   9 +-
 linux-headers/linux/vfio.h|  47 +++--
 linux-headers/linux/vhost.h   |   8 +
 29 files changed, 498 insertions(+), 27 deletions(-)
 create mode 100644 linux-headers/asm-loongarch/bitsperlong.h
 create mode 100644 linux-headers/asm-loongarch/kvm.h
 create mode 100644 linux-headers/asm-loongarch/mman.h
 create mode 100644 linux-headers/asm-loongarch/unistd.h

diff --git a/include/standard-headers/drm/drm_fourcc.h 
b/include/standard-headers/drm/drm_fourcc.h
index 72279f4d25..3afb70160f 100644
--- a/include/standard-headers/drm/drm_fourcc.h
+++ b/include/standard-headers/drm/drm_fourcc.h
@@ -322,6 +322,8 @@ extern "C" {
  * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
  */
 #define DRM_FORMAT_NV15fourcc_code('N', 'V', '1', '5') /* 2x2 
subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV20fourcc_code('N', 'V', '2', '0') /* 2x1 
subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV30fourcc_code('N', 'V', '3', '0') /* 
non-subsampled Cr:Cb plane */
 
 /*
  * 2 plane YCbCr MSB aligned
diff --git a/include/standard-headers/linux/pci_regs.h 
b/include/standard-headers/linux/pci_regs.h
index e5f558d964..a39193213f 100644
--- a/include/standard-headers/linux/pci_regs.h
+++ b/include/standard-headers/linux/pci_regs.h
@@ -80,6 +80,7 @@
 #define  PCI_HEADER_TYPE_NORMAL0
 #define  PCI_HEADER_TYPE_BRIDGE1
 #define  PCI_HEADER_TYPE_CARDBUS   2
+#define  PCI_HEADER_TYPE_MFD   0x80/* Multi-Function Device 
(possible) */
 
 #define PCI_BIST   0x0f/* 8 bits */
 #define  PCI_BIST_CODE_MASK0x0f/* Return result */
@@ -637,6 +638,7 @@
 #define PCI_EXP_RTCAP  0x1e/* Root Capabilities */
 #define  PCI_EXP_RTCAP_CRSVIS  0x0001  /* CRS Software Visibility capability */
 #define PCI_EXP_RTSTA  0x20/* Root Status */
+#define  PCI_EXP_RTSTA_PME_RQ_ID 0x /* PME Requester ID */
 #define  PCI_EXP_RTSTA_PME 0x0001 /* PME status */
 #define  PCI_EXP_RTSTA_PENDING 0x0002 /* PME pending */
 /*
@@ -930,12 +932,13 @@
 
 /* Process Address Space ID */
 #define PCI_PASID_CAP  0x04/* PASID feature register */
-#define  PCI_PASID_CAP_EXEC0x02/* Exec permissions Supported */
-#define  PCI_PASID_CAP_PRIV0x04/* Privilege Mode Supported */
+#define  PCI_PASID_CAP_EXEC0x0002  /* Exec permissions Supported */
+#define  PCI_PASID_CAP_PRIV0x0004  /* Privilege Mode Supported */
+#define  PCI_PASID_CAP_WIDTH   0x1f00
 #define PCI_PASID_CTRL 0x06/* PASID control register */
-#define  PCI_PASID_CTRL_ENABLE 0x01/* Enable bit */
-#define  PCI_PASID_CTRL_EXEC   0x02/* Exec permissions Enable */
-#define  PCI_PASID_CTRL_PRIV   0x04/* Privilege Mode Enable */
+#define  PCI_PASID_CTRL_ENABLE 0x0001  /* Enable bit */
+#define  PCI_PASID_CTRL_EXEC   0x0002  /* Exec permissions Enable */
+#define  PCI_PASID_CTRL_PRIV   0x0004  /* Privilege Mode Enable */
 #define PCI_EXT_CAP_PASID_SIZEOF   8
 
 /* Single Root I/O Virtualization */
@@ -975,6 +978,8 @@
 #define  PCI_LTR_VALUE_MASK

[PULL 58/65] target/riscv/kvm: do PR_RISCV_V_SET_CONTROL during realize()

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Linux RISC-V vector documentation (Document/arch/riscv/vector.rst)
mandates a prctl() in order to allow an userspace thread to use the
Vector extension from the host.

This is something to be done in realize() time, after init(), when we
already decided whether we're using RVV or not. We don't have a
realize() callback for KVM yet, so add kvm_cpu_realize() and enable RVV
for the thread via PR_RISCV_V_SET_CONTROL.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-ID: <20231218204321.75757-4-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 841756ab9b..d7d6fb1af0 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -18,6 +18,7 @@
 
 #include "qemu/osdep.h"
 #include 
+#include 
 
 #include 
 
@@ -47,6 +48,9 @@
 #include "sysemu/runstate.h"
 #include "hw/riscv/numa.h"
 
+#define PR_RISCV_V_SET_CONTROL69
+#define PR_RISCV_V_VSTATE_CTRL_ON  2
+
 void riscv_kvm_aplic_request(void *opaque, int irq, int level)
 {
 kvm_set_irq(kvm_state, irq, !!level);
@@ -1496,11 +1500,36 @@ static void kvm_cpu_instance_init(CPUState *cs)
 }
 }
 
+/*
+ * We'll get here via the following path:
+ *
+ * riscv_cpu_realize()
+ *   -> cpu_exec_realizefn()
+ *  -> kvm_cpu_realize() (via accel_cpu_common_realize())
+ */
+static bool kvm_cpu_realize(CPUState *cs, Error **errp)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+int ret;
+
+if (riscv_has_ext(&cpu->env, RVV)) {
+ret = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON);
+if (ret) {
+error_setg(errp, "Error in prctl PR_RISCV_V_SET_CONTROL, code: %s",
+   strerrorname_np(errno));
+return false;
+}
+}
+
+   return true;
+}
+
 static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data)
 {
 AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
 
 acc->cpu_instance_init = kvm_cpu_instance_init;
+acc->cpu_target_realize = kvm_cpu_realize;
 }
 
 static const TypeInfo kvm_cpu_accel_type_info = {
-- 
2.43.0




[PULL 32/65] target/riscv: add rv64i CPU

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

We don't have any form of a 'bare bones' CPU. rv64, our default CPUs,
comes with a lot of defaults. This is fine for most regular uses but
it's not suitable when more control of what is actually loaded in the
CPU is required.

A bare-bones CPU would be annoying to deal with if not by profile
support, a way to load a multitude of extensions with a single flag.
Profile support is going to be implemented shortly, so let's add a CPU
for it.

The new 'rv64i' CPU will have only RVI loaded. It is inspired in the
profile specification that dictates, for RVA22U64 [1]:

"RVA22U64 Mandatory Base
 RV64I is the mandatory base ISA for RVA22U64"

And so it seems that RV64I is the mandatory base ISA for all profiles
listed in [1], making it an ideal CPU to use with profile support.

rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features
from pre-existent CPUs:

- it allows extensions to be enabled, like generic CPUs;
- it will not inherit extension defaults, like vendor CPUs.

This is the minimum extension set to boot OpenSBI and buildroot using
rv64i:

./build/qemu-system-riscv64 -nographic -M virt \
-cpu rv64i,sv39=true,g=true,c=true,s=true,u=true

Our minimal riscv,isa in this case will be:

 # cat /proc/device-tree/cpus/cpu@0/riscv,isa
rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd#

[1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-5-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu-qom.h |  2 ++
 target/riscv/cpu.c | 46 ++
 2 files changed, 48 insertions(+)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index ca7dd509e3..4d1aa54311 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -24,6 +24,7 @@
 #define TYPE_RISCV_CPU "riscv-cpu"
 #define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu"
 #define TYPE_RISCV_VENDOR_CPU "riscv-vendor-cpu"
+#define TYPE_RISCV_BARE_CPU "riscv-bare-cpu"
 
 #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
 #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
@@ -33,6 +34,7 @@
 #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
 #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
 #define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("x-rv128")
+#define TYPE_RISCV_CPU_RV64IRISCV_CPU_TYPE_NAME("rv64i")
 #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
 #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
 #define TYPE_RISCV_CPU_SIFIVE_E31   RISCV_CPU_TYPE_NAME("sifive-e31")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index bf0235305e..33d25d12a6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -371,6 +371,17 @@ static void set_satp_mode_max_supported(RISCVCPU *cpu,
 /* Set the satp mode to the max supported */
 static void set_satp_mode_default_map(RISCVCPU *cpu)
 {
+/*
+ * Bare CPUs do not default to the max available.
+ * Users must set a valid satp_mode in the command
+ * line.
+ */
+if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
+warn_report("No satp mode set. Defaulting to 'bare'");
+cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE);
+return;
+}
+
 cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
 }
 #endif
@@ -553,6 +564,28 @@ static void rv128_base_cpu_init(Object *obj)
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
 }
+
+static void rv64i_bare_cpu_init(Object *obj)
+{
+CPURISCVState *env = &RISCV_CPU(obj)->env;
+riscv_cpu_set_misa(env, MXL_RV64, RVI);
+
+/* Remove the defaults from the parent class */
+RISCV_CPU(obj)->cfg.ext_zicntr = false;
+RISCV_CPU(obj)->cfg.ext_zihpm = false;
+
+/* Set to QEMU's first supported priv version */
+env->priv_ver = PRIV_VERSION_1_10_0;
+
+/*
+ * Support all available satp_mode settings. The default
+ * value will be set to MBARE if the user doesn't set
+ * satp_mode manually (see set_satp_mode_default()).
+ */
+#ifndef CONFIG_USER_ONLY
+set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV64);
+#endif
+}
 #else
 static void rv32_base_cpu_init(Object *obj)
 {
@@ -1755,6 +1788,13 @@ char *riscv_isa_string(RISCVCPU *cpu)
 .instance_init = initfn  \
 }
 
+#define DEFINE_BARE_CPU(type_name, initfn) \
+{  \
+.name = type_name, \
+.parent = TYPE_RISCV_BARE_CPU, \
+.instance_init = initfn\
+}
+
 static const TypeInfo riscv_cpu_type_infos[] = {
 {
 .name = TYPE_RISCV_CPU,
@@ -1777,6 +1817,11 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 .parent = TYPE_RISCV_CPU,
 .abstract = true,
 },
+{
+.name = TYPE_RIS

[PULL 64/65] target/riscv: Don't adjust vscause for exceptions

2024-01-10 Thread Alistair Francis
From: Alistair Francis 

We have been incorrectly adjusting both the interrupt and exception
cause when using the hypervisor extension and trapping to VS-mode. This
patch changes the conditional to ensure we only adjust the cause for
interrupts and not exceptions.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1708
Signed-off-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20240108001328.280222-3-alistair.fran...@wdc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 99d1275729..c7cc7eb423 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1749,8 +1749,8 @@ void riscv_cpu_do_interrupt(CPUState *cs)
  * See if we need to adjust cause. Yes if its VS mode interrupt
  * no if hypervisor has delegated one of hs mode's interrupt
  */
-if (cause == IRQ_VS_TIMER || cause == IRQ_VS_SOFT ||
-cause == IRQ_VS_EXT) {
+if (async && (cause == IRQ_VS_TIMER || cause == IRQ_VS_SOFT ||
+  cause == IRQ_VS_EXT)) {
 cause = cause - 1;
 }
 write_gva = false;
-- 
2.43.0




[PULL 29/65] target/riscv: create TYPE_RISCV_VENDOR_CPU

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

We want to add a new CPU type for bare CPUs that will inherit specific
traits of the 2 existing types:

- it will allow for extensions to be enabled/disabled, like generic
  CPUs;

- it will NOT inherit defaults, like vendor CPUs.

We can make this conditions met by adding an explicit type for the
existing vendor CPUs and change the existing logic to not imply that
"not generic" means vendor CPUs.

Let's add the "vendor" CPU type first.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-2-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu-qom.h |  1 +
 target/riscv/cpu.c | 30 +-
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 91b3361dec..ca7dd509e3 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -23,6 +23,7 @@
 
 #define TYPE_RISCV_CPU "riscv-cpu"
 #define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu"
+#define TYPE_RISCV_VENDOR_CPU "riscv-vendor-cpu"
 
 #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
 #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 21b0eddf6f..bf0235305e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1748,6 +1748,13 @@ char *riscv_isa_string(RISCVCPU *cpu)
 .instance_init = initfn   \
 }
 
+#define DEFINE_VENDOR_CPU(type_name, initfn) \
+{\
+.name = type_name,   \
+.parent = TYPE_RISCV_VENDOR_CPU, \
+.instance_init = initfn  \
+}
+
 static const TypeInfo riscv_cpu_type_infos[] = {
 {
 .name = TYPE_RISCV_CPU,
@@ -1765,21 +1772,26 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 .parent = TYPE_RISCV_CPU,
 .abstract = true,
 },
+{
+.name = TYPE_RISCV_VENDOR_CPU,
+.parent = TYPE_RISCV_CPU,
+.abstract = true,
+},
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,  riscv_max_cpu_init),
 #if defined(TARGET_RISCV32)
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32,   rv32_base_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,   rv32_sifive_e_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34,   rv32_imafcu_nommu_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,   rv32_sifive_u_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX,rv32_ibex_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31,  rv32_sifive_e_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34,  rv32_imafcu_nommu_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34,  rv32_sifive_u_cpu_init),
 #elif defined(TARGET_RISCV64)
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64,   rv64_base_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,   rv64_sifive_e_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,   rv64_sifive_u_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,   rv64_thead_c906_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_VEYRON_V1,rv64_veyron_v1_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51,  rv64_sifive_e_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54,  rv64_sifive_u_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C,rv64_sifive_u_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906,  rv64_thead_c906_cpu_init),
+DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,   rv64_veyron_v1_cpu_init),
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
 #endif
 };
-- 
2.43.0




[PULL 25/65] hw/riscv/virt.c: fix the interrupts-extended property format of PLIC

2024-01-10 Thread Alistair Francis
From: Yong-Xuan Wang 

The interrupts-extended property of PLIC only has 2 * hart number
fields when KVM enabled, copy 4 * hart number fields to fdt will
expose some uninitialized value.

In this patch, I also refactor the code about the setting of
interrupts-extended property of PLIC for improved readability.

Signed-off-by: Yong-Xuan Wang 
Reviewed-by: Jim Shu 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20231218090543.22353-1-yongxuan.w...@sifive.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt.c | 47 +++
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a7c4c3508e..4194ddcef1 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -437,24 +437,6 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
 "sifive,plic-1.0.0", "riscv,plic0"
 };
 
-if (kvm_enabled()) {
-plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
-} else {
-plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
-}
-
-for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
-if (kvm_enabled()) {
-plic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
-plic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
-} else {
-plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
-plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
-plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
-plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
-}
-}
-
 plic_phandles[socket] = (*phandle)++;
 plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket);
 plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr);
@@ -467,8 +449,33 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
   (char **)&plic_compat,
   ARRAY_SIZE(plic_compat));
 qemu_fdt_setprop(ms->fdt, plic_name, "interrupt-controller", NULL, 0);
-qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended",
-plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
+
+if (kvm_enabled()) {
+plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
+
+for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
+plic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
+plic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
+}
+
+qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended",
+ plic_cells,
+ s->soc[socket].num_harts * sizeof(uint32_t) * 2);
+   } else {
+plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
+
+for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
+plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
+plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
+plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
+plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
+}
+
+qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended",
+ plic_cells,
+ s->soc[socket].num_harts * sizeof(uint32_t) * 4);
+}
+
 qemu_fdt_setprop_cells(ms->fdt, plic_name, "reg",
 0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
 qemu_fdt_setprop_cell(ms->fdt, plic_name, "riscv,ndev",
-- 
2.43.0




[PULL 21/65] hw/pci-host/gpex: Define properties for MMIO ranges

2024-01-10 Thread Alistair Francis
From: Sunil V L 

ACPI DSDT generator needs information like ECAM range, PIO range, 32-bit
and 64-bit PCI MMIO range etc related to the PCI host bridge. Instead of
making these values machine specific, create properties for the GPEX
host bridge with default value 0. During initialization, the firmware
can initialize these properties with correct values for the platform.
This basically allows DSDT generator code independent of the machine
specific memory map accesses.

Suggested-by: Igor Mammedov 
Signed-off-by: Sunil V L 
Acked-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20231218150247.466427-11-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 include/hw/pci-host/gpex.h | 28 
 hw/pci-host/gpex-acpi.c| 13 +
 hw/pci-host/gpex.c | 12 
 3 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
index b0240bd768..dce883573b 100644
--- a/include/hw/pci-host/gpex.h
+++ b/include/hw/pci-host/gpex.h
@@ -40,6 +40,15 @@ struct GPEXRootState {
 /*< public >*/
 };
 
+struct GPEXConfig {
+MemMapEntry ecam;
+MemMapEntry mmio32;
+MemMapEntry mmio64;
+MemMapEntry pio;
+int irq;
+PCIBus  *bus;
+};
+
 struct GPEXHost {
 /*< private >*/
 PCIExpressHost parent_obj;
@@ -55,19 +64,22 @@ struct GPEXHost {
 int irq_num[GPEX_NUM_IRQS];
 
 bool allow_unmapped_accesses;
-};
 
-struct GPEXConfig {
-MemMapEntry ecam;
-MemMapEntry mmio32;
-MemMapEntry mmio64;
-MemMapEntry pio;
-int irq;
-PCIBus  *bus;
+struct GPEXConfig gpex_cfg;
 };
 
 int gpex_set_irq_num(GPEXHost *s, int index, int gsi);
 
 void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg);
+void acpi_dsdt_add_gpex_host(Aml *scope, uint32_t irq);
+
+#define PCI_HOST_PIO_BASE   "x-pio-base"
+#define PCI_HOST_PIO_SIZE   "x-pio-size"
+#define PCI_HOST_ECAM_BASE  "x-ecam-base"
+#define PCI_HOST_ECAM_SIZE  "x-ecam-size"
+#define PCI_HOST_BELOW_4G_MMIO_BASE "x-below-4g-mmio-base"
+#define PCI_HOST_BELOW_4G_MMIO_SIZE "x-below-4g-mmio-size"
+#define PCI_HOST_ABOVE_4G_MMIO_BASE "x-above-4g-mmio-base"
+#define PCI_HOST_ABOVE_4G_MMIO_SIZE "x-above-4g-mmio-size"
 
 #endif /* HW_GPEX_H */
diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index 1092dc3b70..f69413ea2c 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -281,3 +281,16 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
 
 crs_range_set_free(&crs_range_set);
 }
+
+void acpi_dsdt_add_gpex_host(Aml *scope, uint32_t irq)
+{
+bool ambig;
+Object *obj = object_resolve_path_type("", TYPE_GPEX_HOST, &ambig);
+
+if (!obj || ambig) {
+return;
+}
+
+GPEX_HOST(obj)->gpex_cfg.irq = irq;
+acpi_dsdt_add_gpex(scope, &GPEX_HOST(obj)->gpex_cfg);
+}
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index e117e47fa7..e9cf455bf5 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -154,6 +154,18 @@ static Property gpex_host_properties[] = {
  */
 DEFINE_PROP_BOOL("allow-unmapped-accesses", GPEXHost,
  allow_unmapped_accesses, true),
+DEFINE_PROP_UINT64(PCI_HOST_ECAM_BASE, GPEXHost, gpex_cfg.ecam.base, 0),
+DEFINE_PROP_SIZE(PCI_HOST_ECAM_SIZE, GPEXHost, gpex_cfg.ecam.size, 0),
+DEFINE_PROP_UINT64(PCI_HOST_PIO_BASE, GPEXHost, gpex_cfg.pio.base, 0),
+DEFINE_PROP_SIZE(PCI_HOST_PIO_SIZE, GPEXHost, gpex_cfg.pio.size, 0),
+DEFINE_PROP_UINT64(PCI_HOST_BELOW_4G_MMIO_BASE, GPEXHost,
+   gpex_cfg.mmio32.base, 0),
+DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MMIO_SIZE, GPEXHost,
+ gpex_cfg.mmio32.size, 0),
+DEFINE_PROP_UINT64(PCI_HOST_ABOVE_4G_MMIO_BASE, GPEXHost,
+   gpex_cfg.mmio64.base, 0),
+DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MMIO_SIZE, GPEXHost,
+ gpex_cfg.mmio64.size, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.43.0




[PULL 27/65] disas/riscv: Add amocas.[w,d,q] instructions

2024-01-10 Thread Alistair Francis
From: Rob Bradford 

Signed-off-by: Rob Bradford 
Reviewed-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20231207153842.32401-3-rbradf...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 disas/riscv.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/disas/riscv.c b/disas/riscv.c
index e9458e574b..8a546d5ea5 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -903,6 +903,9 @@ typedef enum {
 rv_op_vwsll_vv = 872,
 rv_op_vwsll_vx = 873,
 rv_op_vwsll_vi = 874,
+rv_op_amocas_w = 875,
+rv_op_amocas_d = 876,
+rv_op_amocas_q = 877,
 } rv_op;
 
 /* register names */
@@ -2090,6 +2093,9 @@ const rv_opcode_data rvi_opcode_data[] = {
 { "vwsll.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
 { "vwsll.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
 { "vwsll.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+{ "amocas.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+{ "amocas.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
+{ "amocas.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 },
 };
 
 /* CSR names */
@@ -2841,6 +2847,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
 case 34: op = rv_op_amoxor_w; break;
 case 35: op = rv_op_amoxor_d; break;
 case 36: op = rv_op_amoxor_q; break;
+case 42: op = rv_op_amocas_w; break;
+case 43: op = rv_op_amocas_d; break;
+case 44: op = rv_op_amocas_q; break;
 case 66: op = rv_op_amoor_w; break;
 case 67: op = rv_op_amoor_d; break;
 case 68: op = rv_op_amoor_q; break;
-- 
2.43.0




[PULL 57/65] linux-headers: riscv: add ptrace.h

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

KVM vector support for RISC-V requires the linux-header ptrace.h.

Signed-off-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Message-ID: <20231218204321.75757-3-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 linux-headers/asm-riscv/ptrace.h | 132 +++
 scripts/update-linux-headers.sh  |   3 +
 2 files changed, 135 insertions(+)
 create mode 100644 linux-headers/asm-riscv/ptrace.h

diff --git a/linux-headers/asm-riscv/ptrace.h b/linux-headers/asm-riscv/ptrace.h
new file mode 100644
index 00..1e3166caca
--- /dev/null
+++ b/linux-headers/asm-riscv/ptrace.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Copyright (C) 2012 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_PTRACE_H
+#define _ASM_RISCV_PTRACE_H
+
+#ifndef __ASSEMBLY__
+
+#include 
+
+#define PTRACE_GETFDPIC33
+
+#define PTRACE_GETFDPIC_EXEC   0
+#define PTRACE_GETFDPIC_INTERP 1
+
+/*
+ * User-mode register state for core dumps, ptrace, sigcontext
+ *
+ * This decouples struct pt_regs from the userspace ABI.
+ * struct user_regs_struct must form a prefix of struct pt_regs.
+ */
+struct user_regs_struct {
+   unsigned long pc;
+   unsigned long ra;
+   unsigned long sp;
+   unsigned long gp;
+   unsigned long tp;
+   unsigned long t0;
+   unsigned long t1;
+   unsigned long t2;
+   unsigned long s0;
+   unsigned long s1;
+   unsigned long a0;
+   unsigned long a1;
+   unsigned long a2;
+   unsigned long a3;
+   unsigned long a4;
+   unsigned long a5;
+   unsigned long a6;
+   unsigned long a7;
+   unsigned long s2;
+   unsigned long s3;
+   unsigned long s4;
+   unsigned long s5;
+   unsigned long s6;
+   unsigned long s7;
+   unsigned long s8;
+   unsigned long s9;
+   unsigned long s10;
+   unsigned long s11;
+   unsigned long t3;
+   unsigned long t4;
+   unsigned long t5;
+   unsigned long t6;
+};
+
+struct __riscv_f_ext_state {
+   __u32 f[32];
+   __u32 fcsr;
+};
+
+struct __riscv_d_ext_state {
+   __u64 f[32];
+   __u32 fcsr;
+};
+
+struct __riscv_q_ext_state {
+   __u64 f[64] __attribute__((aligned(16)));
+   __u32 fcsr;
+   /*
+* Reserved for expansion of sigcontext structure.  Currently zeroed
+* upon signal, and must be zero upon sigreturn.
+*/
+   __u32 reserved[3];
+};
+
+struct __riscv_ctx_hdr {
+   __u32 magic;
+   __u32 size;
+};
+
+struct __riscv_extra_ext_header {
+   __u32 __padding[129] __attribute__((aligned(16)));
+   /*
+* Reserved for expansion of sigcontext structure.  Currently zeroed
+* upon signal, and must be zero upon sigreturn.
+*/
+   __u32 reserved;
+   struct __riscv_ctx_hdr hdr;
+};
+
+union __riscv_fp_state {
+   struct __riscv_f_ext_state f;
+   struct __riscv_d_ext_state d;
+   struct __riscv_q_ext_state q;
+};
+
+struct __riscv_v_ext_state {
+   unsigned long vstart;
+   unsigned long vl;
+   unsigned long vtype;
+   unsigned long vcsr;
+   unsigned long vlenb;
+   void *datap;
+   /*
+* In signal handler, datap will be set a correct user stack offset
+* and vector registers will be copied to the address of datap
+* pointer.
+*/
+};
+
+struct __riscv_v_regset_state {
+   unsigned long vstart;
+   unsigned long vl;
+   unsigned long vtype;
+   unsigned long vcsr;
+   unsigned long vlenb;
+   char vreg[];
+};
+
+/*
+ * According to spec: The number of bits in a single vector register,
+ * VLEN >= ELEN, which must be a power of 2, and must be no greater than
+ * 2^16 = 65536bits = 8192bytes
+ */
+#define RISCV_MAX_VLENB (8192)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_PTRACE_H */
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 34295c0fe5..a0006eec6f 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -156,6 +156,9 @@ for arch in $ARCHLIST; do
 cp_portable "$tmpdir/bootparam.h" \
 "$output/include/standard-headers/asm-$arch"
 fi
+if [ $arch = riscv ]; then
+cp "$tmpdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/"
+fi
 done
 
 rm -rf "$output/linux-headers/linux"
-- 
2.43.0




[PULL 50/65] target/riscv/cpu.c: add riscv_cpu_is_32bit()

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Next patch will need to retrieve if a given RISCVCPU is 32 or 64 bit.
The existing helper riscv_is_32bit() (hw/riscv/boot.c) will always check
the first CPU of a given hart array, not any given CPU.

Create a helper to retrieve the info for any given CPU, not the first
CPU of the hart array. The helper is using the same 32 bit check that
riscv_cpu_satp_mode_finalize() was doing.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-23-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 1 +
 target/riscv/cpu.c | 7 ++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3d1c347b71..a0f768e77d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -693,6 +693,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
   uint64_t *cs_base, uint32_t *pflags);
 
 void riscv_cpu_update_mask(CPURISCVState *env);
+bool riscv_cpu_is_32bit(RISCVCPU *cpu);
 
 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 65f69a7dd3..4d1fd7fd48 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -53,6 +53,11 @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, 
RVV,
 #define BYTE(x)   (x)
 #endif
 
+bool riscv_cpu_is_32bit(RISCVCPU *cpu)
+{
+return riscv_cpu_mxl(&cpu->env) == MXL_RV32;
+}
+
 #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
 {#_name, _min_ver, CPU_CFG_OFFSET(_prop)}
 
@@ -978,7 +983,7 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 #ifndef CONFIG_USER_ONLY
 static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
 {
-bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
+bool rv32 = riscv_cpu_is_32bit(cpu);
 uint8_t satp_mode_map_max, satp_mode_supported_max;
 
 /* The CPU wants the OS to decide which satp mode to use */
-- 
2.43.0




[PULL 63/65] target/riscv: Assert that the CSR numbers will be correct

2024-01-10 Thread Alistair Francis
From: Alistair Francis 

The CSRs will always be between either CSR_MHPMCOUNTER3 and
CSR_MHPMCOUNTER31 or CSR_MHPMCOUNTER3H and CSR_MHPMCOUNTER31H.

So although ctr_index can't be negative, Coverity doesn't know this and
it isn't obvious to human readers either. Let's add an assert to ensure
that Coverity knows the values will be within range.

To simplify the code let's also change the RV32 adjustment.

Fixes: Coverity CID 1523910
Signed-off-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20240108001328.280222-2-alistair.fran...@wdc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d8f751a0ae..674ea075a4 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -195,8 +195,11 @@ static RISCVException mctr(CPURISCVState *env, int csrno)
 
 if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
 /* Offset for RV32 mhpmcounternh counters */
-base_csrno += 0x80;
+csrno -= 0x80;
 }
+
+g_assert(csrno >= CSR_MHPMCOUNTER3 && csrno <= CSR_MHPMCOUNTER31);
+
 ctr_index = csrno - base_csrno;
 if ((BIT(ctr_index) & pmu_avail_ctrs >> 3) == 0) {
 /* The PMU is not enabled or counter is out of range */
-- 
2.43.0




[PULL 40/65] target/riscv/tcg: add riscv_cpu_write_misa_bit()

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

We have two instances of the setting/clearing a MISA bit from
env->misa_ext and env->misa_ext_mask pattern. And the next patch will
end up adding one more.

Create a helper to avoid code repetition.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Andrew Jones 
Message-ID: <20231218125334.37184-13-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 731ec2279e..dd8f49b2a6 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -42,6 +42,20 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
  GUINT_TO_POINTER(ext_offset));
 }
 
+static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit,
+ bool enabled)
+{
+CPURISCVState *env = &cpu->env;
+
+if (enabled) {
+env->misa_ext |= bit;
+env->misa_ext_mask |= bit;
+} else {
+env->misa_ext &= ~bit;
+env->misa_ext_mask &= ~bit;
+}
+}
+
 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
   const TranslationBlock *tb)
 {
@@ -833,13 +847,9 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
  */
 env->priv_ver = PRIV_VERSION_1_12_0;
 }
-
-env->misa_ext |= misa_bit;
-env->misa_ext_mask |= misa_bit;
-} else {
-env->misa_ext &= ~misa_bit;
-env->misa_ext_mask &= ~misa_bit;
 }
+
+riscv_cpu_write_misa_bit(cpu, misa_bit, value);
 }
 
 static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
@@ -883,7 +893,6 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
  */
 static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 {
-CPURISCVState *env = &RISCV_CPU(cpu_obj)->env;
 bool use_def_vals = riscv_cpu_is_generic(cpu_obj);
 int i;
 
@@ -904,13 +913,8 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 NULL, (void *)misa_cfg);
 object_property_set_description(cpu_obj, name, desc);
 if (use_def_vals) {
-if (misa_cfg->enabled) {
-env->misa_ext |= bit;
-env->misa_ext_mask |= bit;
-} else {
-env->misa_ext &= ~bit;
-env->misa_ext_mask &= ~bit;
-}
+riscv_cpu_write_misa_bit(RISCV_CPU(cpu_obj), bit,
+ misa_cfg->enabled);
 }
 }
 }
-- 
2.43.0




[PULL 55/65] target/riscv/kvm.c: remove group setting of KVM AIA if the machine only has 1 socket

2024-01-10 Thread Alistair Francis
From: Yong-Xuan Wang 

The emulated AIA within the Linux kernel restores the HART index
of the IMSICs according to the configured AIA settings. During
this process, the group setting is used only when the machine
partitions harts into groups. It's unnecessary to set the group
configuration if the machine has only one socket, as its address
space might not contain the group shift.

Signed-off-by: Yong-Xuan Wang 
Reviewed-by: Jim Shu 
Reviewed-by: Daniel Henrique Barboza 
Message-ID: <20231218090543.22353-2-yongxuan.w...@sifive.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 31 +--
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 2c5217102c..841756ab9b 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1390,21 +1390,24 @@ void kvm_riscv_aia_create(MachineState *machine, 
uint64_t group_shift,
 exit(1);
 }
 
-socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1;
-ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
-KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS,
-&socket_bits, true, NULL);
-if (ret < 0) {
-error_report("KVM AIA: failed to set group_bits");
-exit(1);
-}
 
-ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
-KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT,
-&group_shift, true, NULL);
-if (ret < 0) {
-error_report("KVM AIA: failed to set group_shift");
-exit(1);
+if (socket_count > 1) {
+socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1;
+ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
+KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS,
+&socket_bits, true, NULL);
+if (ret < 0) {
+error_report("KVM AIA: failed to set group_bits");
+exit(1);
+}
+
+ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
+KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT,
+&group_shift, true, NULL);
+if (ret < 0) {
+error_report("KVM AIA: failed to set group_shift");
+exit(1);
+}
 }
 
 guest_bits = guest_num == 0 ? 0 :
-- 
2.43.0




[PULL 06/65] target/riscv/cpu.c: fix machine IDs getters

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

mvendorid is an uint32 property, mimpid/marchid are uint64 properties.
But their getters are returning bools. The reason this went under the
radar for this long is because we have no code using the getters.

The problem can be seem via the 'qom-get' API though. Launching QEMU
with the 'veyron-v1' CPU, a model with:

VEYRON_V1_MVENDORID: 0x61f (1567)
VEYRON_V1_MIMPID: 0x111 (273)
VEYRON_V1_MARCHID: 0x8001 (9223372036854841344)

This is what the API returns when retrieving these properties:

(qemu) qom-get /machine/soc0/harts[0] mvendorid
true
(qemu) qom-get /machine/soc0/harts[0] mimpid
true
(qemu) qom-get /machine/soc0/harts[0] marchid
true

After this patch:

(qemu) qom-get /machine/soc0/harts[0] mvendorid
1567
(qemu) qom-get /machine/soc0/harts[0] mimpid
273
(qemu) qom-get /machine/soc0/harts[0] marchid
9223372036854841344

Fixes: 1e34150045 ("target/riscv/cpu.c: restrict 'mvendorid' value")
Fixes: a1863ad368 ("target/riscv/cpu.c: restrict 'mimpid' value")
Fixes: d6a427e2c0 ("target/riscv/cpu.c: restrict 'marchid' value")
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20231211170732.2541368-1-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b07a76ef6b..53b82cc581 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1570,9 +1570,9 @@ static void cpu_set_mvendorid(Object *obj, Visitor *v, 
const char *name,
 static void cpu_get_mvendorid(Object *obj, Visitor *v, const char *name,
   void *opaque, Error **errp)
 {
-bool value = RISCV_CPU(obj)->cfg.mvendorid;
+uint32_t value = RISCV_CPU(obj)->cfg.mvendorid;
 
-visit_type_bool(v, name, &value, errp);
+visit_type_uint32(v, name, &value, errp);
 }
 
 static void cpu_set_mimpid(Object *obj, Visitor *v, const char *name,
@@ -1599,9 +1599,9 @@ static void cpu_set_mimpid(Object *obj, Visitor *v, const 
char *name,
 static void cpu_get_mimpid(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
 {
-bool value = RISCV_CPU(obj)->cfg.mimpid;
+uint64_t value = RISCV_CPU(obj)->cfg.mimpid;
 
-visit_type_bool(v, name, &value, errp);
+visit_type_uint64(v, name, &value, errp);
 }
 
 static void cpu_set_marchid(Object *obj, Visitor *v, const char *name,
@@ -1649,9 +1649,9 @@ static void cpu_set_marchid(Object *obj, Visitor *v, 
const char *name,
 static void cpu_get_marchid(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
 {
-bool value = RISCV_CPU(obj)->cfg.marchid;
+uint64_t value = RISCV_CPU(obj)->cfg.marchid;
 
-visit_type_bool(v, name, &value, errp);
+visit_type_uint64(v, name, &value, errp);
 }
 
 static void riscv_cpu_class_init(ObjectClass *c, void *data)
-- 
2.43.0




[PULL 44/65] target/riscv/tcg: validate profiles during finalize

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Enabling a profile and then disabling some of its mandatory extensions
is a valid use. It can be useful for debugging and testing. But the
common expected use of enabling a profile is to enable all its mandatory
extensions.

Add an user warning when mandatory extensions from an enabled profile
are disabled in the command line. We're also going to disable the
profile flag in this case since the profile must include all the
mandatory extensions. This flag can be exposed by QMP to indicate the
actual profile state after the CPU is realized.

After this patch, this will throw warnings:

-cpu rv64,rva22u64=true,zihintpause=false,zicbom=false,zicboz=false

qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension 
zihintpause
qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension 
zicbom
qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension 
zicboz

Note that the following will NOT throw warnings because the profile is
being enabled last, hence all its mandatory extensions will be enabled:

-cpu rv64,zihintpause=false,zicbom=false,zicboz=false,rva22u64=true

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-17-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 69 ++
 1 file changed, 69 insertions(+)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index d2a42a347b..6c9e2e9a28 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -147,6 +147,26 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
 g_assert_not_reached();
 }
 
+static const char *cpu_cfg_ext_get_name(uint32_t ext_offset)
+{
+const RISCVCPUMultiExtConfig *feat;
+const RISCVIsaExtData *edata;
+
+for (edata = isa_edata_arr; edata->name != NULL; edata++) {
+if (edata->ext_enable_offset == ext_offset) {
+return edata->name;
+}
+}
+
+for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) {
+if (feat->offset == ext_offset) {
+return feat->name;
+}
+}
+
+g_assert_not_reached();
+}
+
 static bool cpu_cfg_offset_is_named_feat(uint32_t ext_offset)
 {
 const RISCVCPUMultiExtConfig *feat;
@@ -732,6 +752,54 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 riscv_cpu_disable_priv_spec_isa_exts(cpu);
 }
 
+static void riscv_cpu_validate_profile(RISCVCPU *cpu,
+   RISCVCPUProfile *profile)
+{
+const char *warn_msg = "Profile %s mandates disabled extension %s";
+bool send_warn = profile->user_set && profile->enabled;
+bool profile_impl = true;
+int i;
+
+for (i = 0; misa_bits[i] != 0; i++) {
+uint32_t bit = misa_bits[i];
+
+if (!(profile->misa_ext & bit)) {
+continue;
+}
+
+if (!riscv_has_ext(&cpu->env, bit)) {
+profile_impl = false;
+
+if (send_warn) {
+warn_report(warn_msg, profile->name,
+riscv_get_misa_ext_name(bit));
+}
+}
+}
+
+for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
+int ext_offset = profile->ext_offsets[i];
+
+if (!isa_ext_is_enabled(cpu, ext_offset)) {
+profile_impl = false;
+
+if (send_warn) {
+warn_report(warn_msg, profile->name,
+cpu_cfg_ext_get_name(ext_offset));
+}
+}
+}
+
+profile->enabled = profile_impl;
+}
+
+static void riscv_cpu_validate_profiles(RISCVCPU *cpu)
+{
+for (int i = 0; riscv_profiles[i] != NULL; i++) {
+riscv_cpu_validate_profile(cpu, riscv_profiles[i]);
+}
+}
+
 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
 {
 CPURISCVState *env = &cpu->env;
@@ -750,6 +818,7 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 }
 
 riscv_cpu_update_named_features(cpu);
+riscv_cpu_validate_profiles(cpu);
 
 if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) {
 /*
-- 
2.43.0




[PULL 60/65] docs/system/riscv: sifive_u: Update S-mode U-Boot image build instructions

2024-01-10 Thread Alistair Francis
From: Bin Meng 

Currently, the documentation outlines the process for building the
S-mode U-Boot image using `make menuconfig` and manual actions within
the menuconfig UI. However, this approach is fragile due to Kconfig
options potentially changing across different releases. For example,
CONFIG_OF_PRIOR_STAGE has been replaced by CONFIG_BOARD since v2022.01
release, and CONFIG_TEXT_BASE has been moved to the 'General setup'
menu from the 'Boot options' menu in v2024.01 release.

This update aims to make the S-mode U-Boot image build instructions
future-proof. It leverages the 'config' script provided in the U-Boot
source tree to edit the .config file, followed by a `make olddefconfig`.

Validated with U-Boot v2024.01 release.

Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 
Message-ID: <20240104071523.273702-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 docs/system/riscv/sifive_u.rst | 33 -
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst
index 7b166567f9..8f55ae8e31 100644
--- a/docs/system/riscv/sifive_u.rst
+++ b/docs/system/riscv/sifive_u.rst
@@ -210,7 +210,7 @@ command line options with ``qemu-system-riscv32``.
 Running U-Boot
 --
 
-U-Boot mainline v2021.07 release is tested at the time of writing. To build a
+U-Boot mainline v2024.01 release is tested at the time of writing. To build a
 U-Boot mainline bootloader that can be booted by the ``sifive_u`` machine, use
 the sifive_unleashed_defconfig with similar commands as described above for
 Linux:
@@ -325,15 +325,10 @@ configuration of U-Boot:
 
   $ export CROSS_COMPILE=riscv64-linux-
   $ make sifive_unleashed_defconfig
-  $ make menuconfig
-
-then manually select the following configuration:
-
-  * Device Tree Control ---> Provider of DTB for DT Control ---> Prior Stage 
bootloader DTB
-
-and unselect the following configuration:
-
-  * Library routines ---> Allow access to binman information in the device tree
+  $ ./scripts/config --enable OF_BOARD
+  $ ./scripts/config --disable BINMAN_FDT
+  $ ./scripts/config --disable SPL
+  $ make olddefconfig
 
 This changes U-Boot to use the QEMU generated device tree blob, and bypass
 running the U-Boot SPL stage.
@@ -352,17 +347,13 @@ It's possible to create a 32-bit U-Boot S-mode image as 
well.
 
   $ export CROSS_COMPILE=riscv64-linux-
   $ make sifive_unleashed_defconfig
-  $ make menuconfig
-
-then manually update the following configuration in U-Boot:
-
-  * Device Tree Control ---> Provider of DTB for DT Control ---> Prior Stage 
bootloader DTB
-  * RISC-V architecture ---> Base ISA ---> RV32I
-  * Boot options ---> Boot images ---> Text Base ---> 0x8040
-
-and unselect the following configuration:
-
-  * Library routines ---> Allow access to binman information in the device tree
+  $ ./scripts/config --disable ARCH_RV64I
+  $ ./scripts/config --enable ARCH_RV32I
+  $ ./scripts/config --set-val TEXT_BASE 0x8040
+  $ ./scripts/config --enable OF_BOARD
+  $ ./scripts/config --disable BINMAN_FDT
+  $ ./scripts/config --disable SPL
+  $ make olddefconfig
 
 Use the same command line options to boot the 32-bit U-Boot S-mode image:
 
-- 
2.43.0




[PULL 53/65] target/riscv: add RVA22S64 profile

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

The RVA22S64 profile consists of the following:

- all mandatory extensions of RVA22U64;
- priv spec v1.12.0;
- satp mode sv39;
- Ssccptr, a cache related named feature that we're assuming always
  enable since we don't implement a cache;
- Other named features already implemented: Sstvecd, Sstvala,
  Sscounterenw;
- the new Svade named feature that was recently added.

Most of the work is already done, so this patch is enough to implement
the profile.

After this patch, the 'rva22s64' user flag alone can be used with the
rva64i CPU to boot Linux:

-cpu rv64i,rva22s64=true

This is the /proc/cpuinfo with this profile enabled:

 # cat /proc/cpuinfo
processor   : 0
hart: 0
isa : 
rv64imafdc_zicbom_zicbop_zicboz_zicntr_zicsr_zifencei_zihintpause_zihpm_zfhmin_zca_zcd_zba_zbb_zbs_zkt_svinval_svpbmt
mmu : sv39

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-26-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 616b091303..a8f4081922 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1559,8 +1559,40 @@ static RISCVCPUProfile RVA22U64 = {
 }
 };
 
+/*
+ * As with RVA22U64, RVA22S64 also defines 'named features'.
+ *
+ * Cache related features that we consider enabled since we don't
+ * implement cache: Ssccptr
+ *
+ * Other named features that we already implement: Sstvecd, Sstvala,
+ * Sscounterenw
+ *
+ * Named features that we need to enable: svade
+ *
+ * The remaining features/extensions comes from RVA22U64.
+ */
+static RISCVCPUProfile RVA22S64 = {
+.parent = &RVA22U64,
+.name = "rva22s64",
+.misa_ext = RVS,
+.priv_spec = PRIV_VERSION_1_12_0,
+.satp_mode = VM_1_10_SV39,
+.ext_offsets = {
+/* rva22s64 exts */
+CPU_CFG_OFFSET(ext_zifencei), CPU_CFG_OFFSET(ext_svpbmt),
+CPU_CFG_OFFSET(ext_svinval),
+
+/* rva22s64 named features */
+CPU_CFG_OFFSET(svade),
+
+RISCV_PROFILE_EXT_LIST_END
+}
+};
+
 RISCVCPUProfile *riscv_profiles[] = {
 &RVA22U64,
+&RVA22S64,
 NULL,
 };
 
-- 
2.43.0




[PULL 34/65] target/riscv/tcg: add 'zic64b' support

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

zic64b is defined in the RVA22U64 profile [1] as a named feature for
"Cache blocks must be 64 bytes in size, naturally aligned in the address
space". It's a fantasy name for 64 bytes cache blocks. The RVA22U64
profile mandates this feature, meaning that applications using this
profile expects 64 bytes cache blocks.

To make the upcoming RVA22U64 implementation complete, we'll zic64b as
a 'named feature', not a regular extension. This means that:

- it won't be exposed to users;
- it won't be written in riscv,isa.

This will be extended to other named extensions in the future, so we're
creating some common boilerplate for them as well.

zic64b is default to 'true' since we're already using 64 bytes blocks.
If any cache block size (cbo{m,p,z}_blocksize) is changed to something
different than 64, zic64b is set to 'false'.

Our profile implementation will then be able to check the current state
of zic64b and take the appropriate action (e.g. throw a warning).

[1] https://github.com/riscv/riscv-profiles/releases/download/v1.0/profiles.pdf

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-7-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 +
 target/riscv/cpu_cfg.h |  1 +
 target/riscv/cpu.c |  6 ++
 target/riscv/tcg/tcg-cpu.c | 26 ++
 4 files changed, 34 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 2725528bb5..bfa42a0393 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -765,6 +765,7 @@ typedef struct RISCVCPUMultiExtConfig {
 extern const RISCVCPUMultiExtConfig riscv_cpu_extensions[];
 extern const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[];
 extern const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[];
+extern const RISCVCPUMultiExtConfig riscv_cpu_named_features[];
 extern const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[];
 extern Property riscv_cpu_options[];
 
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 2da8ac9582..350ea44e50 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -117,6 +117,7 @@ struct RISCVCPUConfig {
 bool ext_smepmp;
 bool rvv_ta_all_1s;
 bool rvv_ma_all_1s;
+bool zic64b;
 
 uint32_t mvendorid;
 uint64_t marchid;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ce0a3ded04..29fdd64298 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1443,6 +1443,12 @@ const RISCVCPUMultiExtConfig 
riscv_cpu_experimental_exts[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
+MULTI_EXT_CFG_BOOL("zic64b", zic64b, true),
+
+DEFINE_PROP_END_OF_LIST(),
+};
+
 /* Deprecated entries marked for future removal */
 const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = {
 MULTI_EXT_CFG_BOOL("Zifencei", ext_zifencei, true),
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index e9f980805e..f12e0620e5 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -114,6 +114,19 @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
 g_assert_not_reached();
 }
 
+static bool cpu_cfg_offset_is_named_feat(uint32_t ext_offset)
+{
+const RISCVCPUMultiExtConfig *feat;
+
+for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) {
+if (feat->offset == ext_offset) {
+return true;
+}
+}
+
+return false;
+}
+
 static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env,
 uint32_t ext_offset)
 {
@@ -123,6 +136,10 @@ static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env,
 return;
 }
 
+if (cpu_cfg_offset_is_named_feat(ext_offset)) {
+return;
+}
+
 ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset);
 
 if (env->priv_ver < ext_priv_ver) {
@@ -293,6 +310,13 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU 
*cpu)
 }
 }
 
+static void riscv_cpu_update_named_features(RISCVCPU *cpu)
+{
+cpu->cfg.zic64b = cpu->cfg.cbom_blocksize == 64 &&
+  cpu->cfg.cbop_blocksize == 64 &&
+  cpu->cfg.cboz_blocksize == 64;
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly.
@@ -662,6 +686,8 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 return;
 }
 
+riscv_cpu_update_named_features(cpu);
+
 if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) {
 /*
  * Enhanced PMP should only be available
-- 
2.43.0




Re: [RFC PATCH v3 03/30] io: implement io_pwritev/preadv for QIOChannelFile

2024-01-10 Thread Daniel P . Berrangé
On Mon, Nov 27, 2023 at 05:25:45PM -0300, Fabiano Rosas wrote:
> From: Nikolay Borisov 
> 
> The upcoming 'fixed-ram' feature will require qemu to write data to
> (and restore from) specific offsets of the migration file.
> 
> Add a minimal implementation of pwritev/preadv and expose them via the
> io_pwritev and io_preadv interfaces.
> 
> Signed-off-by: Nikolay Borisov 
> Signed-off-by: Fabiano Rosas 
> ---
> - check CONFIG_PREADV to avoid breaking Windows
> ---
>  io/channel-file.c | 56 +++
>  1 file changed, 56 insertions(+)

Reviewed-by: Daniel P. Berrangé 


With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




[PULL 12/65] hw/arm/virt-acpi-build.c: Migrate fw_cfg creation to common location

2024-01-10 Thread Alistair Francis
From: Sunil V L 

RISC-V also needs to use the same code to create fw_cfg in DSDT. So,
avoid code duplication by moving the code in arm and riscv to a device
specific file.

Suggested-by: Igor Mammedov 
Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Reviewed-by: Andrew Jones 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-2-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 include/hw/nvram/fw_cfg_acpi.h | 15 +++
 hw/arm/virt-acpi-build.c   | 19 ++-
 hw/nvram/fw_cfg-acpi.c | 23 +++
 hw/riscv/virt-acpi-build.c | 19 ++-
 hw/nvram/meson.build   |  1 +
 5 files changed, 43 insertions(+), 34 deletions(-)
 create mode 100644 include/hw/nvram/fw_cfg_acpi.h
 create mode 100644 hw/nvram/fw_cfg-acpi.c

diff --git a/include/hw/nvram/fw_cfg_acpi.h b/include/hw/nvram/fw_cfg_acpi.h
new file mode 100644
index 00..b6553d86fc
--- /dev/null
+++ b/include/hw/nvram/fw_cfg_acpi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * ACPI support for fw_cfg
+ *
+ */
+
+#ifndef FW_CFG_ACPI_H
+#define FW_CFG_ACPI_H
+
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+
+void fw_cfg_acpi_dsdt_add(Aml *scope, const MemMapEntry *fw_cfg_memmap);
+
+#endif
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 5e7cf6c6b3..b6edf9db00 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -35,7 +35,7 @@
 #include "target/arm/cpu.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
-#include "hw/nvram/fw_cfg.h"
+#include "hw/nvram/fw_cfg_acpi.h"
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/acpi/aml-build.h"
 #include "hw/acpi/utils.h"
@@ -94,21 +94,6 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
*uart_memmap,
 aml_append(scope, dev);
 }
 
-static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
-{
-Aml *dev = aml_device("FWCF");
-aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
-/* device present, functioning, decoding, not shown in UI */
-aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
-aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
-
-Aml *crs = aml_resource_template();
-aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
-   fw_cfg_memmap->size, AML_READ_WRITE));
-aml_append(dev, aml_name_decl("_CRS", crs));
-aml_append(scope, dev);
-}
-
 static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
 {
 Aml *dev, *crs;
@@ -864,7 +849,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 if (vmc->acpi_expose_flash) {
 acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
 }
-acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
+fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
 acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms);
diff --git a/hw/nvram/fw_cfg-acpi.c b/hw/nvram/fw_cfg-acpi.c
new file mode 100644
index 00..4e48baeaa0
--- /dev/null
+++ b/hw/nvram/fw_cfg-acpi.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Add fw_cfg device in DSDT
+ *
+ */
+
+#include "hw/nvram/fw_cfg_acpi.h"
+#include "hw/acpi/aml-build.h"
+
+void fw_cfg_acpi_dsdt_add(Aml *scope, const MemMapEntry *fw_cfg_memmap)
+{
+Aml *dev = aml_device("FWCF");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
+   fw_cfg_memmap->size, AML_READ_WRITE));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index d3bfaf502e..fc04d1defa 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -28,6 +28,7 @@
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/aml-build.h"
 #include "hw/acpi/utils.h"
+#include "hw/nvram/fw_cfg_acpi.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "sysemu/reset.h"
@@ -97,22 +98,6 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
 }
 }
 
-static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
-{
-Aml *dev = aml_device("FWCF");
-aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
-
-/* device present, functioning, decoding, not shown in UI */
-aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
-aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
-
-Aml *crs = aml_resource_te

[PULL 54/65] target/riscv: add rva22s64 cpu

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Add a new profile CPU 'rva22s64' to work as an alias of

-cpu rv64i,rva22s64

Like the existing rva22u64 CPU already does with the RVA22U64 profile.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-27-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu-qom.h | 1 +
 target/riscv/cpu.c | 8 
 2 files changed, 9 insertions(+)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 12fe78fc52..9219c2fcc3 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -36,6 +36,7 @@
 #define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("x-rv128")
 #define TYPE_RISCV_CPU_RV64IRISCV_CPU_TYPE_NAME("rv64i")
 #define TYPE_RISCV_CPU_RVA22U64 RISCV_CPU_TYPE_NAME("rva22u64")
+#define TYPE_RISCV_CPU_RVA22S64 RISCV_CPU_TYPE_NAME("rva22s64")
 #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
 #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
 #define TYPE_RISCV_CPU_SIFIVE_E31   RISCV_CPU_TYPE_NAME("sifive-e31")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a8f4081922..b32681f7f3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1623,6 +1623,13 @@ static void rva22u64_profile_cpu_init(Object *obj)
 
 RVA22U64.enabled = true;
 }
+
+static void rva22s64_profile_cpu_init(Object *obj)
+{
+rv64i_bare_cpu_init(obj);
+
+RVA22S64.enabled = true;
+}
 #endif
 
 static const gchar *riscv_gdb_arch_name(CPUState *cs)
@@ -1938,6 +1945,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
 DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init),
 DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, rva22u64_profile_cpu_init),
+DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64, rva22s64_profile_cpu_init),
 #endif
 };
 
-- 
2.43.0




Re: [RFC PATCH v3 04/30] io: fsync before closing a file channel

2024-01-10 Thread Daniel P . Berrangé
On Mon, Nov 27, 2023 at 05:25:46PM -0300, Fabiano Rosas wrote:
> Make sure the data is flushed to disk before closing file
> channels. This will ensure data is on disk at the end of a migration
> to file.
> 
> Signed-off-by: Fabiano Rosas 
> ---
>  io/channel-file.c | 5 +
>  1 file changed, 5 insertions(+)

Reviewed-by: Daniel P. Berrangé 
Acked-by: Daniel P. Berrangé 

> 
> diff --git a/io/channel-file.c b/io/channel-file.c
> index a6ad7770c6..d4706fa592 100644
> --- a/io/channel-file.c
> +++ b/io/channel-file.c
> @@ -242,6 +242,11 @@ static int qio_channel_file_close(QIOChannel *ioc,
>  {
>  QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
>  
> +if (qemu_fdatasync(fioc->fd) < 0) {
> +error_setg_errno(errp, errno,
> + "Unable to synchronize file data with storage 
> device");
> +return -1;
> +}
>  if (qemu_close(fioc->fd) < 0) {
>  error_setg_errno(errp, errno,
>   "Unable to close file");
> -- 
> 2.35.3
> 

With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




[PULL 62/65] target/riscv: pmp: Ignore writes when RW=01 and MML=0

2024-01-10 Thread Alistair Francis
From: Ivan Klokov 

This patch changes behavior on writing RW=01 to pmpcfg with MML=0.
RWX filed is form of collective WARL with the combination of
pmpcfg.RW=01 remains reserved for future standard use.

According to definition of WARL writing the CSR has no other side
effect. But current implementation change architectural state and
change system behavior. After writing we will get unreadable-unwriteble
region regardless on the previous state.

On the other side WARL said that we should read legal value and nothing
says about what we should write. Current behavior change system state
regardless of whether we read this register or not.

Fixes: ac66f2f0 ("target/riscv: pmp: Ignore writes when RW=01")

Signed-off-by: Ivan Klokov 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-ID: <20231220153205.11072-1-ivan.klo...@syntacore.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index dff9512c3f..2a76b611a0 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -126,7 +126,7 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t 
pmp_index, uint8_t val)
 /* If !mseccfg.MML then ignore writes with encoding RW=01 */
 if ((val & PMP_WRITE) && !(val & PMP_READ) &&
 !MSECCFG_MML_ISSET(env)) {
-val &= ~(PMP_WRITE | PMP_READ);
+return false;
 }
 env->pmp_state.pmp[pmp_index].cfg_reg = val;
 pmp_update_rule_addr(env, pmp_index);
-- 
2.43.0




[PULL 18/65] hw/riscv/virt-acpi-build.c: Add APLIC in the MADT

2024-01-10 Thread Alistair Francis
From: Sunil V L 

Add APLIC structures for each socket in the MADT when system is configured
with APLIC as the external wired interrupt controller.

Signed-off-by: Sunil V L 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Acked-by: Alistair Francis 
Acked-by: Michael S. Tsirkin 
Message-ID: <20231218150247.466427-8-suni...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt-acpi-build.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 32b5795f09..f50f022dc2 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -274,6 +274,8 @@ static void build_madt(GArray *table_data,
 uint8_t  guest_index_bits = imsic_num_bits(s->aia_guests + 1);
 uint16_t imsic_max_hart_per_socket = 0;
 uint8_t  hart_index_bits;
+uint64_t aplic_addr;
+uint32_t gsi_base;
 uint8_t  socket;
 
 for (socket = 0; socket < riscv_socket_count(ms); socket++) {
@@ -319,6 +321,38 @@ static void build_madt(GArray *table_data,
 build_append_int_noprefix(table_data, IMSIC_MMIO_GROUP_MIN_SHIFT, 1);
 }
 
+if (s->aia_type != VIRT_AIA_TYPE_NONE) {
+/* APLICs */
+for (socket = 0; socket < riscv_socket_count(ms); socket++) {
+aplic_addr = s->memmap[VIRT_APLIC_S].base +
+ s->memmap[VIRT_APLIC_S].size * socket;
+gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
+build_append_int_noprefix(table_data, 0x1A, 1);/* Type */
+build_append_int_noprefix(table_data, 36, 1);  /* Length */
+build_append_int_noprefix(table_data, 1, 1);   /* Version */
+build_append_int_noprefix(table_data, socket, 1);  /* APLIC ID */
+build_append_int_noprefix(table_data, 0, 4);   /* Flags */
+build_append_int_noprefix(table_data, 0, 8);   /* Hardware ID 
*/
+/* Number of IDCs */
+if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
+build_append_int_noprefix(table_data,
+  s->soc[socket].num_harts,
+  2);
+} else {
+build_append_int_noprefix(table_data, 0, 2);
+}
+/* Total External Interrupt Sources Supported */
+build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_SOURCES, 2);
+/* Global System Interrupt Base */
+build_append_int_noprefix(table_data, gsi_base, 4);
+/* APLIC Address */
+build_append_int_noprefix(table_data, aplic_addr, 8);
+/* APLIC size */
+build_append_int_noprefix(table_data,
+  s->memmap[VIRT_APLIC_S].size, 4);
+}
+}
+
 acpi_table_end(linker, &table);
 }
 
-- 
2.43.0




[PULL 37/65] target/riscv/kvm: add 'rva22u64' flag as unavailable

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

KVM does not have the means to support enabling the rva22u64 profile.
The main reasons are:

- we're missing support for some mandatory rva22u64 extensions in the
  KVM module;

- we can't make promises about enabling a profile since it all depends
  on host support in the end.

We'll revisit this decision in the future if needed. For now mark the
'rva22u64' profile as unavailable when running a KVM CPU:

$ qemu-system-riscv64 -machine virt,accel=kvm -cpu rv64,rva22u64=true
qemu-system-riscv64: can't apply global rv64-riscv-cpu.rva22u64=true:
'rva22u64' is not available with KVM

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Andrew Jones 
Message-ID: <20231218125334.37184-10-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/kvm/kvm-cpu.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index a31df6e273..2c5217102c 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -414,7 +414,7 @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
 }
 
 if (value) {
-error_setg(errp, "extension %s is not available with KVM",
+error_setg(errp, "'%s' is not available with KVM",
propname);
 }
 }
@@ -495,6 +495,11 @@ static void kvm_riscv_add_cpu_user_properties(Object 
*cpu_obj)
 riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_extensions);
 riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_vendor_exts);
 riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_experimental_exts);
+
+   /* We don't have the needed KVM support for profiles */
+for (i = 0; riscv_profiles[i] != NULL; i++) {
+riscv_cpu_add_kvm_unavail_prop(cpu_obj, riscv_profiles[i]->name);
+}
 }
 
 static int kvm_riscv_get_regs_core(CPUState *cs)
-- 
2.43.0




[PULL 38/65] target/riscv/tcg: add user flag for profile support

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

The TCG emulation implements all the extensions described in the
RVA22U64 profile, both mandatory and optional. The mandatory extensions
will be enabled via the profile flag. We'll leave the optional
extensions to be enabled by hand.

Given that this is the first profile we're implementing in TCG we'll
need some ground work first:

- all profiles declared in riscv_profiles[] will be exposed to users.
TCG is the main accelerator we're considering when adding profile
support in QEMU, so for now it's safe to assume that all profiles in
riscv_profiles[] will be relevant to TCG;

- we'll not support user profile settings for vendor CPUs. The flags
will still be exposed but users won't be able to change them;

- profile support, albeit available for all non-vendor CPUs, will be
based on top of the new 'rv64i' CPU. Setting a profile to 'true' means
enable all mandatory extensions of this profile, setting it to 'false'
will disable all mandatory profile extensions of the CPU, which will
obliterate preset defaults. This is not a problem for a bare CPU like
rv64i but it can allow for silly scenarios when using other CPUs. E.g.
an user can do "-cpu rv64,rva22u64=false" and have a bunch of default
rv64 extensions disabled. The recommended way of using profiles is the
rv64i CPU, but users are free to experiment.

For now we'll handle multi-letter extensions only. MISA extensions need
additional steps that we'll take care later. At this point we can boot a
Linux buildroot using rva22u64 using the following options:

-cpu rv64i,rva22u64=true,sv39=true,g=true,c=true,s=true

Note that being an usermode/application profile we still need to
explicitly set 's=true' to enable Supervisor mode to boot Linux.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-11-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 80 ++
 1 file changed, 80 insertions(+)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index f12e0620e5..9234254772 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -127,6 +127,19 @@ static bool cpu_cfg_offset_is_named_feat(uint32_t 
ext_offset)
 return false;
 }
 
+static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset)
+{
+switch (feat_offset) {
+case CPU_CFG_OFFSET(zic64b):
+cpu->cfg.cbom_blocksize = 64;
+cpu->cfg.cbop_blocksize = 64;
+cpu->cfg.cboz_blocksize = 64;
+break;
+default:
+g_assert_not_reached();
+}
+}
+
 static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env,
 uint32_t ext_offset)
 {
@@ -890,6 +903,71 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 }
 }
 
+static void cpu_set_profile(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+RISCVCPUProfile *profile = opaque;
+RISCVCPU *cpu = RISCV_CPU(obj);
+bool value;
+int i, ext_offset;
+
+if (riscv_cpu_is_vendor(obj)) {
+error_setg(errp, "Profile %s is not available for vendor CPUs",
+   profile->name);
+return;
+}
+
+if (cpu->env.misa_mxl != MXL_RV64) {
+error_setg(errp, "Profile %s only available for 64 bit CPUs",
+   profile->name);
+return;
+}
+
+if (!visit_type_bool(v, name, &value, errp)) {
+return;
+}
+
+profile->user_set = true;
+profile->enabled = value;
+
+for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) {
+ext_offset = profile->ext_offsets[i];
+
+if (profile->enabled) {
+if (cpu_cfg_offset_is_named_feat(ext_offset)) {
+riscv_cpu_enable_named_feat(cpu, ext_offset);
+}
+
+cpu_bump_multi_ext_priv_ver(&cpu->env, ext_offset);
+}
+
+g_hash_table_insert(multi_ext_user_opts,
+GUINT_TO_POINTER(ext_offset),
+(gpointer)profile->enabled);
+isa_ext_update_enabled(cpu, ext_offset, profile->enabled);
+}
+}
+
+static void cpu_get_profile(Object *obj, Visitor *v, const char *name,
+void *opaque, Error **errp)
+{
+RISCVCPUProfile *profile = opaque;
+bool value = profile->enabled;
+
+visit_type_bool(v, name, &value, errp);
+}
+
+static void riscv_cpu_add_profiles(Object *cpu_obj)
+{
+for (int i = 0; riscv_profiles[i] != NULL; i++) {
+const RISCVCPUProfile *profile = riscv_profiles[i];
+
+object_property_add(cpu_obj, profile->name, "bool",
+cpu_get_profile, cpu_set_profile,
+NULL, (void *)profile);
+}
+}
+
 static bool cpu_ext_is_deprecated(const char *ext_name)
 {
 return isupper(ext_name[0]);
@@ -1017,6 +1095,8 @@ static

Re: [RFC PATCH v3 02/30] io: Add generic pwritev/preadv interface

2024-01-10 Thread Daniel P . Berrangé
On Mon, Nov 27, 2023 at 05:25:44PM -0300, Fabiano Rosas wrote:
> From: Nikolay Borisov 
> 
> Introduce basic pwritev/preadv support in the generic channel layer.
> Specific implementation will follow for the file channel as this is
> required in order to support migration streams with fixed location of
> each ram page.
> 
> Signed-off-by: Nikolay Borisov 
> Signed-off-by: Fabiano Rosas 
> ---
> - fixed naming: s/pwritev_full/pwritev
> ---
>  include/io/channel.h | 82 
>  io/channel.c | 58 +++
>  2 files changed, 140 insertions(+)

Reviewed-by: Daniel P. Berrangé 


With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH 1/2] target/s390x: Fix LAE setting a wrong access register

2024-01-10 Thread David Hildenbrand

On 10.01.24 00:22, Ilya Leoshkevich wrote:

LAE should set the access register corresponding to the first operand,
instead, it always modifies access register 1.

Co-developed-by: Ido Plat 
Cc: qemu-sta...@nongnu.org
Fixes: a1c7610a6879 ("target-s390x: implement LAY and LAEY instructions")
Signed-off-by: Ilya Leoshkevich 
---
  target/s390x/tcg/translate.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 62ab2be8b12..8df00b7df9f 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -3221,6 +3221,7 @@ static DisasJumpType op_mov2e(DisasContext *s, DisasOps 
*o)
  {
  int b2 = get_field(s, b2);
  TCGv ar1 = tcg_temp_new_i64();
+int r1 = get_field(s, r1);
  
  o->out = o->in2;

  o->in2 = NULL;
@@ -3244,7 +3245,7 @@ static DisasJumpType op_mov2e(DisasContext *s, DisasOps 
*o)
  break;
  }
  
-tcg_gen_st32_i64(ar1, tcg_env, offsetof(CPUS390XState, aregs[1]));

+tcg_gen_st32_i64(ar1, tcg_env, offsetof(CPUS390XState, aregs[r1]));
  return DISAS_NEXT;
  }
  


Reviewed-by: David Hildenbrand 

--
Cheers,

David / dhildenb




[PULL 46/65] target/riscv: add 'rva22u64' CPU

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

This CPU was suggested by Alistair [1] and others during the profile
design discussions. It consists of the bare 'rv64i' CPU with rva22u64
enabled by default, like an alias of '-cpu rv64i,rva22u64=true'.

Users now have an even easier way of consuming this user-mode profile by
doing '-cpu rva22u64'. Extensions can be enabled/disabled at will on top
of it.

We can boot Linux with this "user-mode" CPU by doing:

-cpu rva22u64,sv39=true,s=true,zifencei=true

[1] 
https://lore.kernel.org/qemu-riscv/CAKmqyKP7xzZ9Sx=-lbx2ob0qcfb7z+jo944fq2tq+49mqo0...@mail.gmail.com/

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-19-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu-qom.h |  1 +
 target/riscv/cpu.c | 17 +
 target/riscv/tcg/tcg-cpu.c |  9 +
 3 files changed, 27 insertions(+)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 4d1aa54311..12fe78fc52 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -35,6 +35,7 @@
 #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
 #define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("x-rv128")
 #define TYPE_RISCV_CPU_RV64IRISCV_CPU_TYPE_NAME("rv64i")
+#define TYPE_RISCV_CPU_RVA22U64 RISCV_CPU_TYPE_NAME("rva22u64")
 #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
 #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
 #define TYPE_RISCV_CPU_SIFIVE_E31   RISCV_CPU_TYPE_NAME("sifive-e31")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 199b581380..cd3c22e92b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1575,6 +1575,15 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+#if defined(TARGET_RISCV64)
+static void rva22u64_profile_cpu_init(Object *obj)
+{
+rv64i_bare_cpu_init(obj);
+
+RVA22U64.enabled = true;
+}
+#endif
+
 static const gchar *riscv_gdb_arch_name(CPUState *cs)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
@@ -1836,6 +1845,13 @@ char *riscv_isa_string(RISCVCPU *cpu)
 .instance_init = initfn\
 }
 
+#define DEFINE_PROFILE_CPU(type_name, initfn) \
+{ \
+.name = type_name,\
+.parent = TYPE_RISCV_BARE_CPU,\
+.instance_init = initfn   \
+}
+
 static const TypeInfo riscv_cpu_type_infos[] = {
 {
 .name = TYPE_RISCV_CPU,
@@ -1880,6 +1896,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1,   rv64_veyron_v1_cpu_init),
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
 DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init),
+DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, rva22u64_profile_cpu_init),
 #endif
 };
 
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 6c9e2e9a28..f2a9558737 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1100,6 +1100,15 @@ static void riscv_cpu_add_profiles(Object *cpu_obj)
 object_property_add(cpu_obj, profile->name, "bool",
 cpu_get_profile, cpu_set_profile,
 NULL, (void *)profile);
+
+/*
+ * CPUs might enable a profile right from the start.
+ * Enable its mandatory extensions right away in this
+ * case.
+ */
+if (profile->enabled) {
+object_property_set_bool(cpu_obj, profile->name, true, NULL);
+}
 }
 }
 
-- 
2.43.0




[PULL 39/65] target/riscv/tcg: add MISA user options hash

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

We already track user choice for multi-letter extensions because we
needed to honor user choice when enabling/disabling extensions during
realize(). We refrained from adding the same mechanism for MISA
extensions since we didn't need it.

Profile support requires tne need to check for user choice for MISA
extensions, so let's add the corresponding hash now. It works like the
existing multi-letter hash (multi_ext_user_opts) but tracking MISA bits
options in the cpu_set_misa_ext_cfg() callback.

Note that we can't re-use the same hash from multi-letter extensions
because that hash uses cpu->cfg offsets as keys, while for MISA
extensions we're using MISA bits as keys.

After adding the user hash in cpu_set_misa_ext_cfg(), setting default
values with object_property_set_bool() in add_misa_properties() will end
up marking the user choice hash with them. Set the default value
manually to avoid it.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Andrew Jones 
Message-ID: <20231218125334.37184-12-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 9234254772..731ec2279e 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -34,6 +34,7 @@
 
 /* Hash that stores user set extensions */
 static GHashTable *multi_ext_user_opts;
+static GHashTable *misa_ext_user_opts;
 
 static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
 {
@@ -807,6 +808,10 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
+g_hash_table_insert(misa_ext_user_opts,
+GUINT_TO_POINTER(misa_bit),
+(gpointer)value);
+
 prev_val = env->misa_ext & misa_bit;
 
 if (value == prev_val) {
@@ -878,6 +883,7 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
  */
 static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 {
+CPURISCVState *env = &RISCV_CPU(cpu_obj)->env;
 bool use_def_vals = riscv_cpu_is_generic(cpu_obj);
 int i;
 
@@ -898,7 +904,13 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 NULL, (void *)misa_cfg);
 object_property_set_description(cpu_obj, name, desc);
 if (use_def_vals) {
-object_property_set_bool(cpu_obj, name, misa_cfg->enabled, NULL);
+if (misa_cfg->enabled) {
+env->misa_ext |= bit;
+env->misa_ext_mask |= bit;
+} else {
+env->misa_ext &= ~bit;
+env->misa_ext_mask &= ~bit;
+}
 }
 }
 }
@@ -1147,6 +1159,7 @@ static void tcg_cpu_instance_init(CPUState *cs)
 RISCVCPU *cpu = RISCV_CPU(cs);
 Object *obj = OBJECT(cpu);
 
+misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
 multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
 riscv_cpu_add_user_properties(obj);
 
-- 
2.43.0




[PULL 30/65] target/riscv/tcg: do not use "!generic" CPU checks

2024-01-10 Thread Alistair Francis
From: Daniel Henrique Barboza 

Our current logic in get/setters of MISA and multi-letter extensions
works because we have only 2 CPU types, generic and vendor, and by using
"!generic" we're implying that we're talking about vendor CPUs. When adding
a third CPU type this logic will break so let's handle it beforehand.

In set_misa_ext_cfg() and set_multi_ext_cfg(), check for "vendor" cpu instead
of "not generic". The "generic CPU" checks remaining are from
riscv_cpu_add_misa_properties() and cpu_add_multi_ext_prop() before
applying default values for the extensions.

This leaves us with:

- vendor CPUs will not allow extension enablement, all other CPUs will;

- generic CPUs will inherit default values for extensions, all others
  won't.

And now we can add a new, third CPU type, that will allow extensions to
be enabled and will not inherit defaults, without changing the existing
logic.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-ID: <20231218125334.37184-3-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/tcg/tcg-cpu.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 29b5a88931..7174abb7f5 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -668,6 +668,11 @@ static bool riscv_cpu_is_generic(Object *cpu_obj)
 return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
 }
 
+static bool riscv_cpu_is_vendor(Object *cpu_obj)
+{
+return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL;
+}
+
 /*
  * We'll get here via the following path:
  *
@@ -736,7 +741,7 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 target_ulong misa_bit = misa_ext_cfg->misa_bit;
 RISCVCPU *cpu = RISCV_CPU(obj);
 CPURISCVState *env = &cpu->env;
-bool generic_cpu = riscv_cpu_is_generic(obj);
+bool vendor_cpu = riscv_cpu_is_vendor(obj);
 bool prev_val, value;
 
 if (!visit_type_bool(v, name, &value, errp)) {
@@ -750,7 +755,7 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 }
 
 if (value) {
-if (!generic_cpu) {
+if (vendor_cpu) {
 g_autofree char *cpuname = riscv_cpu_get_name(cpu);
 error_setg(errp, "'%s' CPU does not allow enabling extensions",
cpuname);
@@ -855,7 +860,7 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 {
 const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
 RISCVCPU *cpu = RISCV_CPU(obj);
-bool generic_cpu = riscv_cpu_is_generic(obj);
+bool vendor_cpu = riscv_cpu_is_vendor(obj);
 bool prev_val, value;
 
 if (!visit_type_bool(v, name, &value, errp)) {
@@ -879,7 +884,7 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
-if (value && !generic_cpu) {
+if (value && vendor_cpu) {
 g_autofree char *cpuname = riscv_cpu_get_name(cpu);
 error_setg(errp, "'%s' CPU does not allow enabling extensions",
cpuname);
-- 
2.43.0




[PULL 28/65] docs/system/riscv: document acpi parameter of virt machine

2024-01-10 Thread Alistair Francis
From: Heinrich Schuchardt 

Since QEMU v8.0.0 the RISC-V virt machine has a switch to disable ACPI
table generation. Add it to the documentation.

Fixes: 168b8c29cedb ("hw/riscv/virt: Add a switch to disable ACPI")
Signed-off-by: Heinrich Schuchardt 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Sunil V L 
Reviewed-by: Alistair Francis 
Message-ID: <20231220193436.25909-1-heinrich.schucha...@canonical.com>
Signed-off-by: Alistair Francis 
---
 docs/system/riscv/virt.rst | 5 +
 1 file changed, 5 insertions(+)

diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst
index f5fa7b8b29..9a06f95a34 100644
--- a/docs/system/riscv/virt.rst
+++ b/docs/system/riscv/virt.rst
@@ -95,6 +95,11 @@ The following machine-specific options are supported:
   SiFive CLINT. When not specified, this option is assumed to be "off".
   This option is restricted to the TCG accelerator.
 
+- acpi=[on|off|auto]
+
+  When this option is "on" (which is the default), ACPI tables are generated 
and
+  exposed as firmware tables etc/acpi/rsdp and etc/acpi/tables.
+
 - aia=[none|aplic|aplic-imsic]
 
   This option allows selecting interrupt controller defined by the AIA
-- 
2.43.0




Re: [PATCH v4 8/9] target/loongarch: Implement set vcpu intr for kvm

2024-01-10 Thread Philippe Mathieu-Daudé

Hi Tianrui,

On 5/1/24 08:58, Tianrui Zhao wrote:

Implement loongarch kvm set vcpu interrupt interface,
when a irq is set in vcpu, we use the KVM_INTERRUPT
ioctl to set intr into kvm.

Signed-off-by: Tianrui Zhao 
Signed-off-by: xianglai li 
Reviewed-by: Song Gao 
---
  target/loongarch/cpu.c   | 34 +---
  target/loongarch/kvm/kvm.c   | 15 
  target/loongarch/kvm/kvm_loongarch.h | 16 +
  target/loongarch/trace-events|  1 +
  4 files changed, 58 insertions(+), 8 deletions(-)
  create mode 100644 target/loongarch/kvm/kvm_loongarch.h

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 6614a094c8..dfbbe0ace1 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -11,7 +11,6 @@
  #include "qapi/error.h"
  #include "qemu/module.h"
  #include "sysemu/qtest.h"
-#include "exec/cpu_ldst.h"
  #include "exec/exec-all.h"
  #include "cpu.h"
  #include "internals.h"
@@ -20,8 +19,16 @@
  #ifndef CONFIG_USER_ONLY
  #include "sysemu/reset.h"
  #endif
-#include "tcg/tcg.h"
  #include "vec.h"
+#include "sysemu/kvm.h"
+#include "kvm/kvm_loongarch.h"


Shouldn't this header ^ ...


+#ifdef CONFIG_KVM


... goes here?


+#include 
+#endif
+#ifdef CONFIG_TCG
+#include "exec/cpu_ldst.h"
+#include "tcg/tcg.h"
+#endif




RE: [RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location

2024-01-10 Thread JeeHeng Sia


> -Original Message-
> From: JeeHeng Sia
> Sent: Wednesday, January 10, 2024 4:02 PM
> To: Daniel Henrique Barboza ; qemu-...@nongnu.org; 
> qemu-devel@nongnu.org; qemu-
> ri...@nongnu.org
> Cc: m...@redhat.com; imamm...@redhat.com; anisi...@redhat.com; 
> peter.mayd...@linaro.org; shannon.zha...@gmail.com;
> suni...@ventanamicro.com; pal...@dabbelt.com; alistair.fran...@wdc.com; 
> bin.m...@windriver.com; liwei1...@gmail.com;
> zhiwei_...@linux.alibaba.com
> Subject: RE: [RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR 
> creation to common location
> 
> 
> 
> > -Original Message-
> > From: Daniel Henrique Barboza 
> > Sent: Friday, January 5, 2024 8:19 PM
> > To: JeeHeng Sia ; qemu-...@nongnu.org; 
> > qemu-devel@nongnu.org; qemu-ri...@nongnu.org
> > Cc: m...@redhat.com; imamm...@redhat.com; anisi...@redhat.com; 
> > peter.mayd...@linaro.org; shannon.zha...@gmail.com;
> > suni...@ventanamicro.com; pal...@dabbelt.com; alistair.fran...@wdc.com; 
> > bin.m...@windriver.com; liwei1...@gmail.com;
> > zhiwei_...@linux.alibaba.com
> > Subject: Re: [RESEND RFC v1 1/2] hw/arm/virt-acpi-build.c: Migrate SPCR 
> > creation to common location
> >
> >
> >
> > On 1/5/24 06:06, Sia Jee Heng wrote:
> > > RISC-V should also generate the SPCR in a manner similar to ARM.
> > > Therefore, instead of replicating the code, relocate this function
> > > to the common AML build.
> > >
> > > Signed-off-by: Sia Jee Heng 
> > > ---
> > >   hw/acpi/aml-build.c | 51 
> > >   hw/arm/virt-acpi-build.c| 68 +++--
> > >   include/hw/acpi/acpi-defs.h | 33 ++
> > >   include/hw/acpi/aml-build.h |  4 +++
> > >   4 files changed, 115 insertions(+), 41 deletions(-)
> > >
> > > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > > index af66bde0f5..1efa534aa8 100644
> > > --- a/hw/acpi/aml-build.c
> > > +++ b/hw/acpi/aml-build.c
> > > @@ -1994,6 +1994,57 @@ static void build_processor_hierarchy_node(GArray 
> > > *tbl, uint32_t flags,
> > >   }
> > >   }
> > >
> > > +void build_spcr(GArray *table_data, BIOSLinker *linker,
> > > +const AcpiSpcrData *f, const char *oem_id,
> > > +const char *oem_table_id)
> > > +{
> > > +AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = oem_id,
> > > +.oem_table_id = oem_table_id };
> > > +
> > > +acpi_table_begin(&table, table_data);
> > > +/* Interface type */
> > > +build_append_int_noprefix(table_data, f->interface_type, 1);
> > > +/* Reserved */
> > > +build_append_int_noprefix(table_data, 0, 3);
> > > +/* Base Address */
> > > +build_append_gas(table_data, f->base_addr.id, f->base_addr.width,
> > > + f->base_addr.offset, f->base_addr.size,
> > > + f->base_addr.addr);
> > > +/* Interrupt type */
> > > +build_append_int_noprefix(table_data, f->interrupt_type, 1);
> > > +/* IRQ */
> > > +build_append_int_noprefix(table_data, f->pc_interrupt, 1);
> > > +/* Global System Interrupt */
> > > +build_append_int_noprefix(table_data, f->interrupt, 4);
> > > +/* Baud Rate */
> > > +build_append_int_noprefix(table_data, f->baud_rate, 1);
> > > +/* Parity */
> > > +build_append_int_noprefix(table_data, f->parity, 1);
> > > +/* Stop Bits */
> > > +build_append_int_noprefix(table_data, f->stop_bits, 1);
> > > +/* Flow Control */
> > > +build_append_int_noprefix(table_data, f->flow_control, 1);
> > > +/* Terminal Type */
> > > +build_append_int_noprefix(table_data, f->terminal_type, 1);
> > > +/* PCI Device ID  */
> > > +build_append_int_noprefix(table_data, f->pci_device_id, 2);
> > > +/* PCI Vendor ID */
> > > +build_append_int_noprefix(table_data, f->pci_vendor_id, 2);
> > > +/* PCI Bus Number */
> > > +build_append_int_noprefix(table_data, f->pci_bus, 1);
> > > +/* PCI Device Number */
> > > +build_append_int_noprefix(table_data, f->pci_device, 1);
> > > +/* PCI Function Number */
> > > +build_append_int_noprefix(table_data, f->pci_function, 1);
> > > +/* PCI Flags */
> > > +build_append_int_noprefix(table_data, f->pci_flags, 4);
> > > +/* PCI Segment */
> > > +build_append_int_noprefix(table_data, f->pci_segment, 1);
> > > +/* Reserved */
> > > +build_append_int_noprefix(table_data, 0, 4);
> > > +
> > > +acpi_table_end(linker, &table);
> > > +}
> > >   /*
> > >* ACPI spec, Revision 6.3
> > >* 5.2.29 Processor Properties Topology Table (PPTT)
> > > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > > index 510ab0dcca..a31f736d1a 100644
> > > --- a/hw/arm/virt-acpi-build.c
> > > +++ b/hw/arm/virt-acpi-build.c
> > > @@ -431,48 +431,34 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
> > > VirtMachineState *vms)
> > >* Rev: 1.07
> > >*/
> > >   static void
> > > -build_spcr(GArray *table_data, BIOSL

Re: [PATCH v7 02/16] i386/cpu: Use APIC ID offset to encode cache topo in CPUID[4]

2024-01-10 Thread Xiaoyao Li

On 1/8/2024 4:27 PM, Zhao Liu wrote:

From: Zhao Liu 

Refer to the fixes of cache_info_passthrough ([1], [2]) and SDM, the
CPUID.04H:EAX[bits 25:14] and CPUID.04H:EAX[bits 31:26] should use the
nearest power-of-2 integer.

The nearest power-of-2 integer can be calculated by pow2ceil() or by
using APIC ID offset (like L3 topology using 1 << die_offset [3]).

But in fact, CPUID.04H:EAX[bits 25:14] and CPUID.04H:EAX[bits 31:26]
are associated with APIC ID. For example, in linux kernel, the field
"num_threads_sharing" (Bits 25 - 14) is parsed with APIC ID. 


And for

another example, on Alder Lake P, the CPUID.04H:EAX[bits 31:26] is not
matched with actual core numbers and it's calculated by:
"(1 << (pkg_offset - core_offset)) - 1".


could you elaborate it more? what is the value of actual core numbers on 
Alder lake P? and what is the pkg_offset and core_offset?



Therefore the offset of APIC ID should be preferred to calculate nearest
power-of-2 integer for CPUID.04H:EAX[bits 25:14] and CPUID.04H:EAX[bits
31:26]:
1. d/i cache is shared in a core, 1 << core_offset should be used
instand of "cs->nr_threads" in encode_cache_cpuid4() for


/s/instand/instead


CPUID.04H.00H:EAX[bits 25:14] and CPUID.04H.01H:EAX[bits 25:14].
2. L2 cache is supposed to be shared in a core as for now, thereby
1 << core_offset should also be used instand of "cs->nr_threads" in


ditto


encode_cache_cpuid4() for CPUID.04H.02H:EAX[bits 25:14].
3. Similarly, the value for CPUID.04H:EAX[bits 31:26] should also be
calculated with the bit width between the Package and SMT levels in
the APIC ID (1 << (pkg_offset - core_offset) - 1).

In addition, use APIC ID offset to replace "pow2ceil()" for
cache_info_passthrough case.

[1]: efb3934adf9e ("x86: cpu: make sure number of addressable IDs for processor 
cores meets the spec")
[2]: d7caf13b5fcf ("x86: cpu: fixup number of addressable IDs for logical processors 
sharing cache")
[3]: d65af288a84d ("i386: Update new x86_apicid parsing rules with die_offset 
support")

Fixes: 7e3482f82480 ("i386: Helpers to encode cache information consistently")
Suggested-by: Robert Hoo 
Signed-off-by: Zhao Liu 
Tested-by: Babu Moger 
Tested-by: Yongwei Ma 
Acked-by: Michael S. Tsirkin 
---
Changes since v3:
  * Fix compile warnings. (Babu)
  * Fix spelling typo.

Changes since v1:
  * Use APIC ID offset to replace "pow2ceil()" for cache_info_passthrough
case. (Yanan)
  * Split the L1 cache fix into a separate patch.
  * Rename the title of this patch (the original is "i386/cpu: Fix number
of addressable IDs in CPUID.04H").
---
  target/i386/cpu.c | 30 +++---
  1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5a3678a789cf..c8d2a585723a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6014,7 +6014,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
  {
  X86CPU *cpu = env_archcpu(env);
  CPUState *cs = env_cpu(env);
-uint32_t die_offset;
  uint32_t limit;
  uint32_t signature[3];
  X86CPUTopoInfo topo_info;
@@ -6098,39 +6097,56 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
  int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
  int vcpus_per_socket = cs->nr_cores * cs->nr_threads;
  if (cs->nr_cores > 1) {
+int addressable_cores_offset =
+apicid_pkg_offset(&topo_info) -
+apicid_core_offset(&topo_info);
+
  *eax &= ~0xFC00;
-*eax |= (pow2ceil(cs->nr_cores) - 1) << 26;
+*eax |= (1 << (addressable_cores_offset - 1)) << 26;


it should be ((1 << addressable_cores_offset) - 1) << 26

I think naming it addressable_cores_width is better than 
addressable_cores_offset. It's not offset because offset means the bit 
position from bit 0.


And we can get the width by another algorithm:

int addressable_cores_width = apicid_core_width(&topo_info) + 
apicid_die_width(&topo_info);

*eax |= ((1 << addressable_cores_width) - 1)) << 26;


  }
  if (host_vcpus_per_cache > vcpus_per_socket) {
+int pkg_offset = apicid_pkg_offset(&topo_info);
+
  *eax &= ~0x3FFC000;
-*eax |= (pow2ceil(vcpus_per_socket) - 1) << 14;
+*eax |= (1 << (pkg_offset - 1)) << 14;


Ditto, ((1 << pkg_offset) - 1) << 14

For this one, I think pow2ceil(vcpus_per_socket) is better. Because it's 
intuitive that when host_vcpus_per_cache > vcpus_per_socket, we expose 
vcpus_per_cache (configured by users) to VM.



  }
  }
  } else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) {
  *eax = *ebx = *ecx = *edx = 0;
  } else {
  *eax = 0;
+   

[PATCH v4 8/9b] target/loongarch: Implement set vcpu intr for kvm

2024-01-10 Thread Philippe Mathieu-Daudé
From: Tianrui Zhao 

Implement loongarch kvm set vcpu interrupt interface,
when a irq is set in vcpu, we use the KVM_INTERRUPT
ioctl to set intr into kvm.

Signed-off-by: Tianrui Zhao 
Signed-off-by: xianglai li 
Reviewed-by: Song Gao 
Message-ID: <20240105075804.1228596-9-zhaotian...@loongson.cn>
[PMD: Split from bigger patch, part 2]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/kvm/kvm_loongarch.h | 16 
 target/loongarch/cpu.c   |  9 -
 target/loongarch/kvm/kvm.c   | 15 +++
 target/loongarch/trace-events|  1 +
 4 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 target/loongarch/kvm/kvm_loongarch.h

diff --git a/target/loongarch/kvm/kvm_loongarch.h 
b/target/loongarch/kvm/kvm_loongarch.h
new file mode 100644
index 00..d945b6bb82
--- /dev/null
+++ b/target/loongarch/kvm/kvm_loongarch.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch kvm interface
+ *
+ * Copyright (c) 2023 Loongson Technology Corporation Limited
+ */
+
+#include "cpu.h"
+
+#ifndef QEMU_KVM_LOONGARCH_H
+#define QEMU_KVM_LOONGARCH_H
+
+int  kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
+void kvm_arch_reset_vcpu(CPULoongArchState *env);
+
+#endif
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index d9f8661cfd..d3a8a2f521 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -12,6 +12,7 @@
 #include "qemu/module.h"
 #include "sysemu/qtest.h"
 #include "sysemu/tcg.h"
+#include "sysemu/kvm.h"
 #include "exec/exec-all.h"
 #include "cpu.h"
 #include "internals.h"
@@ -21,6 +22,10 @@
 #include "sysemu/reset.h"
 #endif
 #include "vec.h"
+#ifdef CONFIG_KVM
+#include "kvm/kvm_loongarch.h"
+#include 
+#endif
 #ifdef CONFIG_TCG
 #include "exec/cpu_ldst.h"
 #include "tcg/tcg.h"
@@ -113,7 +118,9 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
 return;
 }
 
-if (tcg_enabled()) {
+if (kvm_enabled()) {
+kvm_loongarch_set_interrupt(cpu, irq, level);
+} else if (tcg_enabled()) {
 env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
 if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index d2dab3fef4..bd33ec2114 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -748,6 +748,21 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 return ret;
 }
 
+int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level)
+{
+struct kvm_interrupt intr;
+CPUState *cs = CPU(cpu);
+
+if (level) {
+intr.irq = irq;
+} else {
+intr.irq = -irq;
+}
+
+trace_kvm_set_intr(irq, level);
+return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
+}
+
 void kvm_arch_accel_class_init(ObjectClass *oc)
 {
 }
diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events
index 021839880e..dea11edc0f 100644
--- a/target/loongarch/trace-events
+++ b/target/loongarch/trace-events
@@ -12,3 +12,4 @@ kvm_failed_put_counter(const char *msg) "Failed to put 
counter into KVM: %s"
 kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s"
 kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"
 kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d"
+kvm_set_intr(int irq, int level) "kvm set interrupt, irq num: %d, level: %d"
-- 
2.41.0




[PATCH v4 8/9a] target/loongarch: Restrict TCG-specific code

2024-01-10 Thread Philippe Mathieu-Daudé
From: Tianrui Zhao 

In preparation of supporting KVM in the next commit.

Signed-off-by: Tianrui Zhao 
Signed-off-by: xianglai li 
Reviewed-by: Song Gao 
Message-ID: <20240105075804.1228596-9-zhaotian...@loongson.cn>
[PMD: Split from bigger patch, part 1]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/cpu.c | 30 +-
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 6614a094c8..d9f8661cfd 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -11,7 +11,7 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "sysemu/qtest.h"
-#include "exec/cpu_ldst.h"
+#include "sysemu/tcg.h"
 #include "exec/exec-all.h"
 #include "cpu.h"
 #include "internals.h"
@@ -20,8 +20,11 @@
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/reset.h"
 #endif
-#include "tcg/tcg.h"
 #include "vec.h"
+#ifdef CONFIG_TCG
+#include "exec/cpu_ldst.h"
+#include "tcg/tcg.h"
+#endif
 
 const char * const regnames[32] = {
 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -110,12 +113,13 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int 
level)
 return;
 }
 
-env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
-
-if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
-cpu_interrupt(cs, CPU_INTERRUPT_HARD);
-} else {
-cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+if (tcg_enabled()) {
+env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
+if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
+cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+} else {
+cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+}
 }
 }
 
@@ -140,7 +144,10 @@ static inline bool 
cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env)
 
 return (pending & status) != 0;
 }
+#endif
 
+#ifdef CONFIG_TCG
+#ifndef CONFIG_USER_ONLY
 static void loongarch_cpu_do_interrupt(CPUState *cs)
 {
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
@@ -322,7 +329,6 @@ static bool loongarch_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 }
 #endif
 
-#ifdef CONFIG_TCG
 static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
   const TranslationBlock *tb)
 {
@@ -560,7 +566,9 @@ static void loongarch_cpu_reset_hold(Object *obj)
 }
 #endif
 
+#ifdef CONFIG_TCG
 restore_fp_status(env);
+#endif
 cs->exception_index = -1;
 }
 
@@ -703,8 +711,10 @@ static void loongarch_cpu_init(Object *obj)
 CPULoongArchState *env = &cpu->env;
 
 qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS);
+#ifdef CONFIG_TCG
 timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
   &loongarch_constant_timer_cb, cpu);
+#endif
 memory_region_init_io(&env->system_iocsr, OBJECT(cpu), NULL,
   env, "iocsr", UINT64_MAX);
 address_space_init(&env->address_space_iocsr, &env->system_iocsr, "IOCSR");
@@ -804,7 +814,9 @@ static struct TCGCPUOps loongarch_tcg_ops = {
 #include "hw/core/sysemu-cpu-ops.h"
 
 static const struct SysemuCPUOps loongarch_sysemu_ops = {
+#ifdef CONFIG_TCG
 .get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
+#endif
 };
 
 static int64_t loongarch_cpu_get_arch_id(CPUState *cs)
-- 
2.41.0




Re: [PATCH v4 0/9] Add loongarch kvm accel support

2024-01-10 Thread Philippe Mathieu-Daudé

Hi Song,

On 10/1/24 03:46, gaosong wrote:

在 2024/1/5 下午3:57, Tianrui Zhao 写道:



This series add loongarch kvm support, mainly implement
some interfaces used by kvm, such as kvm_arch_get/set_regs,
kvm_arch_handle_exit, kvm_loongarch_set_interrupt, etc.




Tianrui Zhao (9):
   linux-headers: Synchronize linux headers from linux v6.7.0-rc8
   target/loongarch: Define some kvm_arch interfaces
   target/loongarch: Supplement vcpu env initial when vcpu reset
   target/loongarch: Implement kvm get/set registers
   target/loongarch: Implement kvm_arch_init function
   target/loongarch: Implement kvm_arch_init_vcpu
   target/loongarch: Implement kvm_arch_handle_exit
   target/loongarch: Implement set vcpu intr for kvm
   target/loongarch: Add loongarch kvm into meson build




Applied to loongarch-next.


Sorry it took me some time to test this on a loongarch64
host. I made minor changes to patch #8, please consider
the alternative:
https://lore.kernel.org/qemu-devel/20240110094152.52138-1-phi...@linaro.org/ 
and

https://lore.kernel.org/qemu-devel/20240110094152.52138-2-phi...@linaro.org/



[PATCH] qemu-img: Fix Column Width and Improve Formatting in snapshot list

2024-01-10 Thread atp--- via
From: Abhiram Tilak 

When running the command `qemu-img snapshot -l SNAPSHOT` the output of
VM_CLOCK (measures the offset between host and VM clock) cannot to
accommodate values in the order of thousands (4-digit).

This line [1] hints on the problem. Additionally, the column width for
the VM_CLOCK field was reduced from 15 to 13 spaces in commit b39847a5
in line [2], resulting in a shortage of space.

[1]: 
https://gitlab.com/qemu-project/qemu/-/blob/master/block/qapi.c?ref_type=heads#L753
[2]: 
https://gitlab.com/qemu-project/qemu/-/blob/master/block/qapi.c?ref_type=heads#L763

This patch restores the column width to 15 spaces and makes adjustments 
to the affected iotests accordingly. Furthermore, addresses a potential source 
of confusion by removing whitespace in column headers. Example, VM CLOCK 
is modified to VM_CLOCK. Additionally a '--' symbol is introduced when 
ICOUNT returns no output for clarity.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2062
Fixes: b39847a50553 (migration: introduce icount field for snapshots )
Signed-off-by: Abhiram Tilak  
---
block/qapi.c | 10 
tests/qemu-iotests/267.out | 48 +++---
2 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index 9e806fa230..ee066ee53c 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -742,15 +742,15 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
char *sizing = NULL;

if (!sn) {
- qemu_printf("%-10s%-17s%8s%20s%13s%11s",
- "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT");
+ qemu_printf("%-10s%-17s%8s%20s%15s%11s",
+ "ID", "TAG", "VM_SIZE", "DATE", "VM_CLOCK", "ICOUNT");
} else {
g_autoptr(GDateTime) date = g_date_time_new_from_unix_local(sn->date_sec);
g_autofree char *date_buf = g_date_time_format(date, "%Y-%m-%d %H:%M:%S");

secs = sn->vm_clock_nsec / 10;
snprintf(clock_buf, sizeof(clock_buf),
- "%02d:%02d:%02d.%03d",
+ "%04d:%02d:%02d.%03d",
(int)(secs / 3600),
(int)((secs / 60) % 60),
(int)(secs % 60),
@@ -759,8 +759,10 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
if (sn->icount != -1ULL) {
snprintf(icount_buf, sizeof(icount_buf),
"%"PRId64, sn->icount);
+ } else {
+ snprintf(icount_buf, sizeof(icount_buf), "--");
}
- qemu_printf("%-9s %-16s %8s%20s%13s%11s",
+ qemu_printf("%-9s %-16s %8s%20s%15s%11s",
sn->id_str, sn->name,
sizing,
date_buf,
diff --git a/tests/qemu-iotests/267.out b/tests/qemu-iotests/267.out
index 7176e376e1..21339e67ad 100644
--- a/tests/qemu-iotests/267.out
+++ b/tests/qemu-iotests/267.out
@@ -33,8 +33,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK ICOUNT
--- snap0 SIZE -mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM_SIZE DATE VM_CLOCK ICOUNT
+-- snap0 SIZE -mm-dd hh:mm:ss :00:00.000 --
(qemu) loadvm snap0
(qemu) quit

@@ -44,8 +44,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK ICOUNT
--- snap0 SIZE -mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM_SIZE DATE VM_CLOCK ICOUNT
+-- snap0 SIZE -mm-dd hh:mm:ss :00:00.000 --
(qemu) loadvm snap0
(qemu) quit

@@ -69,8 +69,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK ICOUNT
--- snap0 SIZE -mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM_SIZE DATE VM_CLOCK ICOUNT
+-- snap0 SIZE -mm-dd hh:mm:ss :00:00.000 --
(qemu) loadvm snap0
(qemu) quit

@@ -94,8 +94,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK ICOUNT
--- snap0 SIZE -mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM_SIZE DATE VM_CLOCK ICOUNT
+-- snap0 SIZE -mm-dd hh:mm:ss :00:00.000 --
(qemu) loadvm snap0
(qemu) quit

@@ -105,8 +105,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK ICOUNT
--- snap0 SIZE -mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM_SIZE DATE VM_CLOCK ICOUNT
+-- snap0 SIZE -mm-dd hh:mm:ss :00:00.000 --
(qemu) loadvm snap0
(qemu) quit

@@ -119,8 +119,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK ICOUNT
--- snap0 SIZE -mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM_SIZE DATE VM_CLOCK ICOUNT
+-- snap0 SIZE -mm-dd hh:mm:ss :00:00.000 --
(qemu) loadvm snap0
(qemu) quit

@@ -134,8 +134,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
(qemu) savevm snap0
(qemu) info snapshots
List of snapshots present on all disks:
-ID TAG VM SIZE DATE VM CLOCK ICOUNT
--- snap0 SIZE -mm-dd hh:mm:ss 00:00:00.000
+ID TAG VM_SIZE DATE VM_C

Re: [PATCH v4 0/9] Add loongarch kvm accel support

2024-01-10 Thread gaosong

在 2024/1/10 下午5:42, Philippe Mathieu-Daudé 写道:

Hi Song,

On 10/1/24 03:46, gaosong wrote:

在 2024/1/5 下午3:57, Tianrui Zhao 写道:



This series add loongarch kvm support, mainly implement
some interfaces used by kvm, such as kvm_arch_get/set_regs,
kvm_arch_handle_exit, kvm_loongarch_set_interrupt, etc.




Tianrui Zhao (9):
   linux-headers: Synchronize linux headers from linux v6.7.0-rc8
   target/loongarch: Define some kvm_arch interfaces
   target/loongarch: Supplement vcpu env initial when vcpu reset
   target/loongarch: Implement kvm get/set registers
   target/loongarch: Implement kvm_arch_init function
   target/loongarch: Implement kvm_arch_init_vcpu
   target/loongarch: Implement kvm_arch_handle_exit
   target/loongarch: Implement set vcpu intr for kvm
   target/loongarch: Add loongarch kvm into meson build




Applied to loongarch-next.


Sorry it took me some time to test this on a loongarch64
host. I made minor changes to patch #8, please consider
the alternative:
https://lore.kernel.org/qemu-devel/20240110094152.52138-1-phi...@linaro.org/ 
and
https://lore.kernel.org/qemu-devel/20240110094152.52138-2-phi...@linaro.org/ 



Thank you ,  I wll  apply them to loongarch-next.
if no new problem with this series,  I think we can merge it on this week.

Thanks.
Song Gao




Re: [PATCH] kvm: limit the maximum CPUID.0xA.edx[0..4] to 3

2024-01-10 Thread Shiyuan Gao via
Anyone has suggestion?

When the host kernel before this commit 2e8cd7a3b828 ("kvm: x86: limit the 
maximum number of vPMU
fixed counters to 3") on icelake microarchitecture and newer, execute cpuid in 
the Guest:

Architecture Performance Monitoring Features (0xa/edx):
number of fixed counters= 0x4 (4)

This is not inconsistent with num_architectural_pmu_fixed_counters in QEMU.



[PATCH v3 2/2] target/riscv: support new isa extension detection devicetree properties

2024-01-10 Thread Conor Dooley
From: Conor Dooley 

A few months ago I submitted a patch to various lists, deprecating
"riscv,isa" with a lengthy commit message [0] that is now commit
aeb71e42caae ("dt-bindings: riscv: deprecate riscv,isa") in the Linux
kernel tree. Primarily, the goal was to replace "riscv,isa" with a new
set of properties that allowed for strictly defining the meaning of
various extensions, where "riscv,isa" was tied to whatever definitions
inflicted upon us by the ISA manual, which have seen some variance over
time.

Two new properties were introduced: "riscv,isa-base" and
"riscv,isa-extensions". The former is a simple string to communicate the
base ISA implemented by a hart and the latter an array of strings used
to communicate the set of ISA extensions supported, per the definitions
of each substring in extensions.yaml [1]. A beneficial side effect was
also the ability to define vendor extensions in a more "official" way,
as the ISA manual and other RVI specifications only covered the format
for vendor extensions in the ISA string, but not the meaning of vendor
extensions, for obvious reasons.

Add support for setting these two new properties in the devicetrees for
the various devicetree platforms supported by QEMU for RISC-V. The Linux
kernel already supports parsing ISA extensions from these new
properties, and documenting them in the dt-binding is a requirement for
new extension detection being added to the kernel.

A side effect of the implementation is that the meaning for elements in
"riscv,isa" and in "riscv,isa-extensions" are now tied together as they
are constructed from the same source. The same applies to the ISA string
provided in ACPI tables, but there does not appear to be any strict
definitions of meanings in ACPI land either.

Link: 
https://lore.kernel.org/qemu-riscv/20230702-eats-scorebook-c951f170d29f@spud/ 
[0]
Link: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/riscv/extensions.yaml
 [1]
Signed-off-by: Conor Dooley 
---
 hw/riscv/sifive_u.c |  7 ++
 hw/riscv/spike.c|  6 ++---
 hw/riscv/virt.c |  6 ++---
 target/riscv/cpu.c  | 53 +
 target/riscv/cpu.h  |  1 +
 5 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ec76dce6c9..2f227f15bc 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -171,7 +171,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
*memmap,
 int cpu_phandle = phandle++;
 nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
-char *isa;
 qemu_fdt_add_subnode(fdt, nodename);
 /* cpu 0 is the management hart that does not have mmu */
 if (cpu != 0) {
@@ -180,11 +179,10 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
*memmap,
 } else {
 qemu_fdt_setprop_string(fdt, nodename, "mmu-type", 
"riscv,sv48");
 }
-isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]);
+riscv_isa_write_fdt(&s->soc.u_cpus.harts[cpu - 1], fdt, nodename);
 } else {
-isa = riscv_isa_string(&s->soc.e_cpus.harts[0]);
+riscv_isa_write_fdt(&s->soc.e_cpus.harts[0], fdt, nodename);
 }
-qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
 qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
 qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
@@ -194,7 +192,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
*memmap,
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
-g_free(isa);
 g_free(intc);
 g_free(nodename);
 }
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 81f7e53aed..64074395bc 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -59,7 +59,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
*memmap,
 MachineState *ms = MACHINE(s);
 uint32_t *clint_cells;
 uint32_t cpu_phandle, intc_phandle, phandle = 1;
-char *name, *mem_name, *clint_name, *clust_name;
+char *mem_name, *clint_name, *clust_name;
 char *core_name, *cpu_name, *intc_name;
 static const char * const clint_compat[2] = {
 "sifive,clint0", "riscv,clint0"
@@ -113,9 +113,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
*memmap,
 } else {
 qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", 
"riscv,sv48");
 }
-name = riscv_isa_string(&s->soc[socket].harts[cpu]);
-qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name);
-g_free(name);
+riscv_isa_write_fdt(&s->soc[s

[PATCH v3 0/2] riscv: support new isa extension detection devicetree properties

2024-01-10 Thread Conor Dooley
From: Conor Dooley 

Making it a series to keep the standalone change to riscv_isa_string()
that Drew reported separate.

Changes in v3:
- g_free() isa_extensions too
- use misa_mxl_max rather than the compile target for the base isa
- add a new patch changing riscv_isa_string() to do the same
- drop a null check that cannot be null
- rebased on top of Alistair's next branch

Changes in v2:
- use g_strdup() for multiletter extension string copying
- wrap stuff in #ifndef to prevent breaking the user mode build
- rename riscv_isa_set_props() -> riscv_isa_write_fdt()

CC: Alistair Francis 
CC: Bin Meng 
CC: Palmer Dabbelt 
CC: Weiwei Li 
CC: Daniel Henrique Barboza 
CC: Andrew Jones 
CC: Liu Zhiwei 
CC: qemu-ri...@nongnu.org
CC: qemu-devel@nongnu.org

Conor Dooley (2):
  target/riscv: use misa_mxl_max to populate isa string rather than
TARGET_LONG_BITS
  target/riscv: support new isa extension detection devicetree
properties

 hw/riscv/sifive_u.c |  7 ++
 hw/riscv/spike.c|  6 ++---
 hw/riscv/virt.c |  6 ++---
 target/riscv/cpu.c  | 57 -
 target/riscv/cpu.h  |  1 +
 5 files changed, 63 insertions(+), 14 deletions(-)

-- 
2.39.2




[PATCH v3 1/2] target/riscv: use misa_mxl_max to populate isa string rather than TARGET_LONG_BITS

2024-01-10 Thread Conor Dooley
From: Conor Dooley 

A cpu may not have the same xlen as the compile time target, and
misa_mxl_max is the source of truth for what the hart supports.

Reported-by: Andrew Jones 
Link: https://lore.kernel.org/qemu-riscv/20240108-efa3f83dcd3997dc0af458d7@orel/
Signed-off-by: Conor Dooley 
---
Perhaps this misa_mxl_max -> width conversion should exist as a macro?
There's now 3 individual conversions of this type - two I added and one
in the gdb code.
---
 target/riscv/cpu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8cbfc7e781..5b5da970f2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1860,7 +1860,9 @@ char *riscv_isa_string(RISCVCPU *cpu)
 int i;
 const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
 char *isa_str = g_new(char, maxlen);
-char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
+int xlen = 16 << cpu->env.misa_mxl_max;
+char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", xlen);
+
 for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
 if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
 *p++ = qemu_tolower(riscv_single_letter_exts[i]);
-- 
2.39.2




Re: [PATCH v3 3/4] ci: Add a migration compatibility test job

2024-01-10 Thread Thomas Huth

On 09/01/2024 21.58, Fabiano Rosas wrote:

Cédric Le Goater  writes:


On 1/5/24 19:04, Fabiano Rosas wrote:

The migration tests have support for being passed two QEMU binaries to
test migration compatibility.

Add a CI job that builds the lastest release of QEMU and another job
that uses that version plus an already present build of the current
version and run the migration tests with the two, both as source and
destination. I.e.:

   old QEMU (n-1) -> current QEMU (development tree)
   current QEMU (development tree) -> old QEMU (n-1)

The purpose of this CI job is to ensure the code we're about to merge
will not cause a migration compatibility problem when migrating the
next release (which will contain that code) to/from the previous
release.

I'm leaving the jobs as manual for now because using an older QEMU in
tests could hit bugs that were already fixed in the current
development tree and we need to handle those case-by-case.

Note: for user forks, the version tags need to be pushed to gitlab
otherwise it won't be able to checkout a different version.

Signed-off-by: Fabiano Rosas 
---
   .gitlab-ci.d/buildtest.yml | 53 ++
   1 file changed, 53 insertions(+)

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index 91663946de..81163a3f6a 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -167,6 +167,59 @@ build-system-centos:
 x86_64-softmmu rx-softmmu sh4-softmmu nios2-softmmu
   MAKE_CHECK_ARGS: check-build
   
+build-previous-qemu:

+  extends: .native_build_job_template
+  artifacts:
+when: on_success
+expire_in: 2 days
+paths:
+  - build-previous
+exclude:
+  - build-previous/**/*.p
+  - build-previous/**/*.a.p
+  - build-previous/**/*.fa.p
+  - build-previous/**/*.c.o
+  - build-previous/**/*.c.o.d
+  - build-previous/**/*.fa
+  needs:
+job: amd64-opensuse-leap-container
+  variables:
+QEMU_JOB_OPTIONAL: 1
+IMAGE: opensuse-leap
+TARGETS: x86_64-softmmu aarch64-softmmu
+  before_script:
+- export QEMU_PREV_VERSION="$(sed 's/\([0-9.]*\)\.[0-9]*/v\1.0/' VERSION)"
+- git checkout $QEMU_PREV_VERSION
+  after_script:
+- mv build build-previous
+
+.migration-compat-common:
+  extends: .common_test_job_template
+  needs:
+- job: build-previous-qemu
+- job: build-system-opensuse
+  allow_failure: true
+  variables:
+QEMU_JOB_OPTIONAL: 1
+IMAGE: opensuse-leap
+MAKE_CHECK_ARGS: check-build
+  script:
+- cd build
+- QTEST_QEMU_BINARY_SRC=../build-previous/qemu-system-${TARGET}
+  QTEST_QEMU_BINARY=./qemu-system-${TARGET} 
./tests/qtest/migration-test
+- QTEST_QEMU_BINARY_DST=../build-previous/qemu-system-${TARGET}
+  QTEST_QEMU_BINARY=./qemu-system-${TARGET} 
./tests/qtest/migration-test
+
+migration-compat-aarch64:
+  extends: .migration-compat-common
+  variables:
+TARGET: aarch64
+
+migration-compat-x86_64:
+  extends: .migration-compat-common
+  variables:
+TARGET: x86_64



What about the others archs, s390x and ppc ? Do you lack the resources
or are there any problems to address ?


Currently s390x and ppc are only tested on KVM. Which means they are not
tested at all unless someone runs migration-test on a custom runner. The
same is true for this test.

The TCG tests have been disabled:
 /*
  * On ppc64, the test only works with kvm-hv, but not with kvm-pr and TCG
  * is touchy due to race conditions on dirty bits (especially on PPC for
  * some reason)
  */

 /*
  * Similar to ppc64, s390x seems to be touchy with TCG, so disable it
  * there until the problems are resolved
  */

It would be great if we could figure out what these issues are and fix
them so we can at least test with TCG like we do for aarch64.

Doing a TCG run of migration-test with both archs (one binary only, not
this series):

- ppc survived one run, taking 6 minutes longer than x86/Aarch64.
- s390x survived one run, taking 40s less than x86/aarch64.

I'll leave them enabled on my machine and do some runs here and there,
see if I spot something. If not, we can consider re-enabling them once
we figure out why ppc takes so long.


I was curious and re-enabled the ppc64 and s390x migration tests with TCG on 
my laptop here, running "make check-tcg -j$(nproc)" in a loop. s390x 
unfortunately hang after the second iteration already, but ppc64 survived 25 
runs (then I stopped it).


So we might want to try to re-enable ppc64 at least. But we might need to 
cut the run time for ppc64 with TCG a little bit, it is currently the 
longest test on my system (it takes 240s to finish, while all other tests 
finish within 150s).


 Thomas




Re: [PATCH v9 00/11] virtio: cleanup vhost-user-generic and reduce c&p + vhost-user-input

2024-01-10 Thread Alex Bennée
Alex Bennée  writes:

> A lot of our vhost-user stubs are large chunks of boilerplate that do
> (mostly) the same thing. This series continues the cleanups by
> splitting the vhost-user-base and vhost-user-generic implementations.
> After adding a new vq_size property the rng, gpio and i2c vhost-user
> devices become simple specialisations of the common base defining the
> ID, number of queues and potentially the config handling.
>
> I've also added Manos' vhost-user-sound and Leo's vhost-user-input
> stubs which are based on the same base.

Ping MST,

Are you waiting for anything else before pulling this into your queue?

>
> Changes
> ---
>
> v9
>   - re-base and fix conflicts
>   - add Leo's vhost-user-input series
>
> v8
>   - scrubbed errant Message-Id
>
> v7
>   - various review comments
>   - move to async teardown (fixes CI failure)
>
> v6
>   - re-base to current master
>   - make vhost-user-device abstract
>   - mention abstractness in docs
>
> v5
>   - addressing comments and tags
>   - improved the docs
>
> v4
>   - dropped the F_TRANSPORT work for another series
>   - added vhost-user-sound
>
> Alex Bennée (6):
>   virtio: split into vhost-user-base and vhost-user-device
>   hw/virtio: convert vhost-user-base to async shutdown
>   hw/virtio: derive vhost-user-rng from vhost-user-base
>   hw/virtio: derive vhost-user-gpio from vhost-user-base
>   hw/virtio: derive vhost-user-i2c from vhost-user-base
>   docs/system: add a basic enumeration of vhost-user devices
>
> Leo Yan (4):
>   hw/virtio: Support set_config() callback in vhost-user-base
>   docs/system: Add vhost-user-input documentation
>   hw/virtio: Move vhost-user-input into virtio folder
>   hw/virtio: derive vhost-user-input from vhost-user-base
>
> Manos Pitsidianakis (1):
>   hw/virtio: add vhost-user-snd and virtio-snd-pci devices
>
>  MAINTAINERS   |  16 +-
>  docs/system/device-emulation.rst  |   1 +
>  docs/system/devices/vhost-user-input.rst  |  45 ++
>  docs/system/devices/vhost-user-rng.rst|   2 +
>  docs/system/devices/vhost-user.rst|  72 +++-
>  ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
>  include/hw/virtio/vhost-user-gpio.h   |  25 +-
>  include/hw/virtio/vhost-user-i2c.h|  14 +-
>  include/hw/virtio/vhost-user-rng.h|  13 +-
>  include/hw/virtio/vhost-user-snd.h|  24 ++
>  include/hw/virtio/virtio-input.h  |   6 +-
>  hw/input/vhost-user-input.c   | 136 --
>  hw/virtio/vhost-user-base.c   | 371 
>  hw/virtio/vhost-user-device-pci.c |  13 +-
>  hw/virtio/vhost-user-device.c | 338 +--
>  hw/virtio/vhost-user-gpio.c   | 407 +-
>  hw/virtio/vhost-user-i2c.c| 272 +---
>  hw/virtio/vhost-user-input-pci.c  |   3 -
>  hw/virtio/vhost-user-input.c  |  58 +++
>  hw/virtio/vhost-user-rng.c| 294 +
>  hw/virtio/vhost-user-snd-pci.c|  75 
>  hw/virtio/vhost-user-snd.c|  67 +++
>  hw/input/meson.build  |   1 -
>  hw/virtio/Kconfig |   5 +
>  hw/virtio/meson.build |  27 +-
>  25 files changed, 850 insertions(+), 1456 deletions(-)
>  create mode 100644 docs/system/devices/vhost-user-input.rst
>  rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
>  create mode 100644 include/hw/virtio/vhost-user-snd.h
>  delete mode 100644 hw/input/vhost-user-input.c
>  create mode 100644 hw/virtio/vhost-user-base.c
>  create mode 100644 hw/virtio/vhost-user-input.c
>  create mode 100644 hw/virtio/vhost-user-snd-pci.c
>  create mode 100644 hw/virtio/vhost-user-snd.c

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH] io: add trace event when cancelling TLS handshake

2024-01-10 Thread Daniel P . Berrangé
Signed-off-by: Daniel P. Berrangé 
---
 io/channel-tls.c | 1 +
 io/trace-events  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/io/channel-tls.c b/io/channel-tls.c
index 58fe1aceee..1d9c9c72bf 100644
--- a/io/channel-tls.c
+++ b/io/channel-tls.c
@@ -381,6 +381,7 @@ static int qio_channel_tls_close(QIOChannel *ioc,
 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);
 
 if (tioc->hs_ioc_tag) {
+trace_qio_channel_tls_handshake_cancel(ioc);
 g_clear_handle_id(&tioc->hs_ioc_tag, g_source_remove);
 }
 
diff --git a/io/trace-events b/io/trace-events
index 3cc5cf1efd..d4c0f84a9a 100644
--- a/io/trace-events
+++ b/io/trace-events
@@ -43,6 +43,7 @@ qio_channel_tls_handshake_start(void *ioc) "TLS handshake 
start ioc=%p"
 qio_channel_tls_handshake_pending(void *ioc, int status) "TLS handshake 
pending ioc=%p status=%d"
 qio_channel_tls_handshake_fail(void *ioc) "TLS handshake fail ioc=%p"
 qio_channel_tls_handshake_complete(void *ioc) "TLS handshake complete ioc=%p"
+qio_channel_tls_handshake_cancel(void *ioc) "TLS handshake cancel ioc=%p"
 qio_channel_tls_credentials_allow(void *ioc) "TLS credentials allow ioc=%p"
 qio_channel_tls_credentials_deny(void *ioc) "TLS credentials deny ioc=%p"
 
-- 
2.43.0




[PATCH] chardev: close QIOChannel before unref'ing

2024-01-10 Thread Daniel P . Berrangé
The chardev socket backend will unref the QIOChannel object while
it is still potentially open. When using TLS there could be a
pending TLS handshake taking place. If the channel is left open
then when the TLS handshake callback runs, it can end up accessing
free'd memory in the tcp_chr_tls_handshake method.

Closing the QIOChannel will unregister any pending handshake
source.

Reported-by: jiangyegen 
Signed-off-by: Daniel P. Berrangé 
---
 chardev/char-socket.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 73947da188..7105753815 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -378,6 +378,10 @@ static void tcp_chr_free_connection(Chardev *chr)
  char_socket_yank_iochannel,
  QIO_CHANNEL(s->sioc));
 }
+
+if (s->ioc) {
+qio_channel_close(s->ioc, NULL);
+}
 object_unref(OBJECT(s->sioc));
 s->sioc = NULL;
 object_unref(OBJECT(s->ioc));
-- 
2.43.0




Re: [PATCH] kvm: limit the maximum CPUID.0xA.edx[0..4] to 3

2024-01-10 Thread Gao,Shiyuan
> Anyone has suggestion?
>
> When the host kernel before this commit 2e8cd7a3b828 ("kvm: x86: limit the 
> maximum number of vPMU
> fixed counters to 3") on icelake microarchitecture and newer, execute cpuid 
> in the Guest:
>
> Architecture Performance Monitoring Features (0xa/edx):
> number of fixed counters= 0x4 (4)
>
> This is not inconsistent with num_architectural_pmu_fixed_counters in QEMU.

This is the orginal patch.

kvm: limit the maximum CPUID.0xA.edx[0..4] to 3

Now, the CPUID.0xA depends on the KVM report. The value of CPUID.0xA.edx[0..4]
and num_architectural_pmu_fixed_counters are inconsistent when the host kernel
before this commit 2e8cd7a3b828 ("kvm: x86: limit the maximum number of vPMU
fixed counters to 3") on icelake microarchitecture.

This also break the live-migration between source host kernel before commit
2e8cd7a3b828 and dest host kernel after the commit on icelake microarchitecture.

Signed-off-by: Shiyuan Gao 
---
 target/i386/kvm/kvm.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index de531842f6..e77129b737 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1761,7 +1761,7 @@ int kvm_arch_init_vcpu(CPUState *cs)

 X86CPU *cpu = X86_CPU(cs);
 CPUX86State *env = &cpu->env;
-uint32_t limit, i, j, cpuid_i;
+uint32_t limit, i, j, cpuid_i, cpuid_0xa;
 uint32_t unused;
 struct kvm_cpuid_entry2 *c;
 uint32_t signature[3];
@@ -1773,6 +1773,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 memset(&cpuid_data, 0, sizeof(cpuid_data));

 cpuid_i = 0;
+cpuid_0xa = 0;

 has_xsave2 = kvm_check_extension(cs->kvm_state, KVM_CAP_XSAVE2);

@@ -2045,6 +2046,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
 c->function = i;
 c->flags = 0;
 cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
+if (0x0a == i) {
+cpuid_0xa = cpuid_i - 1;
+}
 if (!c->eax && !c->ebx && !c->ecx && !c->edx) {
 /*
  * KVM already returns all zeroes if a CPUID entry is missing,
@@ -2059,7 +2063,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
 if (limit >= 0x0a) {
 uint32_t eax, edx;

-cpu_x86_cpuid(env, 0x0a, 0, &eax, &unused, &unused, &edx);
+assert(cpuid_0xa >= 0x0a);
+
+c = &cpuid_data.entries[cpuid_0xa];
+eax = c->eax;
+edx = c->edx;

 has_architectural_pmu_version = eax & 0xff;
 if (has_architectural_pmu_version > 0) {
@@ -2078,6 +2086,7 @@ int kvm_arch_init_vcpu(CPUState *cs)

 if (num_architectural_pmu_fixed_counters > MAX_FIXED_COUNTERS) 
{
 num_architectural_pmu_fixed_counters = MAX_FIXED_COUNTERS;
+c->edx = (edx & ~0x1f) | 
num_architectural_pmu_fixed_counters;
 }
 }
 }



Re: [PATCH v2 01/14] target/arm/cpu: Simplify checking A64_MTE bit in FEATURE_ID register

2024-01-10 Thread Peter Maydell
On Wed, 10 Jan 2024 at 06:01, Richard Henderson
 wrote:
>
> On 1/10/24 05:09, Philippe Mathieu-Daudé wrote:
> > cpu_isar_feature(aa64_mte, cpu) is testing a AArch64-only ID
> > register. The ARM_FEATURE_AARCH64 check is redundant.
> >
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> >   target/arm/cpu.c | 3 +--
> >   1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > index 1c8b787482..c828b333c9 100644
> > --- a/target/arm/cpu.c
> > +++ b/target/arm/cpu.c
> > @@ -1690,8 +1690,7 @@ void arm_cpu_post_init(Object *obj)
> >   }
> >
> >   #ifndef CONFIG_USER_ONLY
> > -if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) &&
> > -cpu_isar_feature(aa64_mte, cpu)) {
> > +if (cpu_isar_feature(aa64_mte, cpu)) {
> >   object_property_add_link(obj, "tag-memory",
> >TYPE_MEMORY_REGION,
> >(Object **)&cpu->tag_memory,
>
> It is not redundant.
>
> If !AARCH64, then the isar registers tested by aa64_mte are invalid.

Ah, I think I steered Philippe wrongly on IRC on this one
because I forgot how our feature checking handled this,
but yes, you're right.

-- PMM



Re: [PATCH v3 1/2] target/riscv: use misa_mxl_max to populate isa string rather than TARGET_LONG_BITS

2024-01-10 Thread Andrew Jones
On Wed, Jan 10, 2024 at 10:25:36AM +, Conor Dooley wrote:
> From: Conor Dooley 
> 
> A cpu may not have the same xlen as the compile time target, and
> misa_mxl_max is the source of truth for what the hart supports.
> 
> Reported-by: Andrew Jones 
> Link: 
> https://lore.kernel.org/qemu-riscv/20240108-efa3f83dcd3997dc0af458d7@orel/
> Signed-off-by: Conor Dooley 
> ---
> Perhaps this misa_mxl_max -> width conversion should exist as a macro?
> There's now 3 individual conversions of this type - two I added and one
> in the gdb code.

A macro is a good idea. I had to go look at Table 3.1 of the priv spec to
understand the 16 shift stuff.

> ---
>  target/riscv/cpu.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 8cbfc7e781..5b5da970f2 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1860,7 +1860,9 @@ char *riscv_isa_string(RISCVCPU *cpu)
>  int i;
>  const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts);
>  char *isa_str = g_new(char, maxlen);
> -char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
> +int xlen = 16 << cpu->env.misa_mxl_max;
> +char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", xlen);
> +
>  for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) {
>  if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) {
>  *p++ = qemu_tolower(riscv_single_letter_exts[i]);
> -- 
> 2.39.2
>

Reviewed-by: Andrew Jones 



Re: [PATCH v3 2/2] target/riscv: support new isa extension detection devicetree properties

2024-01-10 Thread Andrew Jones
On Wed, Jan 10, 2024 at 10:25:37AM +, Conor Dooley wrote:
> From: Conor Dooley 
> 
> A few months ago I submitted a patch to various lists, deprecating
> "riscv,isa" with a lengthy commit message [0] that is now commit
> aeb71e42caae ("dt-bindings: riscv: deprecate riscv,isa") in the Linux
> kernel tree. Primarily, the goal was to replace "riscv,isa" with a new
> set of properties that allowed for strictly defining the meaning of
> various extensions, where "riscv,isa" was tied to whatever definitions
> inflicted upon us by the ISA manual, which have seen some variance over
> time.
> 
> Two new properties were introduced: "riscv,isa-base" and
> "riscv,isa-extensions". The former is a simple string to communicate the
> base ISA implemented by a hart and the latter an array of strings used
> to communicate the set of ISA extensions supported, per the definitions
> of each substring in extensions.yaml [1]. A beneficial side effect was
> also the ability to define vendor extensions in a more "official" way,
> as the ISA manual and other RVI specifications only covered the format
> for vendor extensions in the ISA string, but not the meaning of vendor
> extensions, for obvious reasons.
> 
> Add support for setting these two new properties in the devicetrees for
> the various devicetree platforms supported by QEMU for RISC-V. The Linux
> kernel already supports parsing ISA extensions from these new
> properties, and documenting them in the dt-binding is a requirement for
> new extension detection being added to the kernel.
> 
> A side effect of the implementation is that the meaning for elements in
> "riscv,isa" and in "riscv,isa-extensions" are now tied together as they
> are constructed from the same source. The same applies to the ISA string
> provided in ACPI tables, but there does not appear to be any strict
> definitions of meanings in ACPI land either.
> 
> Link: 
> https://lore.kernel.org/qemu-riscv/20230702-eats-scorebook-c951f170d29f@spud/ 
> [0]
> Link: 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/riscv/extensions.yaml
>  [1]
> Signed-off-by: Conor Dooley 
> ---
>  hw/riscv/sifive_u.c |  7 ++
>  hw/riscv/spike.c|  6 ++---
>  hw/riscv/virt.c |  6 ++---
>  target/riscv/cpu.c  | 53 +
>  target/riscv/cpu.h  |  1 +
>  5 files changed, 60 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index ec76dce6c9..2f227f15bc 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -171,7 +171,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
> *memmap,
>  int cpu_phandle = phandle++;
>  nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
>  char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", 
> cpu);
> -char *isa;
>  qemu_fdt_add_subnode(fdt, nodename);
>  /* cpu 0 is the management hart that does not have mmu */
>  if (cpu != 0) {
> @@ -180,11 +179,10 @@ static void create_fdt(SiFiveUState *s, const 
> MemMapEntry *memmap,
>  } else {
>  qemu_fdt_setprop_string(fdt, nodename, "mmu-type", 
> "riscv,sv48");
>  }
> -isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]);
> +riscv_isa_write_fdt(&s->soc.u_cpus.harts[cpu - 1], fdt, 
> nodename);
>  } else {
> -isa = riscv_isa_string(&s->soc.e_cpus.harts[0]);
> +riscv_isa_write_fdt(&s->soc.e_cpus.harts[0], fdt, nodename);
>  }
> -qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
>  qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
>  qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
>  qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
> @@ -194,7 +192,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
> *memmap,
>  qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
>  qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
>  qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
> -g_free(isa);
>  g_free(intc);
>  g_free(nodename);
>  }
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index 81f7e53aed..64074395bc 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -59,7 +59,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>  MachineState *ms = MACHINE(s);
>  uint32_t *clint_cells;
>  uint32_t cpu_phandle, intc_phandle, phandle = 1;
> -char *name, *mem_name, *clint_name, *clust_name;
> +char *mem_name, *clint_name, *clust_name;
>  char *core_name, *cpu_name, *intc_name;
>  static const char * const clint_compat[2] = {
>  "sifive,clint0", "riscv,clint0"
> @@ -113,9 +113,7 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>  } else {
>  qemu_fdt_setp

  1   2   3   >