mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/shadow: drop hash_vcpu_foreach()
The domain based variant is easily usable by shadow_audit_tables(); all that's needed is conversion of the callback functions. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
1 parent
d04a6ee164
commit
39bd52c91e
3 files changed
+18
-70
No files matched your search
@@ -1680,59 +1680,11 @@ bool shadow_hash_delete(struct domain *d, unsigned long n, unsigned int t,
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef int (*hash_vcpu_callback_t)(struct vcpu *v, mfn_t smfn, mfn_t other_mfn);
|
||||
typedef int (*hash_domain_callback_t)(struct domain *d, mfn_t smfn, mfn_t other_mfn);
|
||||
|
||||
#define HASH_CALLBACKS_CHECK(mask) \
|
||||
BUILD_BUG_ON((mask) > (1U << ARRAY_SIZE(callbacks)) - 1)
|
||||
|
||||
static void hash_vcpu_foreach(struct vcpu *v, unsigned int callback_mask,
|
||||
const hash_vcpu_callback_t callbacks[],
|
||||
mfn_t callback_mfn)
|
||||
/* Walk the hash table looking at the types of the entries and
|
||||
* calling the appropriate callback function for each entry.
|
||||
* The mask determines which shadow types we call back for, and the array
|
||||
* of callbacks tells us which function to call.
|
||||
* Any callback may return non-zero to let us skip the rest of the scan.
|
||||
*
|
||||
* WARNING: Callbacks MUST NOT add or remove hash entries unless they
|
||||
* then return non-zero to terminate the scan. */
|
||||
{
|
||||
int i, done = 0;
|
||||
struct domain *d = v->domain;
|
||||
struct page_info *x;
|
||||
|
||||
ASSERT(paging_locked_by_me(d));
|
||||
|
||||
/* Can be called via p2m code &c after shadow teardown. */
|
||||
if ( unlikely(!d->arch.paging.shadow.hash_table) )
|
||||
return;
|
||||
|
||||
/* Say we're here, to stop hash-lookups reordering the chains */
|
||||
ASSERT(d->arch.paging.shadow.hash_walking == 0);
|
||||
d->arch.paging.shadow.hash_walking = 1;
|
||||
|
||||
for ( i = 0; i < SHADOW_HASH_BUCKETS; i++ )
|
||||
{
|
||||
/* WARNING: This is not safe against changes to the hash table.
|
||||
* The callback *must* return non-zero if it has inserted or
|
||||
* deleted anything from the hash (lookups are OK, though). */
|
||||
for ( x = d->arch.paging.shadow.hash_table[i]; x; x = next_shadow(x) )
|
||||
{
|
||||
if ( callback_mask & (1 << x->u.sh.type) )
|
||||
{
|
||||
ASSERT(x->u.sh.type <= SH_type_max_shadow);
|
||||
ASSERT(callbacks[x->u.sh.type] != NULL);
|
||||
done = callbacks[x->u.sh.type](v, page_to_mfn(x),
|
||||
callback_mfn);
|
||||
if ( done ) break;
|
||||
}
|
||||
}
|
||||
if ( done ) break;
|
||||
}
|
||||
d->arch.paging.shadow.hash_walking = 0;
|
||||
}
|
||||
|
||||
static void hash_domain_foreach(struct domain *d,
|
||||
unsigned int callback_mask,
|
||||
const hash_domain_callback_t callbacks[],
|
||||
@@ -3280,7 +3232,7 @@ int shadow_domctl(struct domain *d,
|
||||
void shadow_audit_tables(struct vcpu *v)
|
||||
{
|
||||
/* Dispatch table for getting per-type functions */
|
||||
static const hash_vcpu_callback_t callbacks[SH_type_unused] = {
|
||||
static const hash_domain_callback_t callbacks[SH_type_unused] = {
|
||||
#if SHADOW_AUDIT & (SHADOW_AUDIT_ENTRIES | SHADOW_AUDIT_ENTRIES_FULL)
|
||||
# ifdef CONFIG_HVM
|
||||
[SH_type_l1_32_shadow] = SHADOW_INTERNAL_NAME(sh_audit_l1_table, 2),
|
||||
@@ -3329,7 +3281,7 @@ void shadow_audit_tables(struct vcpu *v)
|
||||
HASH_CALLBACKS_CHECK(SHADOW_AUDIT & (SHADOW_AUDIT_ENTRIES |
|
||||
SHADOW_AUDIT_ENTRIES_FULL)
|
||||
? SHF_page_type_mask : 0);
|
||||
hash_vcpu_foreach(v, mask, callbacks, INVALID_MFN);
|
||||
hash_domain_foreach(v->domain, mask, callbacks, INVALID_MFN);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PV
|
||||
|
||||
@@ -333,32 +333,32 @@ static void sh_audit_gw(struct vcpu *v, const walk_t *gw)
|
||||
if ( mfn_valid(gw->l4mfn)
|
||||
&& mfn_valid((smfn = get_shadow_status(d, gw->l4mfn,
|
||||
SH_type_l4_shadow))) )
|
||||
(void) sh_audit_l4_table(v, smfn, INVALID_MFN);
|
||||
sh_audit_l4_table(d, smfn, INVALID_MFN);
|
||||
if ( mfn_valid(gw->l3mfn)
|
||||
&& mfn_valid((smfn = get_shadow_status(d, gw->l3mfn,
|
||||
SH_type_l3_shadow))) )
|
||||
(void) sh_audit_l3_table(v, smfn, INVALID_MFN);
|
||||
sh_audit_l3_table(d, smfn, INVALID_MFN);
|
||||
#endif /* PAE or 64... */
|
||||
if ( mfn_valid(gw->l2mfn) )
|
||||
{
|
||||
if ( mfn_valid((smfn = get_shadow_status(d, gw->l2mfn,
|
||||
SH_type_l2_shadow))) )
|
||||
(void) sh_audit_l2_table(v, smfn, INVALID_MFN);
|
||||
sh_audit_l2_table(d, smfn, INVALID_MFN);
|
||||
#if GUEST_PAGING_LEVELS >= 4 && defined(CONFIG_PV32)
|
||||
if ( mfn_valid((smfn = get_shadow_status(d, gw->l2mfn,
|
||||
SH_type_l2h_shadow))) )
|
||||
(void) sh_audit_l2_table(v, smfn, INVALID_MFN);
|
||||
sh_audit_l2_table(d, smfn, INVALID_MFN);
|
||||
#endif
|
||||
}
|
||||
if ( mfn_valid(gw->l1mfn)
|
||||
&& mfn_valid((smfn = get_shadow_status(d, gw->l1mfn,
|
||||
SH_type_l1_shadow))) )
|
||||
(void) sh_audit_l1_table(v, smfn, INVALID_MFN);
|
||||
sh_audit_l1_table(d, smfn, INVALID_MFN);
|
||||
else if ( (guest_l2e_get_flags(gw->l2e) & _PAGE_PRESENT)
|
||||
&& (guest_l2e_get_flags(gw->l2e) & _PAGE_PSE)
|
||||
&& mfn_valid(
|
||||
(smfn = get_fl1_shadow_status(d, guest_l2e_get_gfn(gw->l2e)))) )
|
||||
(void) sh_audit_fl1_table(v, smfn, INVALID_MFN);
|
||||
sh_audit_fl1_table(d, smfn, INVALID_MFN);
|
||||
#endif /* SHADOW_AUDIT & SHADOW_AUDIT_ENTRIES */
|
||||
}
|
||||
|
||||
@@ -3920,9 +3920,8 @@ static const char *sh_audit_flags(const struct domain *d, int level,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cf_check sh_audit_l1_table(struct vcpu *v, mfn_t sl1mfn, mfn_t x)
|
||||
int cf_check sh_audit_l1_table(struct domain *d, mfn_t sl1mfn, mfn_t x)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
guest_l1e_t *gl1e, *gp;
|
||||
shadow_l1e_t *sl1e;
|
||||
mfn_t mfn, gmfn, gl1mfn;
|
||||
@@ -3989,7 +3988,7 @@ int cf_check sh_audit_l1_table(struct vcpu *v, mfn_t sl1mfn, mfn_t x)
|
||||
return done;
|
||||
}
|
||||
|
||||
int cf_check sh_audit_fl1_table(struct vcpu *v, mfn_t sl1mfn, mfn_t x)
|
||||
int cf_check sh_audit_fl1_table(struct domain *d, mfn_t sl1mfn, mfn_t x)
|
||||
{
|
||||
guest_l1e_t *gl1e, e;
|
||||
shadow_l1e_t *sl1e;
|
||||
@@ -4015,9 +4014,8 @@ int cf_check sh_audit_fl1_table(struct vcpu *v, mfn_t sl1mfn, mfn_t x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cf_check sh_audit_l2_table(struct vcpu *v, mfn_t sl2mfn, mfn_t x)
|
||||
int cf_check sh_audit_l2_table(struct domain *d, mfn_t sl2mfn, mfn_t x)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
guest_l2e_t *gl2e, *gp;
|
||||
shadow_l2e_t *sl2e;
|
||||
mfn_t mfn, gmfn, gl2mfn;
|
||||
@@ -4067,9 +4065,8 @@ int cf_check sh_audit_l2_table(struct vcpu *v, mfn_t sl2mfn, mfn_t x)
|
||||
}
|
||||
|
||||
#if GUEST_PAGING_LEVELS >= 4
|
||||
int cf_check sh_audit_l3_table(struct vcpu *v, mfn_t sl3mfn, mfn_t x)
|
||||
int cf_check sh_audit_l3_table(struct domain *d, mfn_t sl3mfn, mfn_t x)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
guest_l3e_t *gl3e, *gp;
|
||||
shadow_l3e_t *sl3e;
|
||||
mfn_t mfn, gmfn, gl3mfn;
|
||||
@@ -4117,9 +4114,8 @@ int cf_check sh_audit_l3_table(struct vcpu *v, mfn_t sl3mfn, mfn_t x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cf_check sh_audit_l4_table(struct vcpu *v, mfn_t sl4mfn, mfn_t x)
|
||||
int cf_check sh_audit_l4_table(struct domain *d, mfn_t sl4mfn, mfn_t x)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
guest_l4e_t *gl4e, *gp;
|
||||
shadow_l4e_t *sl4e;
|
||||
mfn_t mfn, gmfn, gl4mfn;
|
||||
|
||||
@@ -83,19 +83,19 @@ SHADOW_INTERNAL_NAME(sh_remove_l3_shadow, GUEST_LEVELS)
|
||||
#if SHADOW_AUDIT & SHADOW_AUDIT_ENTRIES
|
||||
int cf_check
|
||||
SHADOW_INTERNAL_NAME(sh_audit_l1_table, GUEST_LEVELS)
|
||||
(struct vcpu *v, mfn_t sl1mfn, mfn_t x);
|
||||
(struct domain *d, mfn_t sl1mfn, mfn_t x);
|
||||
int cf_check
|
||||
SHADOW_INTERNAL_NAME(sh_audit_fl1_table, GUEST_LEVELS)
|
||||
(struct vcpu *v, mfn_t sl1mfn, mfn_t x);
|
||||
(struct domain *d, mfn_t sl1mfn, mfn_t x);
|
||||
int cf_check
|
||||
SHADOW_INTERNAL_NAME(sh_audit_l2_table, GUEST_LEVELS)
|
||||
(struct vcpu *v, mfn_t sl2mfn, mfn_t x);
|
||||
(struct domain *d, mfn_t sl2mfn, mfn_t x);
|
||||
int cf_check
|
||||
SHADOW_INTERNAL_NAME(sh_audit_l3_table, GUEST_LEVELS)
|
||||
(struct vcpu *v, mfn_t sl3mfn, mfn_t x);
|
||||
(struct domain *d, mfn_t sl3mfn, mfn_t x);
|
||||
int cf_check
|
||||
SHADOW_INTERNAL_NAME(sh_audit_l4_table, GUEST_LEVELS)
|
||||
(struct vcpu *v, mfn_t sl4mfn, mfn_t x);
|
||||
(struct domain *d, mfn_t sl4mfn, mfn_t x);
|
||||
#endif
|
||||
|
||||
extern const struct paging_mode
|
||||
|
||||