mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
PoD (populate-on-demand) memory 1/9: Add a p2m query type.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
This commit is contained in:
1 parent
9976adf65a
commit
74e14a7867
4 files changed
+41
-19
No files matched your search
@@ -274,7 +274,8 @@ out:
|
||||
}
|
||||
|
||||
/* Read ept p2m entries */
|
||||
static mfn_t ept_get_entry(struct domain *d, unsigned long gfn, p2m_type_t *t)
|
||||
static mfn_t ept_get_entry(struct domain *d, unsigned long gfn, p2m_type_t *t,
|
||||
p2m_query_t q)
|
||||
{
|
||||
ept_entry_t *table =
|
||||
map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table)));
|
||||
@@ -359,9 +360,10 @@ static uint64_t ept_get_entry_content(struct domain *d, unsigned long gfn)
|
||||
return content;
|
||||
}
|
||||
|
||||
static mfn_t ept_get_entry_current(unsigned long gfn, p2m_type_t *t)
|
||||
static mfn_t ept_get_entry_current(unsigned long gfn, p2m_type_t *t,
|
||||
p2m_query_t q)
|
||||
{
|
||||
return ept_get_entry(current->domain, gfn, t);
|
||||
return ept_get_entry(current->domain, gfn, t, q);
|
||||
}
|
||||
|
||||
void ept_change_entry_emt_with_range(struct domain *d, unsigned long start_gfn,
|
||||
|
||||
@@ -345,7 +345,8 @@ p2m_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
|
||||
}
|
||||
|
||||
static mfn_t
|
||||
p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t)
|
||||
p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t,
|
||||
p2m_query_t q)
|
||||
{
|
||||
mfn_t mfn;
|
||||
paddr_t addr = ((paddr_t)gfn) << PAGE_SHIFT;
|
||||
@@ -436,7 +437,8 @@ p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t)
|
||||
}
|
||||
|
||||
/* Read the current domain's p2m table (through the linear mapping). */
|
||||
static mfn_t p2m_gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t)
|
||||
static mfn_t p2m_gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t,
|
||||
p2m_query_t q)
|
||||
{
|
||||
mfn_t mfn = _mfn(INVALID_MFN);
|
||||
p2m_type_t p2mt = p2m_mmio_dm;
|
||||
|
||||
@@ -49,7 +49,7 @@ gfn_to_paddr(gfn_t gfn)
|
||||
|
||||
/* Override gfn_to_mfn to work with gfn_t */
|
||||
#undef gfn_to_mfn
|
||||
#define gfn_to_mfn(d, g, t) _gfn_to_mfn((d), gfn_x(g), (t))
|
||||
#define gfn_to_mfn(d, g, t) _gfn_to_mfn_type((d), gfn_x(g), (t), p2m_alloc)
|
||||
|
||||
|
||||
/* Types of the guest's page tables and access functions for them */
|
||||
|
||||
+31
-13
@@ -66,6 +66,12 @@ typedef enum {
|
||||
p2m_mmio_direct = 5, /* Read/write mapping of genuine MMIO area */
|
||||
} p2m_type_t;
|
||||
|
||||
typedef enum {
|
||||
p2m_query = 0, /* Do not populate a PoD entries */
|
||||
p2m_alloc = 1, /* Automatically populate PoD entries */
|
||||
p2m_guest = 2, /* Guest demand-fault; implies alloc */
|
||||
} p2m_query_t;
|
||||
|
||||
/* We use bitmaps and maks to handle groups of types */
|
||||
#define p2m_to_mask(_t) (1UL << (_t))
|
||||
|
||||
@@ -105,9 +111,11 @@ struct p2m_domain {
|
||||
mfn_t mfn, unsigned int page_order,
|
||||
p2m_type_t p2mt);
|
||||
mfn_t (*get_entry )(struct domain *d, unsigned long gfn,
|
||||
p2m_type_t *p2mt);
|
||||
p2m_type_t *p2mt,
|
||||
p2m_query_t q);
|
||||
mfn_t (*get_entry_current)(unsigned long gfn,
|
||||
p2m_type_t *p2mt);
|
||||
p2m_type_t *p2mt,
|
||||
p2m_query_t q);
|
||||
void (*change_entry_type_global)(struct domain *d,
|
||||
p2m_type_t ot,
|
||||
p2m_type_t nt);
|
||||
@@ -123,23 +131,26 @@ static inline p2m_type_t p2m_flags_to_type(unsigned long flags)
|
||||
return (flags >> 9) & 0x7;
|
||||
}
|
||||
|
||||
/* Read the current domain's p2m table. */
|
||||
static inline mfn_t gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t)
|
||||
/* Read the current domain's p2m table. Do not populate PoD pages. */
|
||||
static inline mfn_t gfn_to_mfn_type_current(unsigned long gfn, p2m_type_t *t,
|
||||
p2m_query_t q)
|
||||
{
|
||||
return current->domain->arch.p2m->get_entry_current(gfn, t);
|
||||
return current->domain->arch.p2m->get_entry_current(gfn, t, q);
|
||||
}
|
||||
|
||||
/* Read another domain's P2M table, mapping pages as we go */
|
||||
/* Read another domain's P2M table, mapping pages as we go.
|
||||
* Do not populate PoD pages. */
|
||||
static inline
|
||||
mfn_t gfn_to_mfn_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t)
|
||||
mfn_t gfn_to_mfn_type_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t,
|
||||
p2m_query_t q)
|
||||
{
|
||||
return d->arch.p2m->get_entry(d, gfn, t);
|
||||
return d->arch.p2m->get_entry(d, gfn, t, q);
|
||||
}
|
||||
|
||||
/* General conversion function from gfn to mfn */
|
||||
#define gfn_to_mfn(d, g, t) _gfn_to_mfn((d), (g), (t))
|
||||
static inline mfn_t _gfn_to_mfn(struct domain *d,
|
||||
unsigned long gfn, p2m_type_t *t)
|
||||
static inline mfn_t _gfn_to_mfn_type(struct domain *d,
|
||||
unsigned long gfn, p2m_type_t *t,
|
||||
p2m_query_t q)
|
||||
{
|
||||
if ( !paging_mode_translate(d) )
|
||||
{
|
||||
@@ -149,11 +160,18 @@ static inline mfn_t _gfn_to_mfn(struct domain *d,
|
||||
return _mfn(gfn);
|
||||
}
|
||||
if ( likely(current->domain == d) )
|
||||
return gfn_to_mfn_current(gfn, t);
|
||||
return gfn_to_mfn_type_current(gfn, t, q);
|
||||
else
|
||||
return gfn_to_mfn_foreign(d, gfn, t);
|
||||
return gfn_to_mfn_type_foreign(d, gfn, t, q);
|
||||
}
|
||||
|
||||
#define gfn_to_mfn(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_alloc)
|
||||
#define gfn_to_mfn_query(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_query)
|
||||
#define gfn_to_mfn_guest(d, g, t) _gfn_to_mfn_type((d), (g), (t), p2m_guest)
|
||||
|
||||
#define gfn_to_mfn_current(g, t) gfn_to_mfn_type_current((g), (t), p2m_alloc)
|
||||
#define gfn_to_mfn_foreign(d, g, t) gfn_to_mfn_type_foreign((d), (g), (t), p2m_alloc)
|
||||
|
||||
/* Compatibility function exporting the old untyped interface */
|
||||
static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gpfn)
|
||||
{
|
||||
|
||||