|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 18/42] xen/riscv: resolve the faulting guest physical address
Recover the guest physical address from htval and stval. On a guest-page
fault to hypervisor, htval holds the guest physical address shifted
right by 2, so that an address wider than HSXLEN fits, and stval holds
the faulting guest virtual address. Shift htval back left by 2 and take
the two low bits from stval. htval is first converted to paddr_t, then
shifted: a guest physical address is 34 bits wide on RV32 with Sv32x4,
so shifting the XLEN-wide register itself would drop the top two bits.
However, there are two cases to distinguish when recovering the
faulting GPA:
- Explicit memory access: the two least significant bits of stval are
the same as those of the guest physical address.
- Implicit memory access for VS-stage translation: the two least
significant bits of the guest physical address (GPA[1:0]) are zero.
These two cases can be distinguished using the value provided in
register htinst.
stval needs no check against an ISA extension: a guest-page fault writes it
with the faulting guest virtual address regardless. Sstvala would not be the
right thing to test for either (it covers stval across every trap type
which writes it, a wider guarantee than what is needed here).
htval does need one. The H extension lets an implementation write it with
either the faulting address or zero, so without Shtvala a zero htval cannot
be told apart from a genuine fault on guest physical address 0-3, and the
address has to be recovered by decoding the access and walking the VS-stage
page tables in software instead. That is left as a TODO; until it is
written, such a fault crashes the domain rather than acting on an address
which may not be the one which faulted.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
Reviewed-by: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>
---
Changes in v4:
- Update the commit message.
- Add Reviewed-by: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>.
---
Changes in v3:
- Update the commit message.
- Drop panic() inside resolve_faulting_gpa() and return -EOPNOTSUPP +
printk_once().
- Leave the comment above resolve_faulting_gpa() alone: it already says
what the function does since "xen/riscv: add guest page fault handling
stub".
- Document in docs/misc/riscv/booting.txt why Shtvala is recommended.
---
Changes in v2:
- New patch.
---
---
docs/misc/riscv/booting.txt | 11 +++++++++++
xen/arch/riscv/emulate.c | 27 ++++++++++++++++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/docs/misc/riscv/booting.txt b/docs/misc/riscv/booting.txt
index 14212ed62f99..283aa49a3b64 100644
--- a/docs/misc/riscv/booting.txt
+++ b/docs/misc/riscv/booting.txt
@@ -35,3 +35,14 @@ Other extensions recognised by Xen are listed in
riscv_isa_ext[] in
xen/arch/riscv/cpufeature.c. Xen uses them when present, but they are not
needed to boot. The second column of that table says whether the extension
is also exposed to guests.
+
+Some of them are nevertheless recommended, as functionality depends on them:
+- Shtvala:
+ Guarantees that htval is written with the faulting guest physical address
+ on a guest-page fault. Without it an implementation may write zero instead,
+ which can't be told apart from a genuine fault on guest physical addresses
+ 0-3. Xen needs that address to emulate a guest's MMIO accesses; recovering
+ it in software (by walking the guest's VS-stage page tables) isn't
+ implemented, so on such hardware a guest-page fault reported with a zero
+ htval crashes the domain. See resolve_faulting_gpa() in
+ xen/arch/riscv/emulate.c.
diff --git a/xen/arch/riscv/emulate.c b/xen/arch/riscv/emulate.c
index de8c09fe1505..d661ef0bf204 100644
--- a/xen/arch/riscv/emulate.c
+++ b/xen/arch/riscv/emulate.c
@@ -9,6 +9,7 @@
#include <xen/sched.h>
#include <xen/types.h>
+#include <asm/cpufeature.h>
#include <asm/csr.h>
#include <asm/current.h>
#include <asm/emulate.h>
@@ -58,7 +59,31 @@ static bool htinst_is_pseudo(unsigned long htinst)
*/
static int resolve_faulting_gpa(struct guest_fault *gf)
{
- return -EOPNOTSUPP;
+ /*
+ * A zero htval is either a genuine fault on guest physical address 0-3, or
+ * an implementation which does not report the address at all; only Shtvala
+ * tells the two apart.
+ *
+ * TODO: where it is absent, recover the address in software rather than
+ * giving up.
+ */
+ if ( !gf->htval &&
+ !riscv_isa_extension_available(NULL, RISCV_ISA_EXT_shtvala) )
+ {
+ printk_once(XENLOG_WARNING
+ "Shtvala isn't supported by h/w; s/w VS-stage walk
required\n");
+ return -EOPNOTSUPP;
+ }
+
+ /*
+ * htval does not carry the two low bits of the address: for an explicit
+ * access they are those of the faulting guest virtual address in stval,
+ * and for an implicit access made for VS-stage translation they are zero.
+ */
+ gf->gpa = ((paddr_t)gf->htval << 2) |
+ (htinst_is_pseudo(gf->htinst) ? 0 : (gf->stval & 3));
+
+ return 0;
}
static int emulate_load(const struct guest_fault *gf)
--
2.56.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |