x86: Add "nopv" parameter to disable PV extensions
authorZhenzhong Duan <zhenzhong.duan@oracle.com>
Thu, 11 Jul 2019 12:02:09 +0000 (20:02 +0800)
committerJuergen Gross <jgross@suse.com>
Wed, 17 Jul 2019 06:09:58 +0000 (08:09 +0200)
In virtualization environment, PV extensions (drivers, interrupts,
timers, etc) are enabled in the majority of use cases which is the
best option.

However, in some cases (kexec not fully working, benchmarking)
we want to disable PV extensions. We have "xen_nopv" for that purpose
but only for XEN. For a consistent admin experience a common command
line parameter "nopv" set across all PV guest implementations is a
better choice.

There are guest types which just won't work without PV extensions,
like Xen PV, Xen PVH and jailhouse. add a "ignore_nopv" member to
struct hypervisor_x86 set to true for those guest types and call
the detect functions only if nopv is false or ignore_nopv is true.

Suggested-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@oracle.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Juergen Gross <jgross@suse.com>
Documentation/admin-guide/kernel-parameters.txt
arch/x86/include/asm/hypervisor.h
arch/x86/kernel/cpu/hypervisor.c
arch/x86/kernel/jailhouse.c
arch/x86/xen/enlighten_pv.c

index 99db4975e6b5c5e8f66fc1b090a85641595d0cdf..936e8e7e64747ca4242f2c07b854cd1564462f41 100644 (file)
                        improve timer resolution at the expense of processing
                        more timer interrupts.
 
+       nopv=           [X86,XEN,KVM,HYPER_V,VMWARE]
+                       Disables the PV optimizations forcing the guest to run
+                       as generic guest with no PV drivers. Currently support
+                       XEN HVM, KVM, HYPER_V and VMWARE guest.
+
        xirc2ps_cs=     [NET,PCMCIA]
                        Format:
                        <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
index 50a30f6c668b6c5fbd7458ae3305b8381e8da93b..f7b4c5338428fc8e29bc63ff1832c6b38398c1ab 100644 (file)
@@ -53,8 +53,12 @@ struct hypervisor_x86 {
 
        /* runtime callbacks */
        struct x86_hyper_runtime runtime;
+
+       /* ignore nopv parameter */
+       bool ignore_nopv;
 };
 
+extern bool nopv;
 extern enum x86_hypervisor_type x86_hyper_type;
 extern void init_hypervisor_platform(void);
 static inline bool hypervisor_is_type(enum x86_hypervisor_type type)
index 87e39ad8d873fdff2a206f18fdd78a03478ae1c5..7eaad41c68f452285a1506fbfc28007a82b38b2f 100644 (file)
@@ -58,6 +58,14 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] =
 enum x86_hypervisor_type x86_hyper_type;
 EXPORT_SYMBOL(x86_hyper_type);
 
+bool __initdata nopv;
+static __init int parse_nopv(char *arg)
+{
+       nopv = true;
+       return 0;
+}
+early_param("nopv", parse_nopv);
+
 static inline const struct hypervisor_x86 * __init
 detect_hypervisor_vendor(void)
 {
@@ -65,6 +73,9 @@ detect_hypervisor_vendor(void)
        uint32_t pri, max_pri = 0;
 
        for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
+               if (unlikely(nopv) && !(*p)->ignore_nopv)
+                       continue;
+
                pri = (*p)->detect();
                if (pri > max_pri) {
                        max_pri = pri;
index 6857b4577f170d83443840a6f8c55e50bc3378f0..3ad34f01de2a6779b134600b8837cf04465da0b5 100644 (file)
@@ -217,4 +217,5 @@ const struct hypervisor_x86 x86_hyper_jailhouse __refconst = {
        .detect                 = jailhouse_detect,
        .init.init_platform     = jailhouse_init_platform,
        .init.x2apic_available  = jailhouse_x2apic_available,
+       .ignore_nopv            = true,
 };
index 4722ba2966ac480218f651e84e2d13b795f8e2f7..5d16824e4dca9542d035ee463e7209c1ecc561c9 100644 (file)
@@ -1463,4 +1463,5 @@ const __initconst struct hypervisor_x86 x86_hyper_xen_pv = {
        .detect                 = xen_platform_pv,
        .type                   = X86_HYPER_XEN_PV,
        .runtime.pin_vcpu       = xen_pin_vcpu,
+       .ignore_nopv            = true,
 };