|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/mm: handle foreign mappings in p2m_entry_modify
commit ce0224bf96a1a1f82391e27b34b5d21d12a757a5
Author: Roger Pau Monne <roger.pau@xxxxxxxxxx>
AuthorDate: Wed Feb 27 12:09:04 2019 +0100
Commit: George Dunlap <george.dunlap@xxxxxxxxxx>
CommitDate: Thu Feb 28 17:36:14 2019 +0000
x86/mm: handle foreign mappings in p2m_entry_modify
So that the specific handling can be removed from
atomic_write_ept_entry and be shared with npt and shadow code.
This commit also removes the check that prevent non-ept PVH dom0 from
mapping foreign pages.
Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>
Reviewed-by: Wei Liu <wei.liu2@xxxxxxxxxx>
Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx>
---
xen/arch/x86/mm/hap/hap.c | 11 +++++++--
xen/arch/x86/mm/p2m-ept.c | 55 ++++-------------------------------------
xen/arch/x86/mm/p2m-pt.c | 7 ------
xen/arch/x86/mm/shadow/common.c | 11 +++++++--
xen/include/asm-x86/p2m.h | 34 ++++++++++++++++++++++---
5 files changed, 53 insertions(+), 65 deletions(-)
diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
index fdf77c59a5..412a442b6a 100644
--- a/xen/arch/x86/mm/hap/hap.c
+++ b/xen/arch/x86/mm/hap/hap.c
@@ -715,6 +715,7 @@ hap_write_p2m_entry(struct p2m_domain *p2m, unsigned long
gfn, l1_pgentry_t *p,
struct domain *d = p2m->domain;
uint32_t old_flags;
bool_t flush_nestedp2m = 0;
+ int rc;
/* We know always use the host p2m here, regardless if the vcpu
* is in host or guest mode. The vcpu can be in guest mode by
@@ -735,8 +736,14 @@ hap_write_p2m_entry(struct p2m_domain *p2m, unsigned long
gfn, l1_pgentry_t *p,
&& perms_strictly_increased(old_flags, l1e_get_flags(new)) );
}
- p2m_entry_modify(p2m, p2m_flags_to_type(l1e_get_flags(new)),
- p2m_flags_to_type(old_flags), level);
+ rc = p2m_entry_modify(p2m, p2m_flags_to_type(l1e_get_flags(new)),
+ p2m_flags_to_type(old_flags), l1e_get_mfn(new),
+ l1e_get_mfn(*p), level);
+ if ( rc )
+ {
+ paging_unlock(d);
+ return rc;
+ }
safe_write_pte(p, new);
if ( old_flags & _PAGE_PRESENT )
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index 0ece6608cb..e3044bee2e 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -50,60 +50,15 @@ static int atomic_write_ept_entry(struct p2m_domain *p2m,
ept_entry_t *entryptr, ept_entry_t new,
int level)
{
- int rc;
- unsigned long oldmfn = mfn_x(INVALID_MFN);
- bool_t check_foreign = (new.mfn != entryptr->mfn ||
- new.sa_p2mt != entryptr->sa_p2mt);
-
- if ( level )
- {
- ASSERT(!is_epte_superpage(&new) || !p2m_is_foreign(new.sa_p2mt));
- write_atomic(&entryptr->epte, new.epte);
- return 0;
- }
-
- if ( unlikely(p2m_is_foreign(new.sa_p2mt)) )
- {
- rc = -EINVAL;
- if ( !is_epte_present(&new) )
- goto out;
-
- if ( check_foreign )
- {
- struct domain *fdom;
-
- if ( !mfn_valid(_mfn(new.mfn)) )
- goto out;
-
- rc = -ESRCH;
- fdom = page_get_owner(mfn_to_page(_mfn(new.mfn)));
- if ( fdom == NULL )
- goto out;
+ int rc = p2m_entry_modify(p2m, new.sa_p2mt, entryptr->sa_p2mt,
+ _mfn(new.mfn), _mfn(entryptr->mfn), level);
- /* get refcount on the page */
- rc = -EBUSY;
- if ( !get_page(mfn_to_page(_mfn(new.mfn)), fdom) )
- goto out;
- }
- }
-
- if ( unlikely(p2m_is_foreign(entryptr->sa_p2mt)) && check_foreign )
- oldmfn = entryptr->mfn;
-
- p2m_entry_modify(p2m, new.sa_p2mt, entryptr->sa_p2mt, level);
+ if ( rc )
+ return rc;
write_atomic(&entryptr->epte, new.epte);
- if ( unlikely(oldmfn != mfn_x(INVALID_MFN)) )
- put_page(mfn_to_page(_mfn(oldmfn)));
-
- rc = 0;
-
- out:
- if ( rc )
- gdprintk(XENLOG_ERR, "epte o:%"PRIx64" n:%"PRIx64" rc:%d\n",
- entryptr->epte, new.epte, rc);
- return rc;
+ return 0;
}
static void ept_p2m_type_to_flags(struct p2m_domain *p2m, ept_entry_t *entry,
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 4a531fdf9d..e62bafcfb7 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -574,13 +574,6 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t
mfn,
__trace_var(TRC_MEM_SET_P2M_ENTRY, 0, sizeof(t), &t);
}
- if ( unlikely(p2m_is_foreign(p2mt)) )
- {
- /* hvm fixme: foreign types are only supported on ept at present */
- gdprintk(XENLOG_WARNING, "Unimplemented foreign p2m type.\n");
- return -EINVAL;
- }
-
/* Carry out any eventually pending earlier changes first. */
rc = do_recalc(p2m, gfn);
if ( rc < 0 )
diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
index c818112360..025071a163 100644
--- a/xen/arch/x86/mm/shadow/common.c
+++ b/xen/arch/x86/mm/shadow/common.c
@@ -3182,6 +3182,7 @@ shadow_write_p2m_entry(struct p2m_domain *p2m, unsigned
long gfn,
unsigned int level)
{
struct domain *d = p2m->domain;
+ int rc;
paging_lock(d);
@@ -3190,8 +3191,14 @@ shadow_write_p2m_entry(struct p2m_domain *p2m, unsigned
long gfn,
if ( likely(d->arch.paging.shadow.total_pages != 0) )
sh_unshadow_for_p2m_change(d, gfn, p, new, level);
- p2m_entry_modify(p2m, p2m_flags_to_type(l1e_get_flags(new)),
- p2m_flags_to_type(l1e_get_flags(*p)), level);
+ rc = p2m_entry_modify(p2m, p2m_flags_to_type(l1e_get_flags(new)),
+ p2m_flags_to_type(l1e_get_flags(*p)),
+ l1e_get_mfn(new), l1e_get_mfn(*p), level);
+ if ( rc )
+ {
+ paging_unlock(d);
+ return rc;
+ }
/* Update the entry with new content */
safe_write_pte(p, new);
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index f4ec2becbd..2801a8ccca 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -932,11 +932,14 @@ int p2m_set_ioreq_server(struct domain *d, unsigned int
flags,
struct hvm_ioreq_server *p2m_get_ioreq_server(struct domain *d,
unsigned int *flags);
-static inline void p2m_entry_modify(struct p2m_domain *p2m, p2m_type_t nt,
- p2m_type_t ot, unsigned int level)
+static inline int p2m_entry_modify(struct p2m_domain *p2m, p2m_type_t nt,
+ p2m_type_t ot, mfn_t nfn, mfn_t ofn,
+ unsigned int level)
{
- if ( level != 1 || nt == ot )
- return;
+ BUG_ON(level > 1 && (nt == p2m_ioreq_server || nt == p2m_map_foreign));
+
+ if ( level != 1 || (nt == ot && mfn_eq(nfn, ofn)) )
+ return 0;
switch ( nt )
{
@@ -948,6 +951,18 @@ static inline void p2m_entry_modify(struct p2m_domain
*p2m, p2m_type_t nt,
p2m->ioreq.entry_count++;
break;
+ case p2m_map_foreign:
+ if ( !mfn_valid(nfn) )
+ {
+ ASSERT_UNREACHABLE();
+ return -EINVAL;
+ }
+
+ if ( !page_get_owner_and_reference(mfn_to_page(nfn)) )
+ return -EBUSY;
+
+ break;
+
default:
break;
}
@@ -959,9 +974,20 @@ static inline void p2m_entry_modify(struct p2m_domain
*p2m, p2m_type_t nt,
p2m->ioreq.entry_count--;
break;
+ case p2m_map_foreign:
+ if ( !mfn_valid(ofn) )
+ {
+ ASSERT_UNREACHABLE();
+ return -EINVAL;
+ }
+ put_page(mfn_to_page(ofn));
+ break;
+
default:
break;
}
+
+ return 0;
}
#endif /* _XEN_ASM_X86_P2M_H */
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |