diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index 891d2d439f..7a1be84ca9 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -1087,6 +1087,19 @@ value settable via Xen tools. Dom0 is using this value for sizing its maptrack table. +### global-pages (x86) +> `= ` + +> Default: `true` unless running virtualized on AMD or Hygon hardware + +Set whether the PGE bit in CR4 will be enabled for PV guests. This controls the +usage of global pages, and thus the need to perform tlb flushes by writing to +CR4. + +Note it's disabled by default when running virtualized on AMD or Hygon hardware +since AMD SVM doesn't support selective trapping of CR4, so global pages are +not enabled in order to reduce the overhead of TLB flushes. + ### guest_loglvl > `= [/]` where level is `none | error | warning | info | debug | all` diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c index 4b6f48dea2..e6e1c51548 100644 --- a/xen/arch/x86/pv/domain.c +++ b/xen/arch/x86/pv/domain.c @@ -118,6 +118,20 @@ unsigned long pv_fixup_guest_cr4(const struct vcpu *v, unsigned long cr4) (mmu_cr4_features & PV_CR4_GUEST_VISIBLE_MASK)); } +static int8_t __read_mostly opt_global_pages = -1; +boolean_runtime_param("global-pages", opt_global_pages); + +static int __init pge_init(void) +{ + if ( opt_global_pages == -1 ) + opt_global_pages = !cpu_has_hypervisor || + (boot_cpu_data.x86_vendor & + (X86_VENDOR_AMD | X86_VENDOR_HYGON)); + + return 0; +} +__initcall(pge_init); + unsigned long pv_make_cr4(const struct vcpu *v) { const struct domain *d = v->domain; @@ -130,7 +144,7 @@ unsigned long pv_make_cr4(const struct vcpu *v) */ if ( d->arch.pv.pcid ) cr4 |= X86_CR4_PCIDE; - else if ( !d->arch.pv.xpti ) + else if ( !d->arch.pv.xpti && opt_global_pages ) cr4 |= X86_CR4_PGE; /*