|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 3/3] xen/riscv: implement p2m_ctx_switch_{to,from}_state()
Introduce functions required to perform a p2m context switch during
a vCPU context switch.
As no mechanism is provided to atomically change vsatp and hgatp
together. Hence, to prevent speculative execution causing one
guest’s VS-stage translations to be cached under another guest’s
VMID, world-switch code should zero vsatp in p2m_ctx_swith_from(),
then construct new hgatp and write the new vsatp value in
p2m_ctx_switch_to().
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
xen/arch/riscv/include/asm/p2m.h | 4 ++
xen/arch/riscv/p2m.c | 81 ++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
diff --git a/xen/arch/riscv/include/asm/p2m.h b/xen/arch/riscv/include/asm/p2m.h
index f63b5dec99b1..1d8c97326565 100644
--- a/xen/arch/riscv/include/asm/p2m.h
+++ b/xen/arch/riscv/include/asm/p2m.h
@@ -255,6 +255,10 @@ static inline bool p2m_is_locked(const struct p2m_domain
*p2m)
struct page_info *p2m_get_page_from_gfn(struct p2m_domain *p2m, gfn_t gfn,
p2m_type_t *t);
+
+void p2m_ctx_switch_from(struct vcpu *p);
+void p2m_ctx_switch_to(struct vcpu *n);
+
#endif /* ASM__RISCV__P2M_H */
/*
diff --git a/xen/arch/riscv/p2m.c b/xen/arch/riscv/p2m.c
index 0abeb374c110..af68497c4200 100644
--- a/xen/arch/riscv/p2m.c
+++ b/xen/arch/riscv/p2m.c
@@ -1434,3 +1434,84 @@ struct page_info *p2m_get_page_from_gfn(struct
p2m_domain *p2m, gfn_t gfn,
return get_page(page, p2m->domain) ? page : NULL;
}
+
+void p2m_ctx_switch_from(struct vcpu *p)
+{
+ /*
+ * No mechanism is provided to atomically change vsatp and hgatp
+ * together. Hence, to prevent speculative execution causing one
+ * guest’s VS-stage translations to be cached under another guest’s
+ * VMID, world-switch code should zero vsatp, then swap hgatp, then
+ * finally write the new vsatp value.
+ */
+ p->arch.vsatp = csr_read(CSR_VSATP);
+ csr_write(CSR_VSATP, 0);
+
+ /*
+ * No need for VS-stage TLB flush here:
+ * Changing satp.MODE from Bare to other modes and vice versa also
+ * takes effect immediately, without the need to execute an
+ * SFENCE.VMA instruction.
+ * Note that VSATP is just VS-mode’s version of SATP, so the mentioned
+ * above should be true for VSATP.
+ */
+
+ /*
+ * Nothing to do with HGATP as it is constructed each time when
+ * p2m_ctx_switch_to() is called.
+ */
+}
+
+void p2m_ctx_switch_to(struct vcpu *n)
+{
+ struct vcpu_vmid *p_vmid = &n->arch.vmid;
+ uint16_t old_vmid, new_vmid;
+ bool need_flush;
+
+ if ( is_idle_vcpu(n) )
+ return;
+
+ old_vmid = p_vmid->vmid;
+ need_flush = vmid_handle_vmenter(p_vmid);
+ new_vmid = p_vmid->vmid;
+
+#ifdef P2M_DEBUG
+ printk(XENLOG_INFO, "%pv: oldvmid(%d) new_vmid(%d), need_flush(%d)\n",
+ n, old_vmid, new_vmid, need_flush);
+#endif
+
+ csr_write(CSR_HGATP, construct_hgatp(p2m_get_hostp2m(current->domain),
+ new_vmid));
+
+ if ( unlikely(need_flush) )
+ local_hfence_gvma_all();
+
+ /*
+ * According to the RISC-V specification, speculation can happen
+ * during an update of hgatp and vsatp:
+ * No mechanism is provided to atomically change vsatp and hgatp
+ * together. Hence, to prevent speculative execution causing one
+ * guest’s VS-stage translations to be cached under another guest’s
+ * VMID, world-switch code should zero vsatp, then swap hgatp, then
+ * finally write the new vsatp value. Similarly, if henvcfg.PBMTE
+ * need be world-switched, it should be switched after zeroing vsatp
+ * but before writing the new vsatp value, obviating the need to
+ * execute an HFENCE.VVMA instruction.
+ * So just flush TLBs for VS-Stage and G-stage after both of regs are
+ * touched.
+ */
+ flush_tlb_guest_local();
+
+ /*
+ * The vsatp register is a VSXLEN-bit read/write register that is
+ * VS-mode’s version of supervisor register satp, so the following is
+ * true for VSATP registers:
+ * Changing satp.MODE from Bare to other modes and vice versa also takes
+ * effect immediately, without the need to execute an SFENCE.VMA
+ * instruction. Likewise, changes to satp.ASID take effect immediately.
+ * Considering the mentioned above and that VS-stage TLB flush has been
+ * already done there is no need to flush VS-stage TLB after an update
+ * of VSATP from Bare mode to what is written in `n->arch.vsatp`.
+ */
+ csr_write(CSR_VSATP, n->arch.vsatp);
+}
--
2.52.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |