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@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
This commit is contained in:
Roger Pau Monne authored and George Dunlap committed 2019-02-28 17:35:22 +00:00
1 parent c7a4c088ad
commit 0d0f4d78e5
9 files changed
+92 -34

No files matched your search

+3 -1
View File
@@ -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(
+3 -1
View File
@@ -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;
}
/********************************************/
+62 -15
View File
@@ -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);
+8 -4
View File
@@ -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)
+3 -1
View File
@@ -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;
}
/**************************************************************************/
+4 -3
View File
@@ -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 = {
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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);
/*
+4 -4
View File
@@ -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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.