* [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ
@ 2023-09-19 10:12 Peter Maydell
2023-09-19 10:12 ` [RFC 1/3] tests/qtest/bios-tables-test: Allow changes to virt GTDT Peter Maydell
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Peter Maydell @ 2023-09-19 10:12 UTC (permalink / raw)
To: qemu-arm, qemu-devel
Cc: Leif Lindholm, Marcin Juszkiewicz, Ard Biesheuvel, Shannon Zhao,
Michael S. Tsirkin, Igor Mammedov, Ani Sinha
This patchset is an RFC that wires up the NS EL2 virtual timer IRQ on
the virt board, similarly to what
https://patchew.org/QEMU/20230913140610.214893-1-marcin.juszkiewicz@linaro.org/
does for the sbsa-ref board.
Patches 1 and 3 are the usual dance to keep the ACPI unit tests happy
with the change to the ACPI table contents; patch 2 is the meat.
This is an RFC for two reasons:
(1) I'm not very familiar with ACPI, and patch 2 needs to update the
ACPI GTDT table to report the interrupt number. In particular, this
means we need the rev 3 of this table (present in ACPI spec 6.3 and
later), not the rev 2 we currently report. I'm not sure if it's
permitted to rev just this table, or if we would need to upgrade all
our ACPI tables to the newer spec first.
(2) The change causes EDK2 (UEFI) to assert on startup:
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
This is because the EDK2 code that consumes the QEMU generated device
tree blob is incorrectly insisting that the architectural-timer
interrupts property has only 3 or 4 entries, so it falls over if
given a dtb with the 5th entry for the EL2 virtual timer irq. In
particular this breaks the avocado test:
machine_aarch64_virt.py:Aarch64VirtMachine.test_alpine_virt_tcg_gic_max
I'm not entirely sure what to do about this -- we can get EDK2 fixed
and update our own test case, but there's a lot of binaries out there
in the wild that won't run if we just update the virt board the way
this patchset does. We could perhaps make the virt board change be
dependent on machine type version, as a way to let users fall back to
the old behaviour.
I'm putting this patchset out on the list to get opinions and
review on those two points.
thanks
-- PMM
Peter Maydell (3):
tests/qtest/bios-tables-test: Allow changes to virt GTDT
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
tests/qtest/bios-tables-test: Update virt/GTDT golden reference
include/hw/arm/virt.h | 2 ++
hw/arm/virt-acpi-build.c | 16 ++++++++++++----
hw/arm/virt.c | 29 ++++++++++++++++++++++++++++-
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
4 files changed, 42 insertions(+), 5 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC 1/3] tests/qtest/bios-tables-test: Allow changes to virt GTDT
2023-09-19 10:12 [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Peter Maydell
@ 2023-09-19 10:12 ` Peter Maydell
2023-09-19 10:12 ` [RFC 2/3] hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ Peter Maydell
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Peter Maydell @ 2023-09-19 10:12 UTC (permalink / raw)
To: qemu-arm, qemu-devel
Cc: Leif Lindholm, Marcin Juszkiewicz, Ard Biesheuvel, Shannon Zhao,
Michael S. Tsirkin, Igor Mammedov, Ani Sinha
Allow changes to the virt GTDT -- we are going to add the IRQ
entry for a new timer to it.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
tests/qtest/bios-tables-test-allowed-diff.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf..bcf131fc160 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/virt/GTDT",
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 2/3] hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
2023-09-19 10:12 [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Peter Maydell
2023-09-19 10:12 ` [RFC 1/3] tests/qtest/bios-tables-test: Allow changes to virt GTDT Peter Maydell
@ 2023-09-19 10:12 ` Peter Maydell
2023-09-19 13:32 ` Ard Biesheuvel
2023-09-19 10:12 ` [RFC 3/3] tests/qtest/bios-tables-test: Update virt/GTDT golden reference Peter Maydell
` (2 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Peter Maydell @ 2023-09-19 10:12 UTC (permalink / raw)
To: qemu-arm, qemu-devel
Cc: Leif Lindholm, Marcin Juszkiewicz, Ard Biesheuvel, Shannon Zhao,
Michael S. Tsirkin, Igor Mammedov, Ani Sinha
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds
a non-secure EL2 virtual timer. We implemented the timer itself
in the CPU model, but never wired up its IRQ line to the GIC.
Wire up the IRQ line (this is always safe whether the CPU has the
interrupt or not, since it always creates the outbound IRQ line).
Report it to the guest via dtb and ACPI if the CPU has the feature.
The DTB binding is documented in the kernel's
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
and the ACPI table entries are documented in the ACPI
specification version 6.3 or later.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/hw/arm/virt.h | 2 ++
hw/arm/virt-acpi-build.c | 16 ++++++++++++----
hw/arm/virt.c | 29 ++++++++++++++++++++++++++++-
3 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index e1ddbea96be..79b1f9b737d 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -49,6 +49,7 @@
#define ARCH_TIMER_S_EL1_IRQ 13
#define ARCH_TIMER_NS_EL1_IRQ 14
#define ARCH_TIMER_NS_EL2_IRQ 10
+#define ARCH_TIMER_NS_EL2_VIRT_IRQ 12
#define VIRTUAL_PMU_IRQ 7
@@ -183,6 +184,7 @@ struct VirtMachineState {
PCIBus *bus;
char *oem_id;
char *oem_table_id;
+ bool ns_el2_virt_timer_present;
};
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 6b674231c27..7bc120a0f13 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -573,8 +573,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
}
/*
- * ACPI spec, Revision 5.1
- * 5.2.24 Generic Timer Description Table (GTDT)
+ * ACPI spec, Revision 6.5
+ * 5.2.25 Generic Timer Description Table (GTDT)
*/
static void
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
@@ -588,7 +588,7 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
1 : /* Interrupt is Edge triggered */
0; /* Interrupt is Level triggered */
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
.oem_table_id = vms->oem_table_id };
acpi_table_begin(&table, table_data);
@@ -624,7 +624,15 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, 0, 4);
/* Platform Timer Offset */
build_append_int_noprefix(table_data, 0, 4);
-
+ if (vms->ns_el2_virt_timer_present) {
+ /* Virtual EL2 Timer GSIV */
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ + 16, 4);
+ /* Virtual EL2 Timer Flags */
+ build_append_int_noprefix(table_data, irqflags, 4);
+ } else {
+ build_append_int_noprefix(table_data, 0, 4);
+ build_append_int_noprefix(table_data, 0, 4);
+ }
acpi_table_end(linker, &table);
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8ad78b23c24..4df7cd0a366 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -248,6 +248,19 @@ static void create_randomness(MachineState *ms, const char *node)
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
}
+/*
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
+ * but we don't want to advertise it to the guest in the dtb or ACPI
+ * table unless it's really going to do something.
+ */
+static bool ns_el2_virt_timer_present(void)
+{
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
+ CPUARMState *env = &cpu->env;
+
+ return arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
+}
+
static void create_fdt(VirtMachineState *vms)
{
MachineState *ms = MACHINE(vms);
@@ -365,11 +378,20 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
"arm,armv7-timer");
}
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
+ if (vms->ns_el2_virt_timer_present) {
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_VIRT_IRQ, irqflags);
+ } else {
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
+ }
}
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
@@ -810,6 +832,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
};
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
@@ -2249,6 +2272,10 @@ static void machvirt_init(MachineState *machine)
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
object_unref(cpuobj);
}
+
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
+ vms->ns_el2_virt_timer_present = ns_el2_virt_timer_present();
+
fdt_add_timer_nodes(vms);
fdt_add_cpu_nodes(vms);
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 3/3] tests/qtest/bios-tables-test: Update virt/GTDT golden reference
2023-09-19 10:12 [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Peter Maydell
2023-09-19 10:12 ` [RFC 1/3] tests/qtest/bios-tables-test: Allow changes to virt GTDT Peter Maydell
2023-09-19 10:12 ` [RFC 2/3] hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ Peter Maydell
@ 2023-09-19 10:12 ` Peter Maydell
2023-09-19 13:32 ` [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Ard Biesheuvel
2023-09-19 15:07 ` Leif Lindholm
4 siblings, 0 replies; 7+ messages in thread
From: Peter Maydell @ 2023-09-19 10:12 UTC (permalink / raw)
To: qemu-arm, qemu-devel
Cc: Leif Lindholm, Marcin Juszkiewicz, Ard Biesheuvel, Shannon Zhao,
Michael S. Tsirkin, Igor Mammedov, Ani Sinha
Update the virt/GTDT golden reference file to be a
revision 3 table with space for the virtual EL2 timer.
Diffs from iasl:
@@ -1,32 +1,32 @@
/*
* Intel ACPI Component Architecture
* AML/ASL+ Disassembler version 20200925 (64-bit version)
* Copyright (c) 2000 - 2020 Intel Corporation
*
- * Disassembly of tests/data/acpi/virt/GTDT, Mon Sep 18 16:19:17 2023
+ * Disassembly of /tmp/aml-PXK8A2, Mon Sep 18 16:19:17 2023
*
* ACPI Data Table [GTDT]
*
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
*/
[000h 0000 4] Signature : "GTDT" [Generic Timer Description Table]
-[004h 0004 4] Table Length : 00000060
-[008h 0008 1] Revision : 02
-[009h 0009 1] Checksum : 9C
+[004h 0004 4] Table Length : 00000068
+[008h 0008 1] Revision : 03
+[009h 0009 1] Checksum : 93
[00Ah 0010 6] Oem ID : "BOCHS "
[010h 0016 8] Oem Table ID : "BXPC "
[018h 0024 4] Oem Revision : 00000001
[01Ch 0028 4] Asl Compiler ID : "BXPC"
[020h 0032 4] Asl Compiler Revision : 00000001
[024h 0036 8] Counter Block Address : FFFFFFFFFFFFFFFF
[02Ch 0044 4] Reserved : 00000000
[030h 0048 4] Secure EL1 Interrupt : 0000001D
[034h 0052 4] EL1 Flags (decoded below) : 00000000
Trigger Mode : 0
Polarity : 0
Always On : 0
[038h 0056 4] Non-Secure EL1 Interrupt : 0000001E
@@ -37,25 +37,28 @@
[040h 0064 4] Virtual Timer Interrupt : 0000001B
[044h 0068 4] VT Flags (decoded below) : 00000000
Trigger Mode : 0
Polarity : 0
Always On : 0
[048h 0072 4] Non-Secure EL2 Interrupt : 0000001A
[04Ch 0076 4] NEL2 Flags (decoded below) : 00000000
Trigger Mode : 0
Polarity : 0
Always On : 0
[050h 0080 8] Counter Read Block Address : FFFFFFFFFFFFFFFF
[058h 0088 4] Platform Timer Count : 00000000
[05Ch 0092 4] Platform Timer Offset : 00000000
+[060h 0096 4] Virtual EL2 Timer GSIV : 00000000
+[064h 0100 4] Virtual EL2 Timer Flags : 00000000
-Raw Table Data: Length 96 (0x60)
+Raw Table Data: Length 104 (0x68)
- 0000: 47 54 44 54 60 00 00 00 02 9C 42 4F 43 48 53 20 // GTDT`.....BOCHS
+ 0000: 47 54 44 54 68 00 00 00 03 93 42 4F 43 48 53 20 // GTDTh.....BOCHS
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
0020: 01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 // ................
0030: 1D 00 00 00 00 00 00 00 1E 00 00 00 04 00 00 00 // ................
0040: 1B 00 00 00 00 00 00 00 1A 00 00 00 00 00 00 00 // ................
0050: FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 // ................
+ 0060: 00 00 00 00 00 00 00 00 // ........
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
2 files changed, 1 deletion(-)
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index bcf131fc160..dfb8523c8bf 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,2 +1 @@
/* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/virt/GTDT",
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
index 6f8cb9b8f30b55f4c93fe515982621e3db50feb2..7f330e04d144f9cc22eef06127ecc19abf9e8009 100644
GIT binary patch
delta 25
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
delta 16
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC 2/3] hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
2023-09-19 10:12 ` [RFC 2/3] hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ Peter Maydell
@ 2023-09-19 13:32 ` Ard Biesheuvel
0 siblings, 0 replies; 7+ messages in thread
From: Ard Biesheuvel @ 2023-09-19 13:32 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-arm, qemu-devel, Leif Lindholm, Marcin Juszkiewicz,
Shannon Zhao, Michael S. Tsirkin, Igor Mammedov, Ani Sinha
On Tue, 19 Sept 2023 at 12:12, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds
> a non-secure EL2 virtual timer. We implemented the timer itself
> in the CPU model, but never wired up its IRQ line to the GIC.
>
> Wire up the IRQ line (this is always safe whether the CPU has the
> interrupt or not, since it always creates the outbound IRQ line).
> Report it to the guest via dtb and ACPI if the CPU has the feature.
>
> The DTB binding is documented in the kernel's
> Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
> and the ACPI table entries are documented in the ACPI
> specification version 6.3 or later.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
As mentioned in reply to the cover letter, this needs the hunk below
to avoid using ACPI 6.3 features while claiming compatibility with
ACPI 6.0
With that added,
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -811,10 +811,10 @@ build_madt(GArray *table_data, BIOSLinker
*linker, VirtMachineState *vms)
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
VirtMachineState *vms, unsigned dsdt_tbl_offset)
{
- /* ACPI v6.0 */
+ /* ACPI v6.3 */
AcpiFadtData fadt = {
.rev = 6,
- .minor_ver = 0,
+ .minor_ver = 3,
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
.xdsdt_tbl_offset = &dsdt_tbl_offset,
};
> ---
> include/hw/arm/virt.h | 2 ++
> hw/arm/virt-acpi-build.c | 16 ++++++++++++----
> hw/arm/virt.c | 29 ++++++++++++++++++++++++++++-
> 3 files changed, 42 insertions(+), 5 deletions(-)
>
> diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
> index e1ddbea96be..79b1f9b737d 100644
> --- a/include/hw/arm/virt.h
> +++ b/include/hw/arm/virt.h
> @@ -49,6 +49,7 @@
> #define ARCH_TIMER_S_EL1_IRQ 13
> #define ARCH_TIMER_NS_EL1_IRQ 14
> #define ARCH_TIMER_NS_EL2_IRQ 10
> +#define ARCH_TIMER_NS_EL2_VIRT_IRQ 12
>
> #define VIRTUAL_PMU_IRQ 7
>
> @@ -183,6 +184,7 @@ struct VirtMachineState {
> PCIBus *bus;
> char *oem_id;
> char *oem_table_id;
> + bool ns_el2_virt_timer_present;
> };
>
> #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 6b674231c27..7bc120a0f13 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -573,8 +573,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> }
>
> /*
> - * ACPI spec, Revision 5.1
> - * 5.2.24 Generic Timer Description Table (GTDT)
> + * ACPI spec, Revision 6.5
> + * 5.2.25 Generic Timer Description Table (GTDT)
> */
> static void
> build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> @@ -588,7 +588,7 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> uint32_t irqflags = vmc->claim_edge_triggered_timers ?
> 1 : /* Interrupt is Edge triggered */
> 0; /* Interrupt is Level triggered */
> - AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
> + AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
> .oem_table_id = vms->oem_table_id };
>
> acpi_table_begin(&table, table_data);
> @@ -624,7 +624,15 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> build_append_int_noprefix(table_data, 0, 4);
> /* Platform Timer Offset */
> build_append_int_noprefix(table_data, 0, 4);
> -
> + if (vms->ns_el2_virt_timer_present) {
> + /* Virtual EL2 Timer GSIV */
> + build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ + 16, 4);
> + /* Virtual EL2 Timer Flags */
> + build_append_int_noprefix(table_data, irqflags, 4);
> + } else {
> + build_append_int_noprefix(table_data, 0, 4);
> + build_append_int_noprefix(table_data, 0, 4);
> + }
> acpi_table_end(linker, &table);
> }
>
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 8ad78b23c24..4df7cd0a366 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -248,6 +248,19 @@ static void create_randomness(MachineState *ms, const char *node)
> qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
> }
>
> +/*
> + * The CPU object always exposes the NS EL2 virt timer IRQ line,
> + * but we don't want to advertise it to the guest in the dtb or ACPI
> + * table unless it's really going to do something.
> + */
> +static bool ns_el2_virt_timer_present(void)
> +{
> + ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
> + CPUARMState *env = &cpu->env;
> +
> + return arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
> +}
> +
> static void create_fdt(VirtMachineState *vms)
> {
> MachineState *ms = MACHINE(vms);
> @@ -365,11 +378,20 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
> "arm,armv7-timer");
> }
> qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
> - qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
> + if (vms->ns_el2_virt_timer_present) {
> + qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
> + GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
> + GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
> + GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
> + GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags,
> + GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_VIRT_IRQ, irqflags);
> + } else {
> + qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
> GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
> GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
> GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
> GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
> + }
> }
>
> static void fdt_add_cpu_nodes(const VirtMachineState *vms)
> @@ -810,6 +832,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
> [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
> [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
> [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
> + [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
> };
>
> for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
> @@ -2249,6 +2272,10 @@ static void machvirt_init(MachineState *machine)
> qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
> object_unref(cpuobj);
> }
> +
> + /* Now we've created the CPUs we can see if they have the hypvirt timer */
> + vms->ns_el2_virt_timer_present = ns_el2_virt_timer_present();
> +
> fdt_add_timer_nodes(vms);
> fdt_add_cpu_nodes(vms);
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ
2023-09-19 10:12 [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Peter Maydell
` (2 preceding siblings ...)
2023-09-19 10:12 ` [RFC 3/3] tests/qtest/bios-tables-test: Update virt/GTDT golden reference Peter Maydell
@ 2023-09-19 13:32 ` Ard Biesheuvel
2023-09-19 15:07 ` Leif Lindholm
4 siblings, 0 replies; 7+ messages in thread
From: Ard Biesheuvel @ 2023-09-19 13:32 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-arm, qemu-devel, Leif Lindholm, Marcin Juszkiewicz,
Shannon Zhao, Michael S. Tsirkin, Igor Mammedov, Ani Sinha
Hi Peter,
On Tue, 19 Sept 2023 at 12:12, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> This patchset is an RFC that wires up the NS EL2 virtual timer IRQ on
> the virt board, similarly to what
> https://patchew.org/QEMU/20230913140610.214893-1-marcin.juszkiewicz@linaro.org/
> does for the sbsa-ref board.
>
> Patches 1 and 3 are the usual dance to keep the ACPI unit tests happy
> with the change to the ACPI table contents; patch 2 is the meat.
>
> This is an RFC for two reasons:
>
> (1) I'm not very familiar with ACPI, and patch 2 needs to update the
> ACPI GTDT table to report the interrupt number. In particular, this
> means we need the rev 3 of this table (present in ACPI spec 6.3 and
> later), not the rev 2 we currently report. I'm not sure if it's
> permitted to rev just this table, or if we would need to upgrade all
> our ACPI tables to the newer spec first.
>
Using a newer revision of a table is fine as long as the FADT
major/minor fields match the spec version that introduced it. No need
to update all the other tables.
> (2) The change causes EDK2 (UEFI) to assert on startup:
> ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
> This is because the EDK2 code that consumes the QEMU generated device
> tree blob is incorrectly insisting that the architectural-timer
> interrupts property has only 3 or 4 entries, so it falls over if
> given a dtb with the 5th entry for the EL2 virtual timer irq. In
> particular this breaks the avocado test:
> machine_aarch64_virt.py:Aarch64VirtMachine.test_alpine_virt_tcg_gic_max
> I'm not entirely sure what to do about this -- we can get EDK2 fixed
> and update our own test case, but there's a lot of binaries out there
> in the wild that won't run if we just update the virt board the way
> this patchset does. We could perhaps make the virt board change be
> dependent on machine type version, as a way to let users fall back to
> the old behaviour.
>
ASSERT()s only fire in DEBUG builds so the impact should be limited.
> I'm putting this patchset out on the list to get opinions and
> review on those two points.
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ
2023-09-19 10:12 [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Peter Maydell
` (3 preceding siblings ...)
2023-09-19 13:32 ` [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Ard Biesheuvel
@ 2023-09-19 15:07 ` Leif Lindholm
4 siblings, 0 replies; 7+ messages in thread
From: Leif Lindholm @ 2023-09-19 15:07 UTC (permalink / raw)
To: Peter Maydell, qemu-arm, qemu-devel
Cc: Marcin Juszkiewicz, Ard Biesheuvel, Shannon Zhao,
Michael S. Tsirkin, Igor Mammedov, Ani Sinha
On 2023-09-19 11:12, Peter Maydell wrote:
> This patchset is an RFC that wires up the NS EL2 virtual timer IRQ on
> the virt board, similarly to what
> https://patchew.org/QEMU/20230913140610.214893-1-marcin.juszkiewicz@linaro.org/
> does for the sbsa-ref board.
>
> Patches 1 and 3 are the usual dance to keep the ACPI unit tests happy
> with the change to the ACPI table contents; patch 2 is the meat.
>
> This is an RFC for two reasons:
>
> (1) I'm not very familiar with ACPI, and patch 2 needs to update the
> ACPI GTDT table to report the interrupt number. In particular, this
> means we need the rev 3 of this table (present in ACPI spec 6.3 and
> later), not the rev 2 we currently report. I'm not sure if it's
> permitted to rev just this table, or if we would need to upgrade all
> our ACPI tables to the newer spec first.
Ard already provided the answer for this.
> (2) The change causes EDK2 (UEFI) to assert on startup:
> ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
> This is because the EDK2 code that consumes the QEMU generated device
> tree blob is incorrectly insisting that the architectural-timer
> interrupts property has only 3 or 4 entries, so it falls over if
> given a dtb with the 5th entry for the EL2 virtual timer irq. In
> particular this breaks the avocado test:
> machine_aarch64_virt.py:Aarch64VirtMachine.test_alpine_virt_tcg_gic_max
> I'm not entirely sure what to do about this -- we can get EDK2 fixed
> and update our own test case, but there's a lot of binaries out there
> in the wild that won't run if we just update the virt board the way
> this patchset does. We could perhaps make the virt board change be
> dependent on machine type version, as a way to let users fall back to
> the old behaviour.
And kind of this one too. Although I might expand somewhat:
As I understand it, this only breaks an existing setup where someone is
- Running a DEBUG build of edk2
- With virtualization=on
I don't see that (currently) happening outside development/ci, and the
RELEASE builds should save anyone not actually working on edk2 but only
running it to test other things.
Ard has given me an r-b on the fix, so that can be merged today.
It will then land in edk2-stable202311 around the end of November, but
will be on the main branch as soon as it passes ci.
I have one comment on my own, which is this clearly has a merge conflict
with my PPI rework patches.
Regards,
Leif
> I'm putting this patchset out on the list to get opinions and
> review on those two points.
>
> thanks
> -- PMM
>
> Peter Maydell (3):
> tests/qtest/bios-tables-test: Allow changes to virt GTDT
> hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
> tests/qtest/bios-tables-test: Update virt/GTDT golden reference
>
> include/hw/arm/virt.h | 2 ++
> hw/arm/virt-acpi-build.c | 16 ++++++++++++----
> hw/arm/virt.c | 29 ++++++++++++++++++++++++++++-
> tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
> 4 files changed, 42 insertions(+), 5 deletions(-)
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-09-19 15:09 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-19 10:12 [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Peter Maydell
2023-09-19 10:12 ` [RFC 1/3] tests/qtest/bios-tables-test: Allow changes to virt GTDT Peter Maydell
2023-09-19 10:12 ` [RFC 2/3] hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ Peter Maydell
2023-09-19 13:32 ` Ard Biesheuvel
2023-09-19 10:12 ` [RFC 3/3] tests/qtest/bios-tables-test: Update virt/GTDT golden reference Peter Maydell
2023-09-19 13:32 ` [RFC 0/3] virt: wire up NS EL2 virtual timer IRQ Ard Biesheuvel
2023-09-19 15:07 ` Leif Lindholm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).