|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 12/42] xen/riscv: save and restore vsiselect on vCPU context switch
vsiselect isn't saved/restored, yet the guest writes it directly
(VS-mode accesses to siselect go to vsiselect). After a context switch a
vCPU therefore sees the selector left by the previous vCPU on that hart:
a guest writing siselect, getting descheduled, then accessing sireg hits
a register it never selected, and it can observe another guest's
selector value.
When Smstateen is implemented, access to vsiselect and vsireg is gated by
hstateen0.CSRIND (bit 60, SMSTATEEN0_SVSLCT in Xen's headers), and
v->arch.hstateen0 holds the bits vcpu_csr_init() ended up with. A clear
bit there covers the two cases in which the CSR has to be skipped:
- Xen didn't hand the guest access to it, so the guest can't have changed
the CSR and there is no state to preserve;
- M-mode denied the state altogether. Smstateen makes a bit which is zero
in mstateen0 read-only zero in hstateen0, and a zero bit in mstateen0
traps accesses from every privilege mode less privileged than M-mode,
HS-mode included, so Xen couldn't even read the CSR to save it.
Without Smstateen no bit controls access to the CSR, so it is saved and
restored whenever Ssaia is available.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
Reviewed-by: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>
Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
---
Changes in v4:
- Reword the commit message.
- Add Reviewed-by: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>.
- Add Acked-by: Jan Beulich <jbeulich@xxxxxxxx>.
---
Changes in v3:
- Rename from "xen/riscv: save and restore AIA state on vCPU context
switch", as only vsiselect is switched now.
- Save and restore only vsiselect: drop hviprio1 and hviprio2.
- Rename vcpu_has_aia_state() to vcpu_can_access_vsiselect() and drop
its hstateen0 bit argument.
- Move switching vsie to uint64_t and csr_{read,write}64() to "xen/riscv:
implement vCPU context switching".
- Update the commit message.
---
Changes in v2:
- New patch.
---
---
xen/arch/riscv/domain.c | 28 ++++++++++++++++++++++++++++
xen/arch/riscv/include/asm/domain.h | 1 +
2 files changed, 29 insertions(+)
diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c
index 9feeaa59b887..089d968ace27 100644
--- a/xen/arch/riscv/domain.c
+++ b/xen/arch/riscv/domain.c
@@ -329,6 +329,28 @@ int arch_domain_create(struct domain *d,
return rc;
}
+/*
+ * vsiselect is a per-hart CSR, but a guest changes it on its own: when V=1,
+ * VS-mode accesses to siselect are really accesses to vsiselect. Hence it is
+ * part of the vCPU context.
+ *
+ * When Smstateen is implemented, hstateen0.CSRIND (SMSTATEEN0_SVSLCT) gates
+ * that access, and a bit staying clear in v->arch.hstateen0 (see
+ * vcpu_csr_init()) means either that the guest was never given access to the
+ * CSR, and so can't have changed it, or that M-mode denied the state
+ * altogether, in which case the CSR can't be accessed from HS-mode either.
+ */
+static bool vcpu_can_access_vsiselect(const struct vcpu *v)
+{
+ if ( !riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ssaia) )
+ return false;
+
+ if ( !riscv_isa_extension_available(NULL, RISCV_ISA_EXT_smstateen) )
+ return true;
+
+ return v->arch.hstateen0 & SMSTATEEN0_SVSLCT;
+}
+
static void csrs_ctxt_switch_from(struct vcpu *p)
{
/*
@@ -347,6 +369,9 @@ static void csrs_ctxt_switch_from(struct vcpu *p)
p->arch.vscause = csr_read(CSR_VSCAUSE);
p->arch.vstval = csr_read(CSR_VSTVAL);
p->arch.vsepc = csr_read(CSR_VSEPC);
+
+ if ( vcpu_can_access_vsiselect(p) )
+ p->arch.vsiselect = csr_read(CSR_VSISELECT);
}
static void csrs_ctxt_switch_to(struct vcpu *n)
@@ -368,6 +393,9 @@ static void csrs_ctxt_switch_to(struct vcpu *n)
csr_write(CSR_VSCAUSE, n->arch.vscause);
csr_write(CSR_VSTVAL, n->arch.vstval);
csr_write(CSR_VSEPC, n->arch.vsepc);
+
+ if ( vcpu_can_access_vsiselect(n) )
+ csr_write(CSR_VSISELECT, n->arch.vsiselect);
}
static void ctxt_switch_from(struct vcpu *p)
diff --git a/xen/arch/riscv/include/asm/domain.h
b/xen/arch/riscv/include/asm/domain.h
index 63e34c1a11ab..c424e2428f60 100644
--- a/xen/arch/riscv/include/asm/domain.h
+++ b/xen/arch/riscv/include/asm/domain.h
@@ -73,6 +73,7 @@ struct arch_vcpu {
register_t vscause;
register_t vsepc;
uint64_t vsie;
+ register_t vsiselect;
register_t vsscratch;
register_t vsstatus;
register_t vstval;
--
2.56.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |