[PATCH v2 15/39] xen/riscv: add IMSIC vCPU context switch handlers
Oleksii Kurochko <[email protected]>
| Newsgroups | gmane.comp.emulators.xen.devel |
|---|---|
| Message-ID | <867af892784c295296cdf63e0371fa1b7ed7a1e7.1787838835.git.oleksii.kurochko@gmail.com> |
IMSIC state currently needs to track only which physical CPU owns a vCPU's
IMSIC guest interrupt file, as the CPU id is part of the physical address
the file is mapped at.
Add imsic_ctxt_switch_from() to record that CPU when a vCPU is switched
out. A vCPU running on the s/w VS-file has no h/w file bound to a CPU, so
there is nothing to record for it. The recorded value stays unused until
vCPU migration support, which needs it to find the file to move away from,
is added later.
imsic_ctxt_switch_to() has nothing to do: by the time a vCPU is switched
in, VGEIN is already assigned to it and its guest interrupt file is already
mapped. Work is only required once a vCPU can move to a different CPU,
which means recalculating VGEIN and remapping the file; that is handled
separately by the vCPU migration patches.
Install both as the ctxt_switch_{from,to} hooks of struct vintc_ops. MSI
delivery is the only mode Xen supports ( aplic_init() panics on an APLIC
without an "msi-parent" property, and a guest's domaincfg.DM reads back as
a fixed one) so the vAPLIC state to save and restore is always the IMSIC
one and no vAPLIC-level forwarder is needed. Being indirect call targets,
both handlers get cf_check.
Co-developed-by: Romain Caritey <[email protected]>
Signed-off-by: Oleksii Kurochko <[email protected]>
---
Changes in v2:
- s/imsic_state_{save,restore}/imsic_ctxt_switch_{from,to}: the old names
suggested saving and restoring register state, which isn't what these
functions do.
- Fix the comment in imsic_ctxt_switch_from(): it explained the
->vsfile_cpu sentinel while the code checks ->guest_file_id.
- Adapt to ->vsfile_cpu holding v->processor instead of a hartid.
- Add cf_check as both are indirect call targets now.
- Fold in the vintc_ops hook-up, which was a separate patch in v1. It no
longer adds vaplic_state_{save,restore}() forwarders: the
BUG_ON("unimplemented") path in them was unreachable and
has_msi_support() was an MMIO read done on every context switch.
- Drop the claim that the not-yet-supported case is guarded by a BUG_ON();
there is no such BUG_ON().
- Update the subject accordingly.
---
---
xen/arch/riscv/imsic.c | 23 +++++++++++++++++++++++
xen/arch/riscv/include/asm/imsic.h | 3 +++
xen/arch/riscv/vaplic.c | 7 +++++++
3 files changed, 33 insertions(+)
diff --git a/xen/arch/riscv/imsic.c b/xen/arch/riscv/imsic.c
index ad0a220edac2..3787f270d8e3 100644
--- a/xen/arch/riscv/imsic.c
+++ b/xen/arch/riscv/imsic.c
@@ -20,6 +20,7 @@
#include <xen/init.h>
#include <xen/libfdt/libfdt.h>
#include <xen/macros.h>
+#include <xen/rwlock.h>
#include <xen/sched.h>
#include <xen/smp.h>
#include <xen/spinlock.h>
@@ -342,6 +343,28 @@ static int __init imsic_parse_node(const struct dt_device_node *node,
return 0;
}
+void cf_check imsic_ctxt_switch_from(struct vcpu *v)
+{
+ struct vimsic_state *imsic_state = v->arch.vimsic_state;
+ unsigned long flags;
+
+ /*
+ * A vCPU using the s/w IMSIC VS-file (guest_file_id == 0) has no h/w
+ * VS-file bound to a physical CPU, so there is no location to record.
+ */
+ if ( !vcpu_guest_file_id(v) )
+ return;
+
+ write_lock_irqsave(&imsic_state->vsfile_lock, flags);
+ imsic_state->vsfile_cpu = v->processor;
+ write_unlock_irqrestore(&imsic_state->vsfile_lock, flags);
+}
+
+void cf_check imsic_ctxt_switch_to(struct vcpu *v)
+{
+ /* Nothing to do */
+}
+
int cf_check vcpu_imsic_init(struct vcpu *v)
{
struct vimsic_state *imsic_state;
diff --git a/xen/arch/riscv/include/asm/imsic.h b/xen/arch/riscv/include/asm/imsic.h
index 93f9e44c7d2c..73129c3c9ea7 100644
--- a/xen/arch/riscv/include/asm/imsic.h
+++ b/xen/arch/riscv/include/asm/imsic.h
@@ -109,4 +109,7 @@ unsigned int vcpu_guest_file_id(const struct vcpu *v);
int vimsic_make_domu_dt_node(struct kernel_info *kinfo, unsigned int *phandle);
+void imsic_ctxt_switch_from(struct vcpu *v);
+void imsic_ctxt_switch_to(struct vcpu *v);
+
#endif /* ASM_RISCV_IMSIC_H */
diff --git a/xen/arch/riscv/vaplic.c b/xen/arch/riscv/vaplic.c
index 8726f7203d6e..6c60fe2baf0c 100644
--- a/xen/arch/riscv/vaplic.c
+++ b/xen/arch/riscv/vaplic.c
@@ -422,6 +422,13 @@ static const struct mmio_handler_ops vaplic_mmio_ops = {
static const struct vintc_ops vintc_ops = {
.vcpu_init = vcpu_imsic_init,
.vcpu_deinit = vcpu_imsic_deinit,
+ /*
+ * MSI delivery is the only supported mode: aplic_init() panics on an
+ * APLIC without an "msi-parent", so the vAPLIC state to save and restore
+ * is always the IMSIC one.
+ */
+ .ctxt_switch_from = imsic_ctxt_switch_from,
+ .ctxt_switch_to = imsic_ctxt_switch_to,
};
int domain_vaplic_init(struct domain *d)
--
2.55.0