|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] p2m: change write_p2m_entry to return an error code
commit 0d0f4d78e5d1e9ecc57e53253437a4d4b09f9d20
Author: Roger Pau Monne <roger.pau@xxxxxxxxxx>
AuthorDate: Wed Feb 27 12:09:03 2019 +0100
Commit: George Dunlap <george.dunlap@xxxxxxxxxx>
CommitDate: Thu Feb 28 17:35:22 2019 +0000
p2m: change write_p2m_entry to return an error code
This is in preparation for also changing p2m_entry_modify to return an
error code.
No functional change intended.
Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
Reviewed-by: Wei Liu <wei.liu2@xxxxxxxxxx>
Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx>
---
xen/arch/x86/mm/hap/hap.c | 4 ++-
xen/arch/x86/mm/hap/nested_hap.c | 4 ++-
xen/arch/x86/mm/p2m-pt.c | 77 ++++++++++++++++++++++++++++++++--------
xen/arch/x86/mm/paging.c | 12 ++++---
xen/arch/x86/mm/shadow/common.c | 4 ++-
xen/arch/x86/mm/shadow/none.c | 7 ++--
xen/arch/x86/mm/shadow/private.h | 6 ++--
xen/include/asm-x86/p2m.h | 4 +--
xen/include/asm-x86/paging.h | 8 ++---
9 files changed, 92 insertions(+), 34 deletions(-)
diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
index 2db7f2c04a..fdf77c59a5 100644
--- a/xen/arch/x86/mm/hap/hap.c
+++ b/xen/arch/x86/mm/hap/hap.c
@@ -708,7 +708,7 @@ static void hap_update_paging_modes(struct vcpu *v)
put_gfn(d, cr3_gfn);
}
-static void
+static int
hap_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, l1_pgentry_t *p,
l1_pgentry_t new, unsigned int level)
{
@@ -746,6 +746,8 @@ hap_write_p2m_entry(struct p2m_domain *p2m, unsigned long
gfn, l1_pgentry_t *p,
if ( flush_nestedp2m )
p2m_flush_nestedp2m(d);
+
+ return 0;
}
static unsigned long hap_gva_to_gfn_real_mode(
diff --git a/xen/arch/x86/mm/hap/nested_hap.c b/xen/arch/x86/mm/hap/nested_hap.c
index d2a07a5c79..abe5958a52 100644
--- a/xen/arch/x86/mm/hap/nested_hap.c
+++ b/xen/arch/x86/mm/hap/nested_hap.c
@@ -71,7 +71,7 @@
/* NESTED VIRT P2M FUNCTIONS */
/********************************************/
-void
+int
nestedp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
l1_pgentry_t *p, l1_pgentry_t new, unsigned int level)
{
@@ -87,6 +87,8 @@ nestedp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned
long gfn,
flush_tlb_mask(p2m->dirty_cpumask);
paging_unlock(d);
+
+ return 0;
}
/********************************************/
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 04e9d81cf6..4a531fdf9d 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -184,6 +184,8 @@ p2m_next_level(struct p2m_domain *p2m, void **table,
l1_pgentry_t *p2m_entry, new_entry;
void *next;
unsigned int flags;
+ int rc;
+ mfn_t mfn;
if ( !(p2m_entry = p2m_find_entry(*table, gfn_remainder, gfn,
shift, max)) )
@@ -194,7 +196,7 @@ p2m_next_level(struct p2m_domain *p2m, void **table,
/* PoD/paging: Not present doesn't imply empty. */
if ( !flags )
{
- mfn_t mfn = p2m_alloc_ptp(p2m, level);
+ mfn = p2m_alloc_ptp(p2m, level);
if ( mfn_eq(mfn, INVALID_MFN) )
return -ENOMEM;
@@ -202,13 +204,14 @@ p2m_next_level(struct p2m_domain *p2m, void **table,
new_entry = l1e_from_mfn(mfn, P2M_BASE_FLAGS | _PAGE_RW);
p2m_add_iommu_flags(&new_entry, level,
IOMMUF_readable|IOMMUF_writable);
- p2m->write_p2m_entry(p2m, gfn, p2m_entry, new_entry, level + 1);
+ rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, new_entry, level + 1);
+ if ( rc )
+ goto error;
}
else if ( flags & _PAGE_PSE )
{
/* Split superpages pages into smaller ones. */
unsigned long pfn = l1e_get_pfn(*p2m_entry);
- mfn_t mfn;
l1_pgentry_t *l1_entry;
unsigned int i;
@@ -250,14 +253,23 @@ p2m_next_level(struct p2m_domain *p2m, void **table,
{
new_entry = l1e_from_pfn(pfn | (i << ((level - 1) *
PAGETABLE_ORDER)),
flags);
- p2m->write_p2m_entry(p2m, gfn, l1_entry + i, new_entry, level);
+ rc = p2m->write_p2m_entry(p2m, gfn, l1_entry + i, new_entry,
level);
+ if ( rc )
+ {
+ unmap_domain_page(l1_entry);
+ goto error;
+ }
}
unmap_domain_page(l1_entry);
new_entry = l1e_from_mfn(mfn, P2M_BASE_FLAGS | _PAGE_RW);
- p2m_add_iommu_flags(&new_entry, level,
IOMMUF_readable|IOMMUF_writable);
- p2m->write_p2m_entry(p2m, gfn, p2m_entry, new_entry, level + 1);
+ p2m_add_iommu_flags(&new_entry, level,
+ IOMMUF_readable|IOMMUF_writable);
+ rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, new_entry,
+ level + 1);
+ if ( rc )
+ goto error;
}
else
ASSERT(flags & _PAGE_PRESENT);
@@ -268,6 +280,12 @@ p2m_next_level(struct p2m_domain *p2m, void **table,
*table = next;
return 0;
+
+ error:
+ ASSERT(rc && mfn_valid(mfn));
+ ASSERT_UNREACHABLE();
+ p2m_free_ptp(p2m, mfn_to_page(mfn));
+ return rc;
}
/*
@@ -321,7 +339,12 @@ static int p2m_pt_set_recalc_range(struct p2m_domain *p2m,
if ( (l1e_get_flags(e) & _PAGE_PRESENT) && !needs_recalc(l1, e) )
{
set_recalc(l1, e);
- p2m->write_p2m_entry(p2m, first_gfn, pent, e, level);
+ err = p2m->write_p2m_entry(p2m, first_gfn, pent, e, level);
+ if ( err )
+ {
+ ASSERT_UNREACHABLE();
+ goto out;
+ }
}
first_gfn += 1UL << (i * PAGETABLE_ORDER);
}
@@ -392,14 +415,24 @@ static int do_recalc(struct p2m_domain *p2m, unsigned
long gfn)
!needs_recalc(l1, ent) )
{
set_recalc(l1, ent);
- p2m->write_p2m_entry(p2m, gfn - remainder, &ptab[i],
- ent, level);
+ err = p2m->write_p2m_entry(p2m, gfn - remainder, &ptab[i],
+ ent, level);
+ if ( err )
+ {
+ ASSERT_UNREACHABLE();
+ goto out;
+ }
}
remainder -= 1UL << ((level - 1) * PAGETABLE_ORDER);
}
smp_wmb();
clear_recalc(l1, e);
- p2m->write_p2m_entry(p2m, gfn, pent, e, level + 1);
+ err = p2m->write_p2m_entry(p2m, gfn, pent, e, level + 1);
+ if ( err )
+ {
+ ASSERT_UNREACHABLE();
+ goto out;
+ }
}
unmap_domain_page((void *)((unsigned long)pent & PAGE_MASK));
}
@@ -444,7 +477,8 @@ static int do_recalc(struct p2m_domain *p2m, unsigned long
gfn)
}
else
clear_recalc(l1, e);
- p2m->write_p2m_entry(p2m, gfn, pent, e, level + 1);
+ err = p2m->write_p2m_entry(p2m, gfn, pent, e, level + 1);
+ ASSERT(!err);
}
out:
@@ -595,8 +629,10 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t
mfn,
if ( entry_content.l1 != 0 )
p2m_add_iommu_flags(&entry_content, 0, iommu_pte_flags);
- p2m->write_p2m_entry(p2m, gfn, p2m_entry, entry_content, 3);
+ rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, entry_content, 3);
/* NB: paging_write_p2m_entry() handles tlb flushes properly */
+ if ( rc )
+ goto out;
}
else
{
@@ -633,8 +669,10 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t
mfn,
p2m_add_iommu_flags(&entry_content, 0, iommu_pte_flags);
/* level 1 entry */
- p2m->write_p2m_entry(p2m, gfn, p2m_entry, entry_content, 1);
+ rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, entry_content, 1);
/* NB: paging_write_p2m_entry() handles tlb flushes properly */
+ if ( rc )
+ goto out;
}
else if ( page_order == PAGE_ORDER_2M )
{
@@ -669,8 +707,10 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t
mfn,
if ( entry_content.l1 != 0 )
p2m_add_iommu_flags(&entry_content, 0, iommu_pte_flags);
- p2m->write_p2m_entry(p2m, gfn, p2m_entry, entry_content, 2);
+ rc = p2m->write_p2m_entry(p2m, gfn, p2m_entry, entry_content, 2);
/* NB: paging_write_p2m_entry() handles tlb flushes properly */
+ if ( rc )
+ goto out;
}
/* Track the highest gfn for which we have ever had a valid mapping */
@@ -894,8 +934,15 @@ static void p2m_pt_change_entry_type_global(struct
p2m_domain *p2m,
if ( (l1e_get_flags(e) & _PAGE_PRESENT) &&
!needs_recalc(l1, e) )
{
+ int rc;
+
set_recalc(l1, e);
- p2m->write_p2m_entry(p2m, gfn, &tab[i], e, 4);
+ rc = p2m->write_p2m_entry(p2m, gfn, &tab[i], e, 4);
+ if ( rc )
+ {
+ ASSERT_UNREACHABLE();
+ break;
+ }
++changed;
}
gfn += 1UL << (L4_PAGETABLE_SHIFT - PAGE_SHIFT);
diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c
index e6ed3006fe..21db3eceb6 100644
--- a/xen/arch/x86/mm/paging.c
+++ b/xen/arch/x86/mm/paging.c
@@ -932,18 +932,22 @@ void paging_update_nestedmode(struct vcpu *v)
}
#endif
-void paging_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
- l1_pgentry_t *p, l1_pgentry_t new,
- unsigned int level)
+int paging_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
+ l1_pgentry_t *p, l1_pgentry_t new,
+ unsigned int level)
{
struct domain *d = p2m->domain;
struct vcpu *v = current;
+ int rc = 0;
+
if ( v->domain != d )
v = d->vcpu ? d->vcpu[0] : NULL;
if ( likely(v && paging_mode_enabled(d) && paging_get_hostmode(v) != NULL)
)
- paging_get_hostmode(v)->write_p2m_entry(p2m, gfn, p, new, level);
+ rc = paging_get_hostmode(v)->write_p2m_entry(p2m, gfn, p, new, level);
else
safe_write_pte(p, new);
+
+ return rc;
}
int paging_set_allocation(struct domain *d, unsigned int pages, bool
*preempted)
diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
index de7abf7150..c818112360 100644
--- a/xen/arch/x86/mm/shadow/common.c
+++ b/xen/arch/x86/mm/shadow/common.c
@@ -3176,7 +3176,7 @@ static void sh_unshadow_for_p2m_change(struct domain *d,
unsigned long gfn,
}
}
-void
+int
shadow_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
l1_pgentry_t *p, l1_pgentry_t new,
unsigned int level)
@@ -3211,6 +3211,8 @@ shadow_write_p2m_entry(struct p2m_domain *p2m, unsigned
long gfn,
#endif
paging_unlock(d);
+
+ return 0;
}
/**************************************************************************/
diff --git a/xen/arch/x86/mm/shadow/none.c b/xen/arch/x86/mm/shadow/none.c
index 316002771d..a70888bd98 100644
--- a/xen/arch/x86/mm/shadow/none.c
+++ b/xen/arch/x86/mm/shadow/none.c
@@ -60,11 +60,12 @@ static void _update_paging_modes(struct vcpu *v)
ASSERT_UNREACHABLE();
}
-static void _write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
- l1_pgentry_t *p, l1_pgentry_t new,
- unsigned int level)
+static int _write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
+ l1_pgentry_t *p, l1_pgentry_t new,
+ unsigned int level)
{
ASSERT_UNREACHABLE();
+ return -EOPNOTSUPP;
}
static const struct paging_mode sh_paging_none = {
diff --git a/xen/arch/x86/mm/shadow/private.h b/xen/arch/x86/mm/shadow/private.h
index 0aaed1edfc..580ef3e29e 100644
--- a/xen/arch/x86/mm/shadow/private.h
+++ b/xen/arch/x86/mm/shadow/private.h
@@ -372,9 +372,9 @@ extern int sh_remove_write_access(struct domain *d, mfn_t
readonly_mfn,
unsigned long fault_addr);
/* Functions that atomically write PT/P2M entries and update state */
-void shadow_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
- l1_pgentry_t *p, l1_pgentry_t new,
- unsigned int level);
+int shadow_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
+ l1_pgentry_t *p, l1_pgentry_t new,
+ unsigned int level);
/* Update all the things that are derived from the guest's CR0/CR3/CR4.
* Called to initialize paging structures if the paging mode
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 834d49d2d4..f4ec2becbd 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -265,7 +265,7 @@ struct p2m_domain {
unsigned long last_gfn);
void (*memory_type_changed)(struct p2m_domain *p2m);
- void (*write_p2m_entry)(struct p2m_domain *p2m,
+ int (*write_p2m_entry)(struct p2m_domain *p2m,
unsigned long gfn, l1_pgentry_t *p,
l1_pgentry_t new, unsigned int
level);
long (*audit_p2m)(struct p2m_domain *p2m);
@@ -837,7 +837,7 @@ void p2m_flush_nestedp2m(struct domain *d);
/* Flushes the np2m specified by np2m_base (if it exists) */
void np2m_flush_base(struct vcpu *v, unsigned long np2m_base);
-void nestedp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
+int nestedp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
l1_pgentry_t *p, l1_pgentry_t new, unsigned int level);
/*
diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h
index 7ec09d7b11..18a7eaeca4 100644
--- a/xen/include/asm-x86/paging.h
+++ b/xen/include/asm-x86/paging.h
@@ -124,7 +124,7 @@ struct paging_mode {
void (*update_cr3 )(struct vcpu *v, int do_locking,
bool noflush);
void (*update_paging_modes )(struct vcpu *v);
- void (*write_p2m_entry )(struct p2m_domain *p2m,
+ int (*write_p2m_entry )(struct p2m_domain *p2m,
unsigned long gfn,
l1_pgentry_t *p, l1_pgentry_t new,
unsigned int level);
@@ -340,9 +340,9 @@ static inline void safe_write_pte(l1_pgentry_t *p,
l1_pgentry_t new)
* we are writing. */
struct p2m_domain;
-void paging_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
- l1_pgentry_t *p, l1_pgentry_t new,
- unsigned int level);
+int paging_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
+ l1_pgentry_t *p, l1_pgentry_t new,
+ unsigned int level);
/*
* Called from the guest to indicate that the a process is being
--
generated by git-patchbot for /home/xen/git/xen.git#staging
_______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |