Skip to content

Commit 460023a

Browse files
committed
Merge tag 'for-linus-4.21-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross: "Xen features and fixes: - a series to enable KVM guests to be booted by qemu via the Xen PVH boot entry for speeding up KVM guest tests - a series for a common driver to be used by Xen PV frontends (right now drm and sound) - two other fixes in Xen related code" * tag 'for-linus-4.21-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: ALSA: xen-front: Use Xen common shared buffer implementation drm/xen-front: Use Xen common shared buffer implementation xen: Introduce shared buffer helpers for page directory... xen/pciback: Check dev_data before using it kprobes/x86/xen: blacklist non-attachable xen interrupt functions KVM: x86: Allow Qemu/KVM to use PVH entry point xen/pvh: Add memory map pointer to hvm_start_info struct xen/pvh: Move Xen code for getting mem map via hcall out of common file xen/pvh: Move Xen specific PVH VM initialization out of common file xen/pvh: Create a new file for Xen specific PVH code xen/pvh: Move PVH entry code out of Xen specific tree xen/pvh: Split CONFIG_XEN_PVH into CONFIG_PVH and CONFIG_XEN_PVH
2 parents a5f2bd4 + 58f9d80 commit 460023a

31 files changed

+996
-862
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16590,6 +16590,7 @@ L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
1659016590
T: git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git
1659116591
S: Supported
1659216592
F: arch/x86/xen/
16593+
F: arch/x86/platform/pvh/
1659316594
F: drivers/*/xen-*front.c
1659416595
F: drivers/xen/
1659516596
F: arch/x86/include/asm/xen/

arch/x86/Kbuild

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ obj-$(CONFIG_KVM) += kvm/
77
# Xen paravirtualization support
88
obj-$(CONFIG_XEN) += xen/
99

10+
obj-$(CONFIG_PVH) += platform/pvh/
11+
1012
# Hyper-V paravirtualization support
1113
obj-$(subst m,y,$(CONFIG_HYPERV)) += hyperv/
1214

arch/x86/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,12 @@ config KVM_GUEST
796796
underlying device model, the host provides the guest with
797797
timing infrastructure such as time of day, and system time
798798

799+
config PVH
800+
bool "Support for running PVH guests"
801+
---help---
802+
This option enables the PVH entry point for guest virtual machines
803+
as specified in the x86/HVM direct boot ABI.
804+
799805
config KVM_DEBUG_FS
800806
bool "Enable debug information for KVM Guests in debugfs"
801807
depends on KVM_GUEST && DEBUG_FS

arch/x86/kernel/head_64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ NEXT_PAGE(early_dynamic_pgts)
386386

387387
.data
388388

389-
#if defined(CONFIG_XEN_PV) || defined(CONFIG_XEN_PVH)
389+
#if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH)
390390
NEXT_PGD_PAGE(init_top_pgt)
391391
.quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC
392392
.org init_top_pgt + L4_PAGE_OFFSET*8, 0

arch/x86/platform/pvh/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
OBJECT_FILES_NON_STANDARD_head.o := y
3+
4+
obj-$(CONFIG_PVH) += enlighten.o
5+
obj-$(CONFIG_PVH) += head.o

arch/x86/platform/pvh/enlighten.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <linux/acpi.h>
3+
4+
#include <xen/hvc-console.h>
5+
6+
#include <asm/io_apic.h>
7+
#include <asm/hypervisor.h>
8+
#include <asm/e820/api.h>
9+
#include <asm/x86_init.h>
10+
11+
#include <asm/xen/interface.h>
12+
13+
#include <xen/xen.h>
14+
#include <xen/interface/hvm/start_info.h>
15+
16+
/*
17+
* PVH variables.
18+
*
19+
* pvh_bootparams and pvh_start_info need to live in the data segment since
20+
* they are used after startup_{32|64}, which clear .bss, are invoked.
21+
*/
22+
struct boot_params pvh_bootparams __attribute__((section(".data")));
23+
struct hvm_start_info pvh_start_info __attribute__((section(".data")));
24+
25+
unsigned int pvh_start_info_sz = sizeof(pvh_start_info);
26+
27+
static u64 pvh_get_root_pointer(void)
28+
{
29+
return pvh_start_info.rsdp_paddr;
30+
}
31+
32+
/*
33+
* Xen guests are able to obtain the memory map from the hypervisor via the
34+
* HYPERVISOR_memory_op hypercall.
35+
* If we are trying to boot a Xen PVH guest, it is expected that the kernel
36+
* will have been configured to provide an override for this routine to do
37+
* just that.
38+
*/
39+
void __init __weak mem_map_via_hcall(struct boot_params *ptr __maybe_unused)
40+
{
41+
xen_raw_printk("Error: Could not find memory map\n");
42+
BUG();
43+
}
44+
45+
static void __init init_pvh_bootparams(bool xen_guest)
46+
{
47+
memset(&pvh_bootparams, 0, sizeof(pvh_bootparams));
48+
49+
if ((pvh_start_info.version > 0) && (pvh_start_info.memmap_entries)) {
50+
struct hvm_memmap_table_entry *ep;
51+
int i;
52+
53+
ep = __va(pvh_start_info.memmap_paddr);
54+
pvh_bootparams.e820_entries = pvh_start_info.memmap_entries;
55+
56+
for (i = 0; i < pvh_bootparams.e820_entries ; i++, ep++) {
57+
pvh_bootparams.e820_table[i].addr = ep->addr;
58+
pvh_bootparams.e820_table[i].size = ep->size;
59+
pvh_bootparams.e820_table[i].type = ep->type;
60+
}
61+
} else if (xen_guest) {
62+
mem_map_via_hcall(&pvh_bootparams);
63+
} else {
64+
/* Non-xen guests are not supported by version 0 */
65+
BUG();
66+
}
67+
68+
if (pvh_bootparams.e820_entries < E820_MAX_ENTRIES_ZEROPAGE - 1) {
69+
pvh_bootparams.e820_table[pvh_bootparams.e820_entries].addr =
70+
ISA_START_ADDRESS;
71+
pvh_bootparams.e820_table[pvh_bootparams.e820_entries].size =
72+
ISA_END_ADDRESS - ISA_START_ADDRESS;
73+
pvh_bootparams.e820_table[pvh_bootparams.e820_entries].type =
74+
E820_TYPE_RESERVED;
75+
pvh_bootparams.e820_entries++;
76+
} else
77+
xen_raw_printk("Warning: Can fit ISA range into e820\n");
78+
79+
pvh_bootparams.hdr.cmd_line_ptr =
80+
pvh_start_info.cmdline_paddr;
81+
82+
/* The first module is always ramdisk. */
83+
if (pvh_start_info.nr_modules) {
84+
struct hvm_modlist_entry *modaddr =
85+
__va(pvh_start_info.modlist_paddr);
86+
pvh_bootparams.hdr.ramdisk_image = modaddr->paddr;
87+
pvh_bootparams.hdr.ramdisk_size = modaddr->size;
88+
}
89+
90+
/*
91+
* See Documentation/x86/boot.txt.
92+
*
93+
* Version 2.12 supports Xen entry point but we will use default x86/PC
94+
* environment (i.e. hardware_subarch 0).
95+
*/
96+
pvh_bootparams.hdr.version = (2 << 8) | 12;
97+
pvh_bootparams.hdr.type_of_loader = ((xen_guest ? 0x9 : 0xb) << 4) | 0;
98+
99+
x86_init.acpi.get_root_pointer = pvh_get_root_pointer;
100+
}
101+
102+
/*
103+
* If we are trying to boot a Xen PVH guest, it is expected that the kernel
104+
* will have been configured to provide the required override for this routine.
105+
*/
106+
void __init __weak xen_pvh_init(void)
107+
{
108+
xen_raw_printk("Error: Missing xen PVH initialization\n");
109+
BUG();
110+
}
111+
112+
static void hypervisor_specific_init(bool xen_guest)
113+
{
114+
if (xen_guest)
115+
xen_pvh_init();
116+
}
117+
118+
/*
119+
* This routine (and those that it might call) should not use
120+
* anything that lives in .bss since that segment will be cleared later.
121+
*/
122+
void __init xen_prepare_pvh(void)
123+
{
124+
125+
u32 msr = xen_cpuid_base();
126+
bool xen_guest = !!msr;
127+
128+
if (pvh_start_info.magic != XEN_HVM_START_MAGIC_VALUE) {
129+
xen_raw_printk("Error: Unexpected magic value (0x%08x)\n",
130+
pvh_start_info.magic);
131+
BUG();
132+
}
133+
134+
hypervisor_specific_init(xen_guest);
135+
136+
init_pvh_bootparams(xen_guest);
137+
}
File renamed without changes.

arch/x86/xen/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ config XEN_DEBUG_FS
7474
Enabling this option may incur a significant performance overhead.
7575

7676
config XEN_PVH
77-
bool "Support for running as a PVH guest"
77+
bool "Support for running as a Xen PVH guest"
7878
depends on XEN && XEN_PVHVM && ACPI
79+
select PVH
7980
def_bool n

arch/x86/xen/Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
22
OBJECT_FILES_NON_STANDARD_xen-asm_$(BITS).o := y
3-
OBJECT_FILES_NON_STANDARD_xen-pvh.o := y
43

54
ifdef CONFIG_FUNCTION_TRACER
65
# Do not profile debug and lowlevel utilities
@@ -38,7 +37,6 @@ obj-$(CONFIG_XEN_PV) += xen-asm.o
3837
obj-$(CONFIG_XEN_PV) += xen-asm_$(BITS).o
3938

4039
obj-$(CONFIG_XEN_PVH) += enlighten_pvh.o
41-
obj-$(CONFIG_XEN_PVH) += xen-pvh.o
4240

4341
obj-$(CONFIG_EVENT_TRACING) += trace.o
4442

arch/x86/xen/enlighten_pvh.c

Lines changed: 17 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -6,103 +6,45 @@
66
#include <asm/io_apic.h>
77
#include <asm/hypervisor.h>
88
#include <asm/e820/api.h>
9-
#include <asm/x86_init.h>
109

10+
#include <xen/xen.h>
1111
#include <asm/xen/interface.h>
1212
#include <asm/xen/hypercall.h>
1313

14-
#include <xen/xen.h>
1514
#include <xen/interface/memory.h>
16-
#include <xen/interface/hvm/start_info.h>
1715

1816
/*
1917
* PVH variables.
2018
*
21-
* xen_pvh pvh_bootparams and pvh_start_info need to live in data segment
22-
* since they are used after startup_{32|64}, which clear .bss, are invoked.
19+
* The variable xen_pvh needs to live in the data segment since it is used
20+
* after startup_{32|64} is invoked, which will clear the .bss segment.
2321
*/
2422
bool xen_pvh __attribute__((section(".data"))) = 0;
25-
struct boot_params pvh_bootparams __attribute__((section(".data")));
26-
struct hvm_start_info pvh_start_info __attribute__((section(".data")));
27-
28-
unsigned int pvh_start_info_sz = sizeof(pvh_start_info);
2923

30-
static u64 pvh_get_root_pointer(void)
24+
void __init xen_pvh_init(void)
3125
{
32-
return pvh_start_info.rsdp_paddr;
26+
u32 msr;
27+
u64 pfn;
28+
29+
xen_pvh = 1;
30+
xen_start_flags = pvh_start_info.flags;
31+
32+
msr = cpuid_ebx(xen_cpuid_base() + 2);
33+
pfn = __pa(hypercall_page);
34+
wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
3335
}
3436

35-
static void __init init_pvh_bootparams(void)
37+
void __init mem_map_via_hcall(struct boot_params *boot_params_p)
3638
{
3739
struct xen_memory_map memmap;
3840
int rc;
3941

40-
memset(&pvh_bootparams, 0, sizeof(pvh_bootparams));
41-
42-
memmap.nr_entries = ARRAY_SIZE(pvh_bootparams.e820_table);
43-
set_xen_guest_handle(memmap.buffer, pvh_bootparams.e820_table);
42+
memmap.nr_entries = ARRAY_SIZE(boot_params_p->e820_table);
43+
set_xen_guest_handle(memmap.buffer, boot_params_p->e820_table);
4444
rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
4545
if (rc) {
4646
xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc);
4747
BUG();
4848
}
49-
pvh_bootparams.e820_entries = memmap.nr_entries;
50-
51-
if (pvh_bootparams.e820_entries < E820_MAX_ENTRIES_ZEROPAGE - 1) {
52-
pvh_bootparams.e820_table[pvh_bootparams.e820_entries].addr =
53-
ISA_START_ADDRESS;
54-
pvh_bootparams.e820_table[pvh_bootparams.e820_entries].size =
55-
ISA_END_ADDRESS - ISA_START_ADDRESS;
56-
pvh_bootparams.e820_table[pvh_bootparams.e820_entries].type =
57-
E820_TYPE_RESERVED;
58-
pvh_bootparams.e820_entries++;
59-
} else
60-
xen_raw_printk("Warning: Can fit ISA range into e820\n");
61-
62-
pvh_bootparams.hdr.cmd_line_ptr =
63-
pvh_start_info.cmdline_paddr;
64-
65-
/* The first module is always ramdisk. */
66-
if (pvh_start_info.nr_modules) {
67-
struct hvm_modlist_entry *modaddr =
68-
__va(pvh_start_info.modlist_paddr);
69-
pvh_bootparams.hdr.ramdisk_image = modaddr->paddr;
70-
pvh_bootparams.hdr.ramdisk_size = modaddr->size;
71-
}
72-
73-
/*
74-
* See Documentation/x86/boot.txt.
75-
*
76-
* Version 2.12 supports Xen entry point but we will use default x86/PC
77-
* environment (i.e. hardware_subarch 0).
78-
*/
79-
pvh_bootparams.hdr.version = (2 << 8) | 12;
80-
pvh_bootparams.hdr.type_of_loader = (9 << 4) | 0; /* Xen loader */
81-
82-
x86_init.acpi.get_root_pointer = pvh_get_root_pointer;
83-
}
84-
85-
/*
86-
* This routine (and those that it might call) should not use
87-
* anything that lives in .bss since that segment will be cleared later.
88-
*/
89-
void __init xen_prepare_pvh(void)
90-
{
91-
u32 msr;
92-
u64 pfn;
93-
94-
if (pvh_start_info.magic != XEN_HVM_START_MAGIC_VALUE) {
95-
xen_raw_printk("Error: Unexpected magic value (0x%08x)\n",
96-
pvh_start_info.magic);
97-
BUG();
98-
}
99-
100-
xen_pvh = 1;
101-
xen_start_flags = pvh_start_info.flags;
102-
103-
msr = cpuid_ebx(xen_cpuid_base() + 2);
104-
pfn = __pa(hypercall_page);
105-
wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
106-
107-
init_pvh_bootparams();
49+
boot_params_p->e820_entries = memmap.nr_entries;
10850
}

arch/x86/xen/xen-asm_64.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <asm/segment.h>
1313
#include <asm/asm-offsets.h>
1414
#include <asm/thread_info.h>
15+
#include <asm/asm.h>
1516

1617
#include <xen/interface/xen.h>
1718

@@ -24,6 +25,7 @@ ENTRY(xen_\name)
2425
pop %r11
2526
jmp \name
2627
END(xen_\name)
28+
_ASM_NOKPROBE(xen_\name)
2729
.endm
2830

2931
xen_pv_trap divide_error

drivers/gpu/drm/xen/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ config DRM_XEN_FRONTEND
1212
select DRM_KMS_HELPER
1313
select VIDEOMODE_HELPERS
1414
select XEN_XENBUS_FRONTEND
15+
select XEN_FRONT_PGDIR_SHBUF
1516
help
1617
Choose this option if you want to enable a para-virtualized
1718
frontend DRM/KMS driver for Xen guest OSes.

drivers/gpu/drm/xen/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ drm_xen_front-objs := xen_drm_front.o \
44
xen_drm_front_kms.o \
55
xen_drm_front_conn.o \
66
xen_drm_front_evtchnl.o \
7-
xen_drm_front_shbuf.o \
87
xen_drm_front_cfg.o \
98
xen_drm_front_gem.o
109

0 commit comments

Comments
 (0)