|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/pagewalk: Consistently use guest_walk_*() helpers for translation
commit 9dc1e0cd81ee469d638d1962a92d9b4bd2972bfa
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Tue May 24 15:46:01 2016 +0100
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Thu Mar 9 17:01:05 2017 +0000
x86/pagewalk: Consistently use guest_walk_*() helpers for translation
hap_p2m_ga_to_gfn() and sh_page_fault() currently use guest_l1e_get_gfn() to
obtain the translation of a pagewalk. This is conceptually wrong (the
semantics of gw.l1e is an internal detail), and will actually be wrong when
PSE36 superpage support is fixed. Switch them to using guest_walk_to_gfn().
guest_walk_tables() also uses guest_l1e_get_gfn(), and is updated for
consistency.
Take the opportunity to const-correct the walk_t parameter of the
guest_walk_to_*() helpers, and implement guest_walk_to_gpa() in terms of
guest_walk_to_gfn() to avoid duplicating the actual translation calculation.
While editing guest_walk_to_gpa(), fix a latent bug by causing it to return
INVALID_PADDR rather than 0 for a failed translation, as 0 is also a valid
successful result. The sole caller, sh_page_fault(), has already confirmed
that the translation is valid, so this doesn't cause a behavioural change.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Tim Deegan <tim@xxxxxxx>
Acked-by: George Dunlap <george.dunlap@xxxxxxxxxx>
---
xen/arch/x86/mm/guest_walk.c | 2 +-
xen/arch/x86/mm/hap/guest_walk.c | 2 +-
xen/arch/x86/mm/shadow/multi.c | 2 +-
xen/include/asm-x86/guest_pt.h | 19 +++++++++----------
4 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c
index 9d11e3b..8187226 100644
--- a/xen/arch/x86/mm/guest_walk.c
+++ b/xen/arch/x86/mm/guest_walk.c
@@ -438,7 +438,7 @@ set_ad:
/* If this guest has a restricted physical address space then the
* target GFN must fit within it. */
- if ( !(rc & _PAGE_PRESENT) && !gfn_valid(d, guest_l1e_get_gfn(gw->l1e)) )
+ if ( !(rc & _PAGE_PRESENT) && !gfn_valid(d, guest_walk_to_gfn(gw)) )
rc |= _PAGE_INVALID_BITS;
return rc;
diff --git a/xen/arch/x86/mm/hap/guest_walk.c b/xen/arch/x86/mm/hap/guest_walk.c
index 569a495..313f82f 100644
--- a/xen/arch/x86/mm/hap/guest_walk.c
+++ b/xen/arch/x86/mm/hap/guest_walk.c
@@ -98,7 +98,7 @@ unsigned long hap_p2m_ga_to_gfn(GUEST_PAGING_LEVELS)(
/* Interpret the answer */
if ( missing == 0 )
{
- gfn_t gfn = guest_l1e_get_gfn(gw.l1e);
+ gfn_t gfn = guest_walk_to_gfn(&gw);
struct page_info *page;
page = get_page_from_gfn_p2m(p2m->domain, p2m, gfn_x(gfn), &p2mt,
NULL, P2M_ALLOC | P2M_UNSHARE);
diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c
index 68ef35c..7ea9d81 100644
--- a/xen/arch/x86/mm/shadow/multi.c
+++ b/xen/arch/x86/mm/shadow/multi.c
@@ -3104,7 +3104,7 @@ static int sh_page_fault(struct vcpu *v,
}
/* What mfn is the guest trying to access? */
- gfn = guest_l1e_get_gfn(gw.l1e);
+ gfn = guest_walk_to_gfn(&gw);
gmfn = get_gfn(d, gfn, &p2mt);
if ( shadow_mode_refcounts(d) &&
diff --git a/xen/include/asm-x86/guest_pt.h b/xen/include/asm-x86/guest_pt.h
index 0bf6cf9..6a06ba0 100644
--- a/xen/include/asm-x86/guest_pt.h
+++ b/xen/include/asm-x86/guest_pt.h
@@ -241,8 +241,7 @@ struct guest_pagetable_walk
/* Given a walk_t, translate the gw->va into the guest's notion of the
* corresponding frame number. */
-static inline gfn_t
-guest_walk_to_gfn(walk_t *gw)
+static inline gfn_t guest_walk_to_gfn(const walk_t *gw)
{
if ( !(guest_l1e_get_flags(gw->l1e) & _PAGE_PRESENT) )
return INVALID_GFN;
@@ -251,19 +250,19 @@ guest_walk_to_gfn(walk_t *gw)
/* Given a walk_t, translate the gw->va into the guest's notion of the
* corresponding physical address. */
-static inline paddr_t
-guest_walk_to_gpa(walk_t *gw)
+static inline paddr_t guest_walk_to_gpa(const walk_t *gw)
{
- if ( !(guest_l1e_get_flags(gw->l1e) & _PAGE_PRESENT) )
- return 0;
- return ((paddr_t)gfn_x(guest_l1e_get_gfn(gw->l1e)) << PAGE_SHIFT) +
- (gw->va & ~PAGE_MASK);
+ gfn_t gfn = guest_walk_to_gfn(gw);
+
+ if ( gfn_eq(gfn, INVALID_GFN) )
+ return INVALID_PADDR;
+
+ return (gfn_x(gfn) << PAGE_SHIFT) | (gw->va & ~PAGE_MASK);
}
/* Given a walk_t from a successful walk, return the page-order of the
* page or superpage that the virtual address is in. */
-static inline unsigned int
-guest_walk_to_page_order(walk_t *gw)
+static inline unsigned int guest_walk_to_page_order(const walk_t *gw)
{
/* This is only valid for successful walks - otherwise the
* PSE bits might be invalid. */
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |