|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] xen/riscv: introduce minimal virtual APLIC (vAPLIC) infrastructure
commit 9164a97efbeb57a8e53b129189223abb8cbc4250
Author: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
AuthorDate: Wed Sep 9 17:07:30 2026 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Sep 21 10:08:35 2026 +0200
xen/riscv: introduce minimal virtual APLIC (vAPLIC) infrastructure
At the current development stage, only domain vINTC init and deinit
operations are required, so implement those first.
Initialize vAPLIC's domaincfg to with the interrupt-enable bit set and
MSI delivery mode selected as the current solution is exepcted to have
always IMSIC, and initialize vintc->ops.
Other operations such as emulate_load(), emulate_store(), and is_access()
will be needed once guests are running and MMIO accesses to APLIC MMIO
range must be handled. These will be introduced separately later.
Introduce a structure to describe a virtual interrupt controller (vINTC)
and a vintc_ops structure, which provides operations to emulate load and
store accesses to interrupt controller MMIOs and to check whether a given
address falls within the MMIO range of a specific virtual interrupt
controller.
Note that already existed init_ops field in struct vintc will be init-ed
for APLIC in the follow up patch.
The vAPLIC implementation of these operations will be provided later
once guests can be run and these operations are actually needed.
Introduce these structures here as they are required for the implementation
of domain_vaplic_init() and domain_vaplic_alloc(). Also, introduce
vaplic_init() and init vintc_ops->vcpu_init() with it.
Co-developed-by: Romain Caritey <Romain.Caritey@xxxxxxxxxxxxx>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
---
xen/arch/riscv/Makefile | 1 +
xen/arch/riscv/domain.c | 11 +++-----
xen/arch/riscv/imsic.c | 4 +--
xen/arch/riscv/include/asm/aplic.h | 7 +++++
xen/arch/riscv/include/asm/intc.h | 12 +++++++++
xen/arch/riscv/include/asm/vaplic.h | 34 ++++++++++++++++++++++++
xen/arch/riscv/vaplic.c | 52 +++++++++++++++++++++++++++++++++++++
7 files changed, 111 insertions(+), 10 deletions(-)
diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index 8e7a6370ee..fcd73c7a2d 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -25,6 +25,7 @@ obj-y += smpboot.o
obj-y += stubs.o
obj-y += time.o
obj-y += traps.o
+obj-y += vaplic.o
obj-y += vmid.o
obj-y += vm_event.o
obj-y += vsbi/
diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c
index c993314759..45712d3059 100644
--- a/xen/arch/riscv/domain.c
+++ b/xen/arch/riscv/domain.c
@@ -11,6 +11,7 @@
#include <asm/bitops.h>
#include <asm/cpufeature.h>
#include <asm/csr.h>
+#include <asm/intc.h>
#include <asm/riscv_encoding.h>
#include <asm/vtimer.h>
@@ -155,14 +156,8 @@ int arch_vcpu_create(struct vcpu *v)
if ( (rc = vcpu_vtimer_init(v)) )
goto fail;
- /*
- * As interrupt controller (IC) is not yet implemented,
- * return an error.
- *
- * TODO: Drop this once IC is implemented.
- */
- rc = -EOPNOTSUPP;
- goto fail;
+ if ( (rc = v->domain->arch.vintc->ops->vcpu_init(v)) )
+ goto fail;
return rc;
diff --git a/xen/arch/riscv/imsic.c b/xen/arch/riscv/imsic.c
index 4a2ef5069d..809f29af86 100644
--- a/xen/arch/riscv/imsic.c
+++ b/xen/arch/riscv/imsic.c
@@ -318,7 +318,7 @@ static int imsic_parse_node(const struct dt_device_node
*node,
return 0;
}
-int vcpu_imsic_init(struct vcpu *v)
+int cf_check vcpu_imsic_init(struct vcpu *v)
{
struct vimsic_state *imsic_state;
@@ -342,7 +342,7 @@ int vcpu_imsic_init(struct vcpu *v)
return 0;
}
-void vcpu_imsic_deinit(struct vcpu *v)
+void cf_check vcpu_imsic_deinit(struct vcpu *v)
{
XVFREE(v->arch.vimsic_state);
}
diff --git a/xen/arch/riscv/include/asm/aplic.h
b/xen/arch/riscv/include/asm/aplic.h
index b0724fe6f3..5a7fcb6ec4 100644
--- a/xen/arch/riscv/include/asm/aplic.h
+++ b/xen/arch/riscv/include/asm/aplic.h
@@ -15,8 +15,15 @@
#include <asm/imsic.h>
+/*
+ * domaincfg read-only fields (AIA spec):
+ * - bits [31:24] -> read-only 0x80
+ * - bit 7 -> read-only 0
+ */
+#define APLIC_DOMAINCFG_RO (0x80U << 24)
#define APLIC_DOMAINCFG_IE BIT(8, U)
#define APLIC_DOMAINCFG_DM BIT(2, U)
+#define APLIC_DOMAINCFG_BE BIT(0, U)
#define APLIC_SOURCECFG_SM_INACTIVE 0x0
#define APLIC_SOURCECFG_SM_DETACH 0x1
diff --git a/xen/arch/riscv/include/asm/intc.h
b/xen/arch/riscv/include/asm/intc.h
index a4e678fad9..8757288852 100644
--- a/xen/arch/riscv/include/asm/intc.h
+++ b/xen/arch/riscv/include/asm/intc.h
@@ -17,6 +17,7 @@ enum intc_variant {
struct cpu_user_regs;
struct irq_desc;
struct kernel_info;
+struct vcpu;
struct intc_info {
enum intc_variant hw_variant;
@@ -53,8 +54,19 @@ struct vintc_init_ops {
int (*make_domu_dt_node)(struct kernel_info *kinfo);
};
+struct vintc_ops {
+ /* Initialize some vINTC-related stuff for a vCPU */
+ int (*vcpu_init)(struct vcpu *v);
+
+ /* Deinitialize some vINTC-related stuff for a vCPU */
+ void (*vcpu_deinit)(struct vcpu *v);
+};
+
struct vintc {
+ /* Callbacks invoked during domain construction only. */
const struct vintc_init_ops *init_ops;
+ /* Runtime callbacks used for the lifetime of the guest. */
+ const struct vintc_ops *ops;
};
void intc_preinit(void);
diff --git a/xen/arch/riscv/include/asm/vaplic.h
b/xen/arch/riscv/include/asm/vaplic.h
new file mode 100644
index 0000000000..96080bfbc2
--- /dev/null
+++ b/xen/arch/riscv/include/asm/vaplic.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * xen/arch/riscv/vaplic.c
+ *
+ * Virtual RISC-V Advanced Platform-Level Interrupt Controller support
+ *
+ * Copyright (c) Microchip.
+ */
+
+#ifndef ASM__RISCV__VAPLIC_H
+#define ASM__RISCV__VAPLIC_H
+
+#include <xen/kernel.h>
+#include <xen/types.h>
+
+#include <asm/intc.h>
+
+struct domain;
+
+#define to_vaplic(d) container_of((d)->arch.vintc, struct vaplic, vintc)
+
+struct vaplic_regs {
+ uint32_t domaincfg;
+};
+
+struct vaplic {
+ struct vintc vintc;
+ struct vaplic_regs regs;
+};
+
+int domain_vaplic_init(struct domain *d);
+void domain_vaplic_deinit(struct domain *d);
+
+#endif /* ASM__RISCV__VAPLIC_H */
diff --git a/xen/arch/riscv/vaplic.c b/xen/arch/riscv/vaplic.c
new file mode 100644
index 0000000000..c9f188b989
--- /dev/null
+++ b/xen/arch/riscv/vaplic.c
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * xen/arch/riscv/vaplic.c
+ *
+ * Virtual RISC-V Advanced Platform-Level Interrupt Controller support
+ *
+ * Copyright (c) Microchip.
+ * Copyright (c) Vates
+ */
+
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/xvmalloc.h>
+
+#include <asm/aia.h>
+#include <asm/imsic.h>
+#include <asm/intc.h>
+#include <asm/vaplic.h>
+
+#include "aplic-priv.h"
+
+static const struct vintc_ops vintc_ops = {
+ .vcpu_init = vcpu_imsic_init,
+ .vcpu_deinit = vcpu_imsic_deinit,
+};
+
+int domain_vaplic_init(struct domain *d)
+{
+ struct vaplic *vaplic = xvzalloc(struct vaplic);
+
+ if ( !vaplic )
+ return -ENOMEM;
+
+ d->arch.vintc = &vaplic->vintc;
+ d->arch.vintc->ops = &vintc_ops;
+
+ vaplic->regs.domaincfg = APLIC_DOMAINCFG_RO;
+
+ return 0;
+}
+
+void domain_vaplic_deinit(struct domain *d)
+{
+ struct vaplic *vaplic;
+
+ if ( !d->arch.vintc )
+ return;
+
+ vaplic = to_vaplic(d);
+ d->arch.vintc = NULL;
+ xvfree(vaplic);
+}
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |