x86: re-arrange struct page_info members

By combining the overlay fields that are 8 bytes long (on x86-64) into
a union separate from the one used for the 4 byte wide fields, no
unnecessary padding will be inserted while at the same time avoiding
to use __attribute__((__packed__)) on any of the sub-structures (which
risks misaligning structure members without immediately noticing).

Signed-off-by: Jan Beulich <jbeulich@novell.com>
This commit is contained in:
Keir Fraser committed 2009-01-30 11:10:43 +00:00
1 parent 1065734fcb
commit f1e6f665b9
4 files changed
+55 -43

No files matched your search

+14 -14
View File
@@ -1334,7 +1334,7 @@ static inline void trace_shadow_prealloc_unpin(struct domain *d, mfn_t smfn)
/* Convert smfn to gfn */
unsigned long gfn;
ASSERT(mfn_valid(smfn));
gfn = mfn_to_gfn(d, _mfn(mfn_to_shadow_page(smfn)->u.sh.back));
gfn = mfn_to_gfn(d, _mfn(mfn_to_shadow_page(smfn)->v.sh.back));
__trace_var(TRC_SHADOW_PREALLOC_UNPIN, 0/*!tsc*/,
sizeof(gfn), (unsigned char*)&gfn);
}
@@ -1542,7 +1542,7 @@ mfn_t shadow_alloc(struct domain *d,
while ( i != order )
{
i--;
sp->u.sh.order = i;
sp->v.free.order = i;
page_list_add_tail(sp, &d->arch.paging.shadow.freelists[i]);
sp += 1 << i;
}
@@ -1569,7 +1569,7 @@ mfn_t shadow_alloc(struct domain *d,
sp[i].u.sh.type = shadow_type;
sp[i].u.sh.pinned = 0;
sp[i].u.sh.count = 0;
sp[i].u.sh.back = backpointer;
sp[i].v.sh.back = backpointer;
set_next_shadow(&sp[i], NULL);
perfc_incr(shadow_alloc_count);
}
@@ -1629,20 +1629,20 @@ void shadow_free(struct domain *d, mfn_t smfn)
if ( (mfn_x(shadow_page_to_mfn(sp)) & mask) ) {
/* Merge with predecessor block? */
if ( ((sp-mask)->u.sh.type != PGT_none) ||
((sp-mask)->u.sh.order != order) )
((sp-mask)->v.free.order != order) )
break;
sp -= mask;
page_list_del(sp, &d->arch.paging.shadow.freelists[order]);
} else {
/* Merge with successor block? */
if ( ((sp+mask)->u.sh.type != PGT_none) ||
((sp+mask)->u.sh.order != order) )
((sp+mask)->v.free.order != order) )
break;
page_list_del(sp + mask, &d->arch.paging.shadow.freelists[order]);
}
}
sp->u.sh.order = order;
sp->v.free.order = order;
page_list_add_tail(sp, &d->arch.paging.shadow.freelists[order]);
}
@@ -1825,7 +1825,7 @@ static unsigned int sh_set_allocation(struct domain *d,
sp[j].u.sh.count = 0;
sp[j].tlbflush_timestamp = 0; /* Not in any TLB */
}
sp->u.sh.order = order;
sp->v.free.order = order;
page_list_add_tail(sp, &d->arch.paging.shadow.freelists[order]);
}
else if ( d->arch.paging.shadow.total_pages > pages )
@@ -1904,17 +1904,17 @@ static void sh_hash_audit_bucket(struct domain *d, int bucket)
BUG_ON( sp->u.sh.type == 0 );
BUG_ON( sp->u.sh.type > SH_type_max_shadow );
/* Wrong bucket? */
BUG_ON( sh_hash(sp->u.sh.back, sp->u.sh.type) != bucket );
BUG_ON( sh_hash(sp->v.sh.back, sp->u.sh.type) != bucket );
/* Duplicate entry? */
for ( x = next_shadow(sp); x; x = next_shadow(x) )
BUG_ON( x->u.sh.back == sp->u.sh.back &&
BUG_ON( x->v.sh.back == sp->v.sh.back &&
x->u.sh.type == sp->u.sh.type );
/* Follow the backpointer to the guest pagetable */
if ( sp->u.sh.type != SH_type_fl1_32_shadow
&& sp->u.sh.type != SH_type_fl1_pae_shadow
&& sp->u.sh.type != SH_type_fl1_64_shadow )
{
struct page_info *gpg = mfn_to_page(_mfn(sp->u.sh.back));
struct page_info *gpg = mfn_to_page(_mfn(sp->v.sh.back));
/* Bad shadow flags on guest page? */
BUG_ON( !(gpg->shadow_flags & (1<<sp->u.sh.type)) );
/* Bad type count on guest page? */
@@ -1930,7 +1930,7 @@ static void sh_hash_audit_bucket(struct domain *d, int bucket)
{
SHADOW_ERROR("MFN %#"PRpgmfn" shadowed (by %#"PRI_mfn")"
" and not OOS but has typecount %#lx\n",
sp->u.sh.back,
sp->v.sh.back,
mfn_x(shadow_page_to_mfn(sp)),
gpg->u.inuse.type_info);
BUG();
@@ -1944,7 +1944,7 @@ static void sh_hash_audit_bucket(struct domain *d, int bucket)
{
SHADOW_ERROR("MFN %#"PRpgmfn" shadowed (by %#"PRI_mfn")"
" but has typecount %#lx\n",
sp->u.sh.back, mfn_x(shadow_page_to_mfn(sp)),
sp->v.sh.back, mfn_x(shadow_page_to_mfn(sp)),
gpg->u.inuse.type_info);
BUG();
}
@@ -2030,7 +2030,7 @@ mfn_t shadow_hash_lookup(struct vcpu *v, unsigned long n, unsigned int t)
prev = NULL;
while(sp)
{
if ( sp->u.sh.back == n && sp->u.sh.type == t )
if ( sp->v.sh.back == n && sp->u.sh.type == t )
{
/* Pull-to-front if 'sp' isn't already the head item */
if ( unlikely(sp != d->arch.paging.shadow.hash_table[key]) )
@@ -2197,7 +2197,7 @@ void sh_destroy_shadow(struct vcpu *v, mfn_t smfn)
t == SH_type_fl1_64_shadow ||
t == SH_type_monitor_table ||
(is_pv_32on64_vcpu(v) && t == SH_type_l4_64_shadow) ||
(page_get_owner(mfn_to_page(_mfn(sp->u.sh.back)))
(page_get_owner(mfn_to_page(_mfn(sp->v.sh.back)))
== v->domain));
/* The down-shifts here are so that the switch statement is on nice
+14 -14
View File
@@ -974,7 +974,7 @@ static int shadow_set_l2e(struct vcpu *v,
#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
{
struct shadow_page_info *sp = mfn_to_shadow_page(sl1mfn);
mfn_t gl1mfn = _mfn(sp->u.sh.back);
mfn_t gl1mfn = _mfn(sp->v.sh.back);
/* If the shadow is a fl1 then the backpointer contains
the GFN instead of the GMFN, and it's definitely not
@@ -1926,7 +1926,7 @@ void sh_destroy_l4_shadow(struct vcpu *v, mfn_t smfn)
ASSERT(t == SH_type_l4_shadow);
/* Record that the guest page isn't shadowed any more (in this type) */
gmfn = _mfn(mfn_to_shadow_page(smfn)->u.sh.back);
gmfn = _mfn(mfn_to_shadow_page(smfn)->v.sh.back);
delete_shadow_status(v, gmfn, t, smfn);
shadow_demote(v, gmfn, t);
/* Decrement refcounts of all the old entries */
@@ -1955,7 +1955,7 @@ void sh_destroy_l3_shadow(struct vcpu *v, mfn_t smfn)
ASSERT(t == SH_type_l3_shadow);
/* Record that the guest page isn't shadowed any more (in this type) */
gmfn = _mfn(mfn_to_shadow_page(smfn)->u.sh.back);
gmfn = _mfn(mfn_to_shadow_page(smfn)->v.sh.back);
delete_shadow_status(v, gmfn, t, smfn);
shadow_demote(v, gmfn, t);
@@ -1990,7 +1990,7 @@ void sh_destroy_l2_shadow(struct vcpu *v, mfn_t smfn)
#endif
/* Record that the guest page isn't shadowed any more (in this type) */
gmfn = _mfn(mfn_to_shadow_page(smfn)->u.sh.back);
gmfn = _mfn(mfn_to_shadow_page(smfn)->v.sh.back);
delete_shadow_status(v, gmfn, t, smfn);
shadow_demote(v, gmfn, t);
@@ -2020,12 +2020,12 @@ void sh_destroy_l1_shadow(struct vcpu *v, mfn_t smfn)
/* Record that the guest page isn't shadowed any more (in this type) */
if ( t == SH_type_fl1_shadow )
{
gfn_t gfn = _gfn(mfn_to_shadow_page(smfn)->u.sh.back);
gfn_t gfn = _gfn(mfn_to_shadow_page(smfn)->v.sh.back);
delete_fl1_shadow_status(v, gfn, smfn);
}
else
{
mfn_t gmfn = _mfn(mfn_to_shadow_page(smfn)->u.sh.back);
mfn_t gmfn = _mfn(mfn_to_shadow_page(smfn)->v.sh.back);
delete_shadow_status(v, gmfn, t, smfn);
shadow_demote(v, gmfn, t);
}
@@ -2349,7 +2349,7 @@ static int validate_gl1e(struct vcpu *v, void *new_ge, mfn_t sl1mfn, void *se)
result |= shadow_set_l1e(v, sl1p, new_sl1e, sl1mfn);
#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
gl1mfn = _mfn(mfn_to_shadow_page(sl1mfn)->u.sh.back);
gl1mfn = _mfn(mfn_to_shadow_page(sl1mfn)->v.sh.back);
if ( mfn_valid(gl1mfn)
&& mfn_is_out_of_sync(gl1mfn) )
{
@@ -2968,7 +2968,7 @@ static int sh_page_fault(struct vcpu *v,
sizeof(sl2e)) != 0)
|| !(shadow_l2e_get_flags(sl2e) & _PAGE_PRESENT)
|| !mfn_valid(gl1mfn = _mfn(mfn_to_shadow_page(
shadow_l2e_get_mfn(sl2e))->u.sh.back))
shadow_l2e_get_mfn(sl2e))->v.sh.back))
|| unlikely(mfn_is_out_of_sync(gl1mfn)) )
{
/* Hit the slow path as if there had been no
@@ -3530,7 +3530,7 @@ sh_invlpg(struct vcpu *v, unsigned long va)
#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
/* Check to see if the SL1 is out of sync. */
{
mfn_t gl1mfn = _mfn(mfn_to_shadow_page(sl1mfn)->u.sh.back);
mfn_t gl1mfn = _mfn(mfn_to_shadow_page(sl1mfn)->v.sh.back);
struct page_info *pg = mfn_to_page(gl1mfn);
if ( mfn_valid(gl1mfn)
&& page_is_out_of_sync(pg) )
@@ -3560,7 +3560,7 @@ sh_invlpg(struct vcpu *v, unsigned long va)
}
sl1mfn = shadow_l2e_get_mfn(sl2e);
gl1mfn = _mfn(mfn_to_shadow_page(sl1mfn)->u.sh.back);
gl1mfn = _mfn(mfn_to_shadow_page(sl1mfn)->v.sh.back);
pg = mfn_to_page(gl1mfn);
if ( likely(sh_mfn_is_a_page_table(gl1mfn)
@@ -4887,7 +4887,7 @@ int sh_audit_l1_table(struct vcpu *v, mfn_t sl1mfn, mfn_t x)
int done = 0;
/* Follow the backpointer */
gl1mfn = _mfn(mfn_to_shadow_page(sl1mfn)->u.sh.back);
gl1mfn = _mfn(mfn_to_shadow_page(sl1mfn)->v.sh.back);
#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
/* Out-of-sync l1 shadows can contain anything: just check the OOS hash */
@@ -4977,7 +4977,7 @@ int sh_audit_l2_table(struct vcpu *v, mfn_t sl2mfn, mfn_t x)
int done = 0;
/* Follow the backpointer */
gl2mfn = _mfn(mfn_to_shadow_page(sl2mfn)->u.sh.back);
gl2mfn = _mfn(mfn_to_shadow_page(sl2mfn)->v.sh.back);
#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
/* Only L1's may be out of sync. */
@@ -5026,7 +5026,7 @@ int sh_audit_l3_table(struct vcpu *v, mfn_t sl3mfn, mfn_t x)
int done = 0;
/* Follow the backpointer */
gl3mfn = _mfn(mfn_to_shadow_page(sl3mfn)->u.sh.back);
gl3mfn = _mfn(mfn_to_shadow_page(sl3mfn)->v.sh.back);
#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
/* Only L1's may be out of sync. */
@@ -5073,7 +5073,7 @@ int sh_audit_l4_table(struct vcpu *v, mfn_t sl4mfn, mfn_t x)
int done = 0;
/* Follow the backpointer */
gl4mfn = _mfn(mfn_to_shadow_page(sl4mfn)->u.sh.back);
gl4mfn = _mfn(mfn_to_shadow_page(sl4mfn)->v.sh.back);
#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
/* Only L1's may be out of sync. */
+1 -1
View File
@@ -631,7 +631,7 @@ static inline int sh_get_ref(struct vcpu *v, mfn_t smfn, paddr_t entry_pa)
if ( unlikely(nx >= 1U<<26) )
{
SHADOW_PRINTK("shadow ref overflow, gmfn=%" PRpgmfn " smfn=%lx\n",
sp->u.sh.back, mfn_x(smfn));
sp->v.sh.back, mfn_x(smfn));
return 0;
}
+26 -14
View File
@@ -15,7 +15,7 @@
* 1. 'struct page_info' contains a 'struct page_list_entry list'.
* 2. Provide a PFN_ORDER() macro for accessing the order of a free page.
*/
#define PFN_ORDER(_pfn) ((_pfn)->u.free.order)
#define PFN_ORDER(_pfn) ((_pfn)->v.free.order)
/*
* This definition is solely for the use in struct page_info (and
@@ -59,8 +59,6 @@ struct page_info
/* Page is in use: ((count_info & PGC_count_mask) != 0). */
struct {
/* Owner of this page (NULL if page is anonymous). */
u32 _domain; /* pickled format */
/* Type reference count and various PGT_xxx flags and fields. */
unsigned long type_info;
} inuse;
@@ -70,24 +68,38 @@ struct page_info
unsigned long type:5; /* What kind of shadow is this? */
unsigned long pinned:1; /* Is the shadow pinned? */
unsigned long count:26; /* Reference count */
union {
/* When in use, GMFN of guest page we're a shadow of. */
__mfn_t back;
/* When free, order of the freelist we're on. */
unsigned int order;
};
} sh;
/* Page is on a free list: ((count_info & PGC_count_mask) == 0). */
struct {
/* Order-size of the free chunk this page is the head of. */
u32 order;
/* Mask of possibly-tainted TLBs. */
cpumask_t cpumask;
} free;
} u;
union {
/* Page is in use, but not as a shadow. */
struct {
/* Owner of this page (NULL if page is anonymous). */
u32 _domain; /* pickled format */
} inuse;
/* Page is in use as a shadow. */
struct {
/* GMFN of guest page we're a shadow of. */
__mfn_t back;
} sh;
/* Page is on a free list (including shadow code free lists). */
struct {
/* Order-size of the free chunk this page is the head of. */
unsigned int order;
} free;
} v;
union {
/*
* Timestamp from 'TLB clock', used to avoid extra safety flushes.
@@ -225,10 +237,10 @@ struct page_info
#define SHADOW_OOS_FIXUPS 2
#define page_get_owner(_p) \
((struct domain *)((_p)->u.inuse._domain ? \
mfn_to_virt((_p)->u.inuse._domain) : NULL))
((struct domain *)((_p)->v.inuse._domain ? \
mfn_to_virt((_p)->v.inuse._domain) : NULL))
#define page_set_owner(_p,_d) \
((_p)->u.inuse._domain = (_d) ? virt_to_mfn(_d) : 0)
((_p)->v.inuse._domain = (_d) ? virt_to_mfn(_d) : 0)
#define maddr_get_owner(ma) (page_get_owner(maddr_to_page((ma))))
#define vaddr_get_owner(va) (page_get_owner(virt_to_page((va))))
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.