mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86/P2M: consolidate handling of types not requiring a valid MFN
As noted regarding the mixture of checks in p2m_pt_set_entry(),
introduce a new P2M type group allowing to be used everywhere we
just care about accepting operations with either a valid MFN or a type
permitting to be used without (valid) MFN.
Note that p2m_mmio_dm is not included in P2M_NO_MFN_TYPES, as for the
intended purpose that one ought to be treated similar to p2m_invalid
(perhaps the two should ultimately get folded anyway).
Note further that PoD superpages now get INVALID_MFN used when creating
page table entries (was _mfn(0) before).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
master commit: c35eefded2
master date: 2015-11-20 12:38:33 +0100
This commit is contained in:
1 parent
1e3e944746
commit
303fdadbe5
4 files changed
+17
-12
No files matched your search
@@ -772,8 +772,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
|
||||
ept_entry = table + (gfn_remainder >> (i * EPT_TABLE_ORDER));
|
||||
}
|
||||
|
||||
if ( mfn_valid(mfn_x(mfn)) || direct_mmio || p2m_is_paged(p2mt) ||
|
||||
(p2mt == p2m_ram_paging_in) )
|
||||
if ( mfn_valid(mfn_x(mfn)) || p2m_allows_invalid_mfn(p2mt) )
|
||||
{
|
||||
int emt = epte_get_entry_emt(p2m->domain, gfn, mfn,
|
||||
i * EPT_TABLE_ORDER, &ipat, direct_mmio);
|
||||
|
||||
@@ -729,7 +729,7 @@ p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn)
|
||||
}
|
||||
|
||||
/* Try to remove the page, restoring old mapping if it fails. */
|
||||
p2m_set_entry(p2m, gfn, _mfn(0), PAGE_ORDER_2M,
|
||||
p2m_set_entry(p2m, gfn, _mfn(INVALID_MFN), PAGE_ORDER_2M,
|
||||
p2m_populate_on_demand, p2m->default_access);
|
||||
|
||||
/* Make none of the MFNs are used elsewhere... for example, mapped
|
||||
@@ -845,7 +845,7 @@ p2m_pod_zero_check(struct p2m_domain *p2m, unsigned long *gfns, int count)
|
||||
}
|
||||
|
||||
/* Try to remove the page, restoring old mapping if it fails. */
|
||||
p2m_set_entry(p2m, gfns[i], _mfn(0), PAGE_ORDER_4K,
|
||||
p2m_set_entry(p2m, gfns[i], _mfn(INVALID_MFN), PAGE_ORDER_4K,
|
||||
p2m_populate_on_demand, p2m->default_access);
|
||||
|
||||
/* See if the page was successfully unmapped. (Allow one refcount
|
||||
@@ -1046,7 +1046,7 @@ p2m_pod_demand_populate(struct p2m_domain *p2m, unsigned long gfn,
|
||||
* NOTE: In a fine-grained p2m locking scenario this operation
|
||||
* may need to promote its locking from gfn->1g superpage
|
||||
*/
|
||||
p2m_set_entry(p2m, gfn_aligned, _mfn(0), PAGE_ORDER_2M,
|
||||
p2m_set_entry(p2m, gfn_aligned, _mfn(INVALID_MFN), PAGE_ORDER_2M,
|
||||
p2m_populate_on_demand, p2m->default_access);
|
||||
return 0;
|
||||
}
|
||||
@@ -1128,7 +1128,7 @@ remap_and_retry:
|
||||
* need promoting the gfn lock from gfn->2M superpage */
|
||||
gfn_aligned = (gfn>>order)<<order;
|
||||
for(i=0; i<(1<<order); i++)
|
||||
p2m_set_entry(p2m, gfn_aligned+i, _mfn(0), PAGE_ORDER_4K,
|
||||
p2m_set_entry(p2m, gfn_aligned + i, _mfn(INVALID_MFN), PAGE_ORDER_4K,
|
||||
p2m_populate_on_demand, p2m->default_access);
|
||||
if ( tb_init_done )
|
||||
{
|
||||
@@ -1183,8 +1183,8 @@ guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
|
||||
}
|
||||
|
||||
/* Now, actually do the two-way mapping */
|
||||
rc = p2m_set_entry(p2m, gfn, _mfn(0), order, p2m_populate_on_demand,
|
||||
p2m->default_access);
|
||||
rc = p2m_set_entry(p2m, gfn, _mfn(INVALID_MFN), order,
|
||||
p2m_populate_on_demand, p2m->default_access);
|
||||
if ( rc == 0 )
|
||||
{
|
||||
pod_lock(p2m);
|
||||
|
||||
@@ -573,7 +573,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
|
||||
}
|
||||
|
||||
ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct);
|
||||
l3e_content = mfn_valid(mfn)
|
||||
l3e_content = mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt)
|
||||
? l3e_from_pfn(mfn_x(mfn),
|
||||
p2m_type_to_flags(p2mt, mfn) | _PAGE_PSE)
|
||||
: l3e_empty();
|
||||
@@ -609,8 +609,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
|
||||
p2m_get_iommu_flags(p2m_flags_to_type(l1e_get_flags(*p2m_entry)));
|
||||
old_mfn = l1e_get_pfn(*p2m_entry);
|
||||
|
||||
if ( mfn_valid(mfn) || (p2mt == p2m_mmio_direct)
|
||||
|| p2m_is_paging(p2mt) )
|
||||
if ( mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt) )
|
||||
entry_content = p2m_l1e_from_pfn(mfn_x(mfn),
|
||||
p2m_type_to_flags(p2mt, mfn));
|
||||
else
|
||||
@@ -646,7 +645,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
|
||||
}
|
||||
|
||||
ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct);
|
||||
if ( mfn_valid(mfn) || p2m_is_pod(p2mt) )
|
||||
if ( mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt) )
|
||||
l2e_content = l2e_from_pfn(mfn_x(mfn),
|
||||
p2m_type_to_flags(p2mt, mfn) |
|
||||
_PAGE_PSE);
|
||||
|
||||
@@ -141,6 +141,11 @@ typedef unsigned int p2m_query_t;
|
||||
| p2m_to_mask(p2m_ram_logdirty) )
|
||||
#define P2M_SHARED_TYPES (p2m_to_mask(p2m_ram_shared))
|
||||
|
||||
/* Valid types not necessarily associated with a (valid) MFN. */
|
||||
#define P2M_INVALID_MFN_TYPES (P2M_POD_TYPES \
|
||||
| p2m_to_mask(p2m_mmio_direct) \
|
||||
| P2M_PAGING_TYPES)
|
||||
|
||||
/* Broken type: the frame backing this pfn has failed in hardware
|
||||
* and must not be touched. */
|
||||
#define P2M_BROKEN_TYPES (p2m_to_mask(p2m_ram_broken))
|
||||
@@ -171,6 +176,8 @@ typedef unsigned int p2m_query_t;
|
||||
(P2M_RAM_TYPES | P2M_GRANT_TYPES | \
|
||||
p2m_to_mask(p2m_map_foreign)))
|
||||
|
||||
#define p2m_allows_invalid_mfn(t) (p2m_to_mask(t) & P2M_INVALID_MFN_TYPES)
|
||||
|
||||
typedef enum {
|
||||
p2m_host,
|
||||
p2m_nested,
|
||||
|
||||