Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/xen: Add "nopv" support for HVM guest

PVH guest needs PV extentions to work, so "nopv" parameter should be
ignored for PVH but not for HVM guest.

If PVH guest boots up via the Xen-PVH boot entry, xen_pvh is set early,
we know it's PVH guest and ignore "nopv" parameter directly.

If PVH guest boots up via the normal boot entry same as HVM guest, it's
hard to distinguish PVH and HVM guest at that time. In this case, we
have to panic early if PVH is detected and nopv is enabled to avoid a
worse situation later.

Remove static from bool_x86_init_noop/x86_op_int_noop so they could be
used globally. Move xen_platform_hvm() after xen_hvm_guest_late_init()
to avoid compile error.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@oracle.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Signed-off-by: Juergen Gross <jgross@suse.com>

authored by

Zhenzhong Duan and committed by
Juergen Gross
bef6e0ae cc8f3b4d

+39 -10
+2
arch/x86/include/asm/x86_init.h
··· 301 301 extern void x86_early_init_platform_quirks(void); 302 302 extern void x86_init_noop(void); 303 303 extern void x86_init_uint_noop(unsigned int unused); 304 + extern bool bool_x86_init_noop(void); 305 + extern void x86_op_int_noop(int cpu); 304 306 extern bool x86_pnpbios_disabled(void); 305 307 306 308 #endif
+2 -2
arch/x86/kernel/x86_init.c
··· 29 29 void __init x86_init_uint_noop(unsigned int unused) { } 30 30 static int __init iommu_init_noop(void) { return 0; } 31 31 static void iommu_shutdown_noop(void) { } 32 - static bool __init bool_x86_init_noop(void) { return false; } 33 - static void x86_op_int_noop(int cpu) { } 32 + bool __init bool_x86_init_noop(void) { return false; } 33 + void x86_op_int_noop(int cpu) { } 34 34 35 35 /* 36 36 * The platform setup functions are preset with the default functions
+35 -8
arch/x86/xen/enlighten_hvm.c
··· 231 231 return true; 232 232 } 233 233 234 - static uint32_t __init xen_platform_hvm(void) 235 - { 236 - if (xen_pv_domain()) 237 - return 0; 238 - 239 - return xen_cpuid_base(); 240 - } 241 - 242 234 static __init void xen_hvm_guest_late_init(void) 243 235 { 244 236 #ifdef CONFIG_XEN_PVH ··· 242 250 /* PVH detected. */ 243 251 xen_pvh = true; 244 252 253 + if (nopv) 254 + panic("\"nopv\" and \"xen_nopv\" parameters are unsupported in PVH guest."); 255 + 245 256 /* Make sure we don't fall back to (default) ACPI_IRQ_MODEL_PIC. */ 246 257 if (!nr_ioapics && acpi_irq_model == ACPI_IRQ_MODEL_PIC) 247 258 acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM; ··· 252 257 machine_ops.emergency_restart = xen_emergency_restart; 253 258 pv_info.name = "Xen PVH"; 254 259 #endif 260 + } 261 + 262 + static uint32_t __init xen_platform_hvm(void) 263 + { 264 + uint32_t xen_domain = xen_cpuid_base(); 265 + struct x86_hyper_init *h = &x86_hyper_xen_hvm.init; 266 + 267 + if (xen_pv_domain()) 268 + return 0; 269 + 270 + if (xen_pvh_domain() && nopv) { 271 + /* Guest booting via the Xen-PVH boot entry goes here */ 272 + pr_info("\"nopv\" parameter is ignored in PVH guest\n"); 273 + nopv = false; 274 + } else if (nopv && xen_domain) { 275 + /* 276 + * Guest booting via normal boot entry (like via grub2) goes 277 + * here. 278 + * 279 + * Use interface functions for bare hardware if nopv, 280 + * xen_hvm_guest_late_init is an exception as we need to 281 + * detect PVH and panic there. 282 + */ 283 + h->init_platform = x86_init_noop; 284 + h->x2apic_available = bool_x86_init_noop; 285 + h->init_mem_mapping = x86_init_noop; 286 + h->init_after_bootmem = x86_init_noop; 287 + h->guest_late_init = xen_hvm_guest_late_init; 288 + x86_hyper_xen_hvm.runtime.pin_vcpu = x86_op_int_noop; 289 + } 290 + return xen_domain; 255 291 } 256 292 257 293 struct hypervisor_x86 x86_hyper_xen_hvm __initdata = { ··· 294 268 .init.init_mem_mapping = xen_hvm_init_mem_mapping, 295 269 .init.guest_late_init = xen_hvm_guest_late_init, 296 270 .runtime.pin_vcpu = xen_pin_vcpu, 271 + .ignore_nopv = true, 297 272 };