From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Jan Beulich <JBeulich@suse.com>,
xen-devel <xen-devel@lists.xenproject.org>
Cc: Tim Deegan <tim@xen.org>, Keir Fraser <keir@xen.org>
Subject: Re: [PATCH v2 3/5] x86/mm: allow for building without shadow mode support
Date: Mon, 2 Feb 2015 11:56:40 +0000 [thread overview]
Message-ID: <54CF65F8.3010505@citrix.com> (raw)
In-Reply-To: <54CF6B72020000780005BDB9@mail.emea.novell.com>
On 02/02/15 11:20, Jan Beulich wrote:
> Considering the complexity of the code, it seems to be a reasonable
> thing to allow people to disable that code entirely even outside the
> immediate need for this by the next patch.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> v2: Set mode table in shadow_vcpu_init() stub. Convert BUG()/BUG_ON()
> to ASSERT()/ASSERT_UNREACHABLE() and make various of the stub
> functions macros or inline. Hide opt_dom0_shadow when
> !CONFIG_SHADOW_PAGING. Adjust Makefile modification.
>
> --- a/xen/arch/x86/Rules.mk
> +++ b/xen/arch/x86/Rules.mk
> @@ -32,9 +32,13 @@ x86 := y
> x86_32 := n
> x86_64 := y
>
> +shadow-paging ?= y
> +
> CFLAGS += -mno-red-zone -mno-sse -fpic
> CFLAGS += -fno-asynchronous-unwind-tables
> # -fvisibility=hidden reduces -fpic cost, if it's available
> ifneq ($(call cc-option,$(CC),-fvisibility=hidden,n),n)
> CFLAGS += -DGCC_HAS_VISIBILITY_ATTRIBUTE
> endif
> +
> +CFLAGS-$(shadow-paging) += -DCONFIG_SHADOW_PAGING
> --- a/xen/arch/x86/domain_build.c
> +++ b/xen/arch/x86/domain_build.c
> @@ -128,8 +128,10 @@ struct vcpu *__init alloc_dom0_vcpu0(str
> return alloc_vcpu(dom0, 0, 0);
> }
>
> +#ifdef CONFIG_SHADOW_PAGING
> static bool_t __initdata opt_dom0_shadow;
> boolean_param("dom0_shadow", opt_dom0_shadow);
> +#endif
>
> static char __initdata opt_dom0_ioports_disable[200] = "";
> string_param("dom0_ioports_disable", opt_dom0_ioports_disable);
> @@ -1399,6 +1401,7 @@ int __init construct_dom0(
> regs->esi = vstartinfo_start;
> regs->eflags = X86_EFLAGS_IF;
>
> +#ifdef CONFIG_SHADOW_PAGING
> if ( opt_dom0_shadow )
> {
> if ( is_pvh_domain(d) )
> @@ -1409,6 +1412,7 @@ int __init construct_dom0(
> if ( paging_enable(d, PG_SH_enable) == 0 )
> paging_update_paging_modes(v);
> }
> +#endif
>
> /*
> * PVH Fixme: XENFEAT_supervisor_mode_kernel has been reused in PVH with a
> --- a/xen/arch/x86/mm/paging.c
> +++ b/xen/arch/x86/mm/paging.c
> @@ -635,16 +635,16 @@ int paging_domain_init(struct domain *d,
> * don't want to leak any active log-dirty bitmaps */
> d->arch.paging.log_dirty.top = _mfn(INVALID_MFN);
>
> - /* The order of the *_init calls below is important, as the later
> - * ones may rewrite some common fields. Shadow pagetables are the
> - * default... */
> - shadow_domain_init(d, domcr_flags);
> -
> - /* ... but we will use hardware assistance if it's available. */
> + /*
> + * Shadow pagetables are the default, but we will use
> + * hardware assistance if it's available and enabled.
> + */
> if ( hap_enabled(d) )
> hap_domain_init(d);
> + else
> + rc = shadow_domain_init(d, domcr_flags);
>
> - return 0;
> + return rc;
> }
>
> /* vcpu paging struct initialization goes here */
> @@ -822,12 +822,16 @@ int paging_enable(struct domain *d, u32
> * and therefore its pagetables will soon be discarded */
> void pagetable_dying(struct domain *d, paddr_t gpa)
> {
> +#ifdef CONFIG_SHADOW_PAGING
> struct vcpu *v;
>
> ASSERT(paging_mode_shadow(d));
>
> v = d->vcpu[0];
> v->arch.paging.mode->shadow.pagetable_dying(v, gpa);
> +#else
> + BUG();
> +#endif
> }
>
> /* Print paging-assistance info to the console */
> --- a/xen/arch/x86/mm/shadow/Makefile
> +++ b/xen/arch/x86/mm/shadow/Makefile
> @@ -1,4 +1,8 @@
> -obj-$(x86_64) += common.o guest_2.o guest_3.o guest_4.o
> +ifeq ($(shadow-paging),y)
> +obj-y += common.o guest_2.o guest_3.o guest_4.o
> +else
> +obj-y += none.o
> +endif
>
> guest_%.o: multi.c Makefile
> $(CC) $(CFLAGS) -DGUEST_PAGING_LEVELS=$* -c $< -o $@
> --- a/xen/arch/x86/mm/shadow/common.c
> +++ b/xen/arch/x86/mm/shadow/common.c
> @@ -47,7 +47,7 @@ static void sh_clean_dirty_bitmap(struct
>
> /* Set up the shadow-specific parts of a domain struct at start of day.
> * Called for every domain from arch_domain_create() */
> -void shadow_domain_init(struct domain *d, unsigned int domcr_flags)
> +int shadow_domain_init(struct domain *d, unsigned int domcr_flags)
> {
> INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.freelist);
> INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.pinned_shadows);
> @@ -61,6 +61,8 @@ void shadow_domain_init(struct domain *d
> d->arch.paging.shadow.oos_off = (domcr_flags & DOMCRF_oos_off) ? 1 : 0;
> #endif
> d->arch.paging.shadow.pagetable_dying_op = 0;
> +
> + return 0;
> }
>
> /* Setup the shadow-specfic parts of a vcpu struct. Note: The most important
> --- /dev/null
> +++ b/xen/arch/x86/mm/shadow/none.c
> @@ -0,0 +1,78 @@
> +#include <xen/mm.h>
> +#include <asm/shadow.h>
> +
> +static int _enable_log_dirty(struct domain *d, bool_t log_global)
> +{
> + ASSERT(is_pv_domain(d));
> + return -EOPNOTSUPP;
> +}
> +
> +static int _disable_log_dirty(struct domain *d)
> +{
> + ASSERT(is_pv_domain(d));
> + return -EOPNOTSUPP;
> +}
> +
> +static void _clean_dirty_bitmap(struct domain *d)
> +{
> + ASSERT(is_pv_domain(d));
> +}
> +
> +int shadow_domain_init(struct domain *d, unsigned int domcr_flags)
> +{
> + paging_log_dirty_init(d, _enable_log_dirty,
> + _disable_log_dirty, _clean_dirty_bitmap);
> + return is_pv_domain(d) ? 0 : -EOPNOTSUPP;
> +}
> +
> +static int _page_fault(struct vcpu *v, unsigned long va,
> + struct cpu_user_regs *regs)
> +{
> + ASSERT_UNREACHABLE();
> + return 0;
> +}
> +
> +static int _invlpg(struct vcpu *v, unsigned long va)
> +{
> + ASSERT_UNREACHABLE();
> + return -EOPNOTSUPP;
> +}
> +
> +static unsigned long _gva_to_gfn(struct vcpu *v, struct p2m_domain *p2m,
> + unsigned long va, uint32_t *pfec)
> +{
> + ASSERT_UNREACHABLE();
> + return INVALID_GFN;
> +}
> +
> +static void _update_cr3(struct vcpu *v, int do_locking)
> +{
> + ASSERT_UNREACHABLE();
> +}
> +
> +static void _update_paging_modes(struct vcpu *v)
> +{
> + ASSERT_UNREACHABLE();
> +}
> +
> +static void _write_p2m_entry(struct domain *d, unsigned long gfn,
> + l1_pgentry_t *p, l1_pgentry_t new,
> + unsigned int level)
> +{
> + ASSERT_UNREACHABLE();
> +}
> +
> +static const struct paging_mode sh_paging_none = {
> + .page_fault = _page_fault,
> + .invlpg = _invlpg,
> + .gva_to_gfn = _gva_to_gfn,
> + .update_cr3 = _update_cr3,
> + .update_paging_modes = _update_paging_modes,
> + .write_p2m_entry = _write_p2m_entry,
> +};
> +
> +void shadow_vcpu_init(struct vcpu *v)
> +{
> + ASSERT(is_pv_domain(v->domain));
> + v->arch.paging.mode = &sh_paging_none;
> +}
> --- a/xen/include/asm-x86/domain.h
> +++ b/xen/include/asm-x86/domain.h
> @@ -87,6 +87,7 @@ void hypercall_page_initialise(struct do
> /* shadow paging extension */
> /************************************************/
> struct shadow_domain {
> +#ifdef CONFIG_SHADOW_PAGING
> unsigned int opt_flags; /* runtime tunable optimizations on/off */
> struct page_list_head pinned_shadows;
>
> @@ -116,9 +117,11 @@ struct shadow_domain {
>
> /* Has this domain ever used HVMOP_pagetable_dying? */
> bool_t pagetable_dying_op;
> +#endif
> };
>
> struct shadow_vcpu {
> +#ifdef CONFIG_SHADOW_PAGING
> /* PAE guests: per-vcpu shadow top-level table */
> l3_pgentry_t l3table[4] __attribute__((__aligned__(32)));
> /* PAE guests: per-vcpu cache of the top-level *guest* entries */
> @@ -144,6 +147,7 @@ struct shadow_vcpu {
> } oos_fixup[SHADOW_OOS_PAGES];
>
> bool_t pagetable_dying;
> +#endif
> };
>
> /************************************************/
> --- a/xen/include/asm-x86/paging.h
> +++ b/xen/include/asm-x86/paging.h
> @@ -39,7 +39,11 @@
> #define PG_SH_shift 20
> #define PG_HAP_shift 21
> /* We're in one of the shadow modes */
> +#ifdef CONFIG_SHADOW_PAGING
> #define PG_SH_enable (1U << PG_SH_shift)
> +#else
> +#define PG_SH_enable 0
> +#endif
> #define PG_HAP_enable (1U << PG_HAP_shift)
>
> /* common paging mode bits */
> @@ -74,6 +78,7 @@
>
> struct sh_emulate_ctxt;
> struct shadow_paging_mode {
> +#ifdef CONFIG_SHADOW_PAGING
> void (*detach_old_tables )(struct vcpu *v);
> int (*x86_emulate_write )(struct vcpu *v, unsigned long va,
> void *src, u32 bytes,
> @@ -88,6 +93,7 @@ struct shadow_paging_mode {
> int (*guess_wrmap )(struct vcpu *v,
> unsigned long vaddr, mfn_t gmfn);
> void (*pagetable_dying )(struct vcpu *v, paddr_t gpa);
> +#endif
> /* For outsiders to tell what mode we're in */
> unsigned int shadow_levels;
> };
> --- a/xen/include/asm-x86/shadow.h
> +++ b/xen/include/asm-x86/shadow.h
> @@ -49,12 +49,14 @@
>
> /* Set up the shadow-specific parts of a domain struct at start of day.
> * Called from paging_domain_init(). */
> -void shadow_domain_init(struct domain *d, unsigned int domcr_flags);
> +int shadow_domain_init(struct domain *d, unsigned int domcr_flags);
>
> /* Setup the shadow-specific parts of a vcpu struct. It is called by
> * paging_vcpu_init() in paging.c */
> void shadow_vcpu_init(struct vcpu *v);
>
> +#ifdef CONFIG_SHADOW_PAGING
> +
> /* Enable an arbitrary shadow mode. Call once at domain creation. */
> int shadow_enable(struct domain *d, u32 mode);
>
> @@ -77,17 +79,40 @@ void shadow_teardown(struct domain *d);
> /* Call once all of the references to the domain have gone away */
> void shadow_final_teardown(struct domain *d);
>
> -/* Remove all shadows of the guest mfn. */
> void sh_remove_shadows(struct vcpu *v, mfn_t gmfn, int fast, int all);
> +
> +/* Discard _all_ mappings from the domain's shadows. */
> +void shadow_blow_tables_per_domain(struct domain *d);
> +
> +#else /* !CONFIG_SHADOW_PAGING */
> +
> +#define shadow_teardown(d) ASSERT(is_pv_domain(d))
> +#define shadow_final_teardown(d) ASSERT(is_pv_domain(d))
> +#define shadow_enable(d, mode) \
> + ({ ASSERT(is_pv_domain(d)); -EOPNOTSUPP; })
> +#define shadow_track_dirty_vram(d, begin_pfn, nr, bitmap) \
> + ({ ASSERT_UNREACHABLE(); -EOPNOTSUPP; })
> +
> +static inline void sh_remove_shadows(struct vcpu *v, mfn_t gmfn,
> + bool_t fast, bool_t all) {}
> +
> +static inline void shadow_blow_tables_per_domain(struct domain *d) {}
> +
> +static inline int shadow_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
> + XEN_GUEST_HANDLE_PARAM(void) u_domctl)
> +{
> + return -EINVAL;
> +}
> +
> +#endif /* CONFIG_SHADOW_PAGING */
> +
> +/* Remove all shadows of the guest mfn. */
> static inline void shadow_remove_all_shadows(struct vcpu *v, mfn_t gmfn)
> {
> /* See the comment about locking in sh_remove_shadows */
> sh_remove_shadows(v, gmfn, 0 /* Be thorough */, 1 /* Must succeed */);
> }
>
> -/* Discard _all_ mappings from the domain's shadows. */
> -void shadow_blow_tables_per_domain(struct domain *d);
> -
> #endif /* _XEN_SHADOW_H */
>
> /*
> --- a/xen/include/xen/paging.h
> +++ b/xen/include/xen/paging.h
> @@ -7,7 +7,7 @@
> #include <asm/paging.h>
> #include <asm/p2m.h>
>
> -#elif defined CONFIG_SHADOW
> +#elif defined CONFIG_SHADOW_PAGING
>
> #include <asm/shadow.h>
>
>
>
next prev parent reply other threads:[~2015-02-02 11:56 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-02 11:09 [PATCH v2 0/5] x86: shadow adjustments / allow for more memory to be used Jan Beulich
2015-02-02 11:18 ` [PATCH v2 1/5] x86/shadow: tidy up fragmentary page lists in multi‑page shadows Jan Beulich
2015-02-02 11:43 ` Andrew Cooper
2015-02-02 11:47 ` Jan Beulich
2015-02-02 11:55 ` [PATCH v2 1/5] x86/shadow: tidy up fragmentary page lists in multi?page shadows Tim Deegan
2015-02-02 11:19 ` [PATCH v2 2/5] x86/shadow: don't needlessly expose internal functions Jan Beulich
2015-02-02 11:47 ` Andrew Cooper
2015-02-02 11:20 ` [PATCH v2 3/5] x86/mm: allow for building without shadow mode support Jan Beulich
2015-02-02 11:56 ` Andrew Cooper [this message]
2015-02-02 11:20 ` [PATCH v2 4/5] IOMMU/x86: correct page_list_first() use Jan Beulich
2015-02-02 11:52 ` Andrew Cooper
2015-02-02 11:21 ` [PATCH v2 5/5] x86: provide build time option to support up to 123Tb of memory Jan Beulich
2015-02-02 11:58 ` Andrew Cooper
2015-02-02 13:03 ` Jan Beulich
2015-02-02 11:54 ` [PATCH v2 0/5] x86: shadow adjustments / allow for more memory to be used Tim Deegan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54CF65F8.3010505@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=JBeulich@suse.com \
--cc=keir@xen.org \
--cc=tim@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.