From 45ac805f7f21c5994b000eba9ab2669cbbec8c9d Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 16 Feb 2017 16:42:16 +0000 Subject: [PATCH] x86/paging: Package up the log dirty function pointers They depend soley on paging mode, so don't need to be repeated per domain, and can live in .rodata. While making this change, drop the redundant log_dirty from the function pointer names. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich Acked-by: Tim Deegan Acked-by: George Dunlap --- xen/arch/x86/mm/hap/hap.c | 10 +++++++--- xen/arch/x86/mm/paging.c | 24 +++++++++--------------- xen/arch/x86/mm/shadow/common.c | 9 +++++++-- xen/include/asm-x86/domain.h | 8 +++++--- xen/include/asm-x86/paging.h | 6 +----- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c index 4a17b130a4..a57b385523 100644 --- a/xen/arch/x86/mm/hap/hap.c +++ b/xen/arch/x86/mm/hap/hap.c @@ -442,12 +442,16 @@ static void hap_destroy_monitor_table(struct vcpu* v, mfn_t mmfn) /************************************************/ void hap_domain_init(struct domain *d) { + static const struct log_dirty_ops hap_ops = { + .enable = hap_enable_log_dirty, + .disable = hap_disable_log_dirty, + .clean = hap_clean_dirty_bitmap, + }; + INIT_PAGE_LIST_HEAD(&d->arch.paging.hap.freelist); /* Use HAP logdirty mechanism. */ - paging_log_dirty_init(d, hap_enable_log_dirty, - hap_disable_log_dirty, - hap_clean_dirty_bitmap); + paging_log_dirty_init(d, &hap_ops); } /* return 0 for success, -errno for failure */ diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c index 97e2780c6d..632763163a 100644 --- a/xen/arch/x86/mm/paging.c +++ b/xen/arch/x86/mm/paging.c @@ -232,7 +232,7 @@ int paging_log_dirty_enable(struct domain *d, bool_t log_global) return -EINVAL; domain_pause(d); - ret = d->arch.paging.log_dirty.enable_log_dirty(d, log_global); + ret = d->arch.paging.log_dirty.ops->enable(d, log_global); domain_unpause(d); return ret; @@ -248,7 +248,7 @@ static int paging_log_dirty_disable(struct domain *d, bool_t resuming) /* Safe because the domain is paused. */ if ( paging_mode_log_dirty(d) ) { - ret = d->arch.paging.log_dirty.disable_log_dirty(d); + ret = d->arch.paging.log_dirty.ops->disable(d); ASSERT(ret <= 0); } } @@ -570,7 +570,7 @@ static int paging_log_dirty_op(struct domain *d, { /* We need to further call clean_dirty_bitmap() functions of specific * paging modes (shadow or hap). Safe because the domain is paused. */ - d->arch.paging.log_dirty.clean_dirty_bitmap(d); + d->arch.paging.log_dirty.ops->clean(d); } domain_unpause(d); return rv; @@ -622,22 +622,16 @@ void paging_log_dirty_range(struct domain *d, flush_tlb_mask(d->domain_dirty_cpumask); } -/* Note that this function takes three function pointers. Callers must supply - * these functions for log dirty code to call. This function usually is - * invoked when paging is enabled. Check shadow_enable() and hap_enable() for - * reference. +/* + * Callers must supply log_dirty_ops for the log dirty code to call. This + * function usually is invoked when paging is enabled. Check shadow_enable() + * and hap_enable() for reference. * * These function pointers must not be followed with the log-dirty lock held. */ -void paging_log_dirty_init(struct domain *d, - int (*enable_log_dirty)(struct domain *d, - bool_t log_global), - int (*disable_log_dirty)(struct domain *d), - void (*clean_dirty_bitmap)(struct domain *d)) +void paging_log_dirty_init(struct domain *d, const struct log_dirty_ops *ops) { - d->arch.paging.log_dirty.enable_log_dirty = enable_log_dirty; - d->arch.paging.log_dirty.disable_log_dirty = disable_log_dirty; - d->arch.paging.log_dirty.clean_dirty_bitmap = clean_dirty_bitmap; + d->arch.paging.log_dirty.ops = ops; } /************************************************/ diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 560a7fde54..d078d78396 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -48,12 +48,17 @@ static void sh_clean_dirty_bitmap(struct domain *); * Called for every domain from arch_domain_create() */ int shadow_domain_init(struct domain *d, unsigned int domcr_flags) { + static const struct log_dirty_ops sh_ops = { + .enable = sh_enable_log_dirty, + .disable = sh_disable_log_dirty, + .clean = sh_clean_dirty_bitmap, + }; + INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.freelist); INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.pinned_shadows); /* Use shadow pagetables for log-dirty support */ - paging_log_dirty_init(d, sh_enable_log_dirty, - sh_disable_log_dirty, sh_clean_dirty_bitmap); + paging_log_dirty_init(d, &sh_ops); #if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) d->arch.paging.shadow.oos_active = 0; diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index d8749df4eb..1beef2f520 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -175,9 +175,11 @@ struct log_dirty_domain { unsigned int dirty_count; /* functions which are paging mode specific */ - int (*enable_log_dirty )(struct domain *d, bool_t log_global); - int (*disable_log_dirty )(struct domain *d); - void (*clean_dirty_bitmap )(struct domain *d); + const struct log_dirty_ops { + int (*enable )(struct domain *d, bool log_global); + int (*disable )(struct domain *d); + void (*clean )(struct domain *d); + } *ops; }; struct paging_domain { diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h index 51808fc08a..2f5befcc81 100644 --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -150,11 +150,7 @@ void paging_log_dirty_range(struct domain *d, int paging_log_dirty_enable(struct domain *d, bool_t log_global); /* log dirty initialization */ -void paging_log_dirty_init(struct domain *d, - int (*enable_log_dirty)(struct domain *d, - bool_t log_global), - int (*disable_log_dirty)(struct domain *d), - void (*clean_dirty_bitmap)(struct domain *d)); +void paging_log_dirty_init(struct domain *d, const struct log_dirty_ops *ops); /* mark a page as dirty */ void paging_mark_dirty(struct domain *d, mfn_t gmfn); -- 2.30.2