Introdce struct arch_vcpu to hold RISC-V vCPU-specific state.
The structure contains:
- Guest-visible CSR state, used to save and restore vCPU execution
state across context switches. hstatus isn't added here as it is
already part of cpu_user_regs struct.
- Callee-saved registers used to preserve Xen’s own execution context
when switching between vCPU stacks.
It is going to be used in the following way (pseudocode):
context_switch(prev_vcpu, next_vcpu):
...
/* Switch from previous stack to the next stack. */
__context_switch(prev_vcpu, next_vcpu);
...
schedule_tail(prev_vcpu):
Save and restore vCPU's CSRs.
The Xen-saved context allows __context_switch() to switch execution
from the previous vCPU’s stack to the next vCPU’s stack and later resume
execution on the original stack when switching back.
During vCPU creation, the Xen-saved context is going to be initialized
with:
- SP pointing to the newly allocated vCPU stack
- RA pointing to a helper that performs final vCPU setup before
transferring control to the guest
After the first execution of __context_switch(), RA naturally points to
the instruction following the call site, and the remaining callee-saved
registers contain the Xen register state at the time of the switch.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in v2:
- Drop hstatus from struct arch_vcpu as it is stored in struct cpu_user_regs
which will be stored on top of vCPU's stack.
- Drop the comment above ra in xen_saved_context struct as it is potentially
misleading.
---
xen/arch/riscv/include/asm/domain.h | 57 ++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 2 deletions(-)
diff --git a/xen/arch/riscv/include/asm/domain.h b/xen/arch/riscv/include/asm/domain.h
index 316e7c6c8448..0d9b4c4b525e 100644
--- a/xen/arch/riscv/include/asm/domain.h
+++ b/xen/arch/riscv/include/asm/domain.h
@@ -22,9 +22,62 @@ struct hvm_domain
struct arch_vcpu_io {
};
-struct arch_vcpu {
+struct arch_vcpu
+{
struct vcpu_vmid vmid;
-};
+
+ /*
+ * Callee saved registers for Xen's state deep in the callframe used to
+ * switch from prev's stack to the next's stack during context switch.
+ */
+ struct
+ {
+ register_t s0;
+ register_t s1;
+ register_t s2;
+ register_t s3;
+ register_t s4;
+ register_t s5;
+ register_t s6;
+ register_t s7;
+ register_t s8;
+ register_t s9;
+ register_t s10;
+ register_t s11;
+ register_t sp;
+ register_t gp;
+ register_t ra;
+ } xen_saved_context;
+
+ /* CSRs */
+ register_t hedeleg;
+ register_t hideleg;
+ register_t hvip;
+ register_t hip;
+ register_t hie;
+ register_t hgeie;
+ register_t henvcfg;
+ register_t hcounteren;
+ register_t htimedelta;
+ register_t htval;
+ register_t htinst;
+ register_t hstateen0;
+#ifdef CONFIG_RISCV_32
+ register_t henvcfgh;
+ register_t htimedeltah;
+#endif
+
+ /* VCSRs */
+ register_t vsstatus;
+ register_t vsip;
+ register_t vsie;
+ register_t vstvec;
+ register_t vsscratch;
+ register_t vscause;
+ register_t vstval;
+ register_t vsatp;
+ register_t vsepc;
+} __cacheline_aligned;
struct paging_domain {
spinlock_t lock;
--
2.52.0