[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 14/39] xen/riscv: add IMSIC vCPU context switch handlers



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. Nothing reads the recorded value yet.

imsic_ctxt_switch_to() has nothing to do: switching a vCPU in on the CPU
which owns its guest interrupt file needs no IMSIC update. Only a move to
another CPU does (a new VGEIN and a remapped file), and that isn't part of
the context switch.

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 the only one vAPLIC emulates, 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 <Romain.Caritey@xxxxxxxxxxxxx>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
Changes in v3:
 - Drop the reference to aplic_init() from the comment on the
   .ctxt_switch_{from,to} initialization in vaplic.c.
 - Use p and n instead of v as the arguments of
   imsic_ctxt_switch_{from,to}(), as the other context switch helpers do.
 - Update the commit message.
---
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            |  6 ++++++
 3 files changed, 32 insertions(+)

diff --git a/xen/arch/riscv/imsic.c b/xen/arch/riscv/imsic.c
index 402b2f14f591..d633f59db20d 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 *p)
+{
+    struct vimsic_state *imsic_state = p->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(p) )
+        return;
+
+    write_lock_irqsave(&imsic_state->vsfile_lock, flags);
+    imsic_state->vsfile_cpu = p->processor;
+    write_unlock_irqrestore(&imsic_state->vsfile_lock, flags);
+}
+
+void cf_check imsic_ctxt_switch_to(struct vcpu *n)
+{
+    /* 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 6baadc008d81..5463fb4c31b2 100644
--- a/xen/arch/riscv/include/asm/imsic.h
+++ b/xen/arch/riscv/include/asm/imsic.h
@@ -96,4 +96,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 *p);
+void imsic_ctxt_switch_to(struct vcpu *n);
+
 #endif /* ASM_RISCV_IMSIC_H */
diff --git a/xen/arch/riscv/vaplic.c b/xen/arch/riscv/vaplic.c
index ea4b0dc88951..4d87fdb5be42 100644
--- a/xen/arch/riscv/vaplic.c
+++ b/xen/arch/riscv/vaplic.c
@@ -456,6 +456,12 @@ 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, 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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.