Skip to content

Commit 44261f8

Browse files
committed
Merge tag 'hyperv-next-signed-20211102' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux
Pull hyperv updates from Wei Liu: - Initial patch set for Hyper-V isolation VM support (Tianyu Lan) - Fix a warning on preemption (Vitaly Kuznetsov) - A bunch of misc cleanup patches * tag 'hyperv-next-signed-20211102' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: x86/hyperv: Protect set_hv_tscchange_cb() against getting preempted Drivers: hv : vmbus: Adding NULL pointer check x86/hyperv: Remove duplicate include x86/hyperv: Remove duplicated include in hv_init Drivers: hv: vmbus: Remove unused code to check for subchannels Drivers: hv: vmbus: Initialize VMbus ring buffer for Isolation VM Drivers: hv: vmbus: Add SNP support for VMbus channel initiate message x86/hyperv: Add ghcb hvcall support for SNP VM x86/hyperv: Add Write/Read MSR registers via ghcb page Drivers: hv: vmbus: Mark vmbus ring buffer visible to host in Isolation VM x86/hyperv: Add new hvcall guest address host visibility support x86/hyperv: Initialize shared memory boundary in the Isolation VM. x86/hyperv: Initialize GHCB page in Isolation VM
2 parents 0aaa58e + 285f68a commit 44261f8

File tree

21 files changed

+761
-172
lines changed

21 files changed

+761
-172
lines changed

arch/x86/hyperv/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0-only
2-
obj-y := hv_init.o mmu.o nested.o irqdomain.o
2+
obj-y := hv_init.o mmu.o nested.o irqdomain.o ivm.o
33
obj-$(CONFIG_X86_64) += hv_apic.o hv_proc.o
44

55
ifdef CONFIG_X86_64

arch/x86/hyperv/hv_init.c

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,42 @@ EXPORT_SYMBOL_GPL(hv_current_partition_id);
3636
void *hv_hypercall_pg;
3737
EXPORT_SYMBOL_GPL(hv_hypercall_pg);
3838

39+
union hv_ghcb __percpu **hv_ghcb_pg;
40+
3941
/* Storage to save the hypercall page temporarily for hibernation */
4042
static void *hv_hypercall_pg_saved;
4143

4244
struct hv_vp_assist_page **hv_vp_assist_page;
4345
EXPORT_SYMBOL_GPL(hv_vp_assist_page);
4446

47+
static int hyperv_init_ghcb(void)
48+
{
49+
u64 ghcb_gpa;
50+
void *ghcb_va;
51+
void **ghcb_base;
52+
53+
if (!hv_isolation_type_snp())
54+
return 0;
55+
56+
if (!hv_ghcb_pg)
57+
return -EINVAL;
58+
59+
/*
60+
* GHCB page is allocated by paravisor. The address
61+
* returned by MSR_AMD64_SEV_ES_GHCB is above shared
62+
* memory boundary and map it here.
63+
*/
64+
rdmsrl(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa);
65+
ghcb_va = memremap(ghcb_gpa, HV_HYP_PAGE_SIZE, MEMREMAP_WB);
66+
if (!ghcb_va)
67+
return -ENOMEM;
68+
69+
ghcb_base = (void **)this_cpu_ptr(hv_ghcb_pg);
70+
*ghcb_base = ghcb_va;
71+
72+
return 0;
73+
}
74+
4575
static int hv_cpu_init(unsigned int cpu)
4676
{
4777
union hv_vp_assist_msr_contents msr = { 0 };
@@ -85,7 +115,7 @@ static int hv_cpu_init(unsigned int cpu)
85115
}
86116
}
87117

88-
return 0;
118+
return hyperv_init_ghcb();
89119
}
90120

91121
static void (*hv_reenlightenment_cb)(void);
@@ -139,7 +169,6 @@ void set_hv_tscchange_cb(void (*cb)(void))
139169
struct hv_reenlightenment_control re_ctrl = {
140170
.vector = HYPERV_REENLIGHTENMENT_VECTOR,
141171
.enabled = 1,
142-
.target_vp = hv_vp_index[smp_processor_id()]
143172
};
144173
struct hv_tsc_emulation_control emu_ctrl = {.enabled = 1};
145174

@@ -153,8 +182,12 @@ void set_hv_tscchange_cb(void (*cb)(void))
153182
/* Make sure callback is registered before we write to MSRs */
154183
wmb();
155184

185+
re_ctrl.target_vp = hv_vp_index[get_cpu()];
186+
156187
wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
157188
wrmsrl(HV_X64_MSR_TSC_EMULATION_CONTROL, *((u64 *)&emu_ctrl));
189+
190+
put_cpu();
158191
}
159192
EXPORT_SYMBOL_GPL(set_hv_tscchange_cb);
160193

@@ -177,6 +210,14 @@ static int hv_cpu_die(unsigned int cpu)
177210
{
178211
struct hv_reenlightenment_control re_ctrl;
179212
unsigned int new_cpu;
213+
void **ghcb_va;
214+
215+
if (hv_ghcb_pg) {
216+
ghcb_va = (void **)this_cpu_ptr(hv_ghcb_pg);
217+
if (*ghcb_va)
218+
memunmap(*ghcb_va);
219+
*ghcb_va = NULL;
220+
}
180221

181222
hv_common_cpu_die(cpu);
182223

@@ -366,10 +407,16 @@ void __init hyperv_init(void)
366407
goto common_free;
367408
}
368409

410+
if (hv_isolation_type_snp()) {
411+
hv_ghcb_pg = alloc_percpu(union hv_ghcb *);
412+
if (!hv_ghcb_pg)
413+
goto free_vp_assist_page;
414+
}
415+
369416
cpuhp = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv_init:online",
370417
hv_cpu_init, hv_cpu_die);
371418
if (cpuhp < 0)
372-
goto free_vp_assist_page;
419+
goto free_ghcb_page;
373420

374421
/*
375422
* Setup the hypercall page and enable hypercalls.
@@ -379,14 +426,15 @@ void __init hyperv_init(void)
379426
guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
380427
wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id);
381428

429+
/* Hyper-V requires to write guest os id via ghcb in SNP IVM. */
430+
hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, guest_id);
431+
382432
hv_hypercall_pg = __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START,
383433
VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX,
384434
VM_FLUSH_RESET_PERMS, NUMA_NO_NODE,
385435
__builtin_return_address(0));
386-
if (hv_hypercall_pg == NULL) {
387-
wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
388-
goto remove_cpuhp_state;
389-
}
436+
if (hv_hypercall_pg == NULL)
437+
goto clean_guest_os_id;
390438

391439
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
392440
hypercall_msr.enable = 1;
@@ -456,8 +504,12 @@ void __init hyperv_init(void)
456504
hv_query_ext_cap(0);
457505
return;
458506

459-
remove_cpuhp_state:
507+
clean_guest_os_id:
508+
wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
509+
hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
460510
cpuhp_remove_state(cpuhp);
511+
free_ghcb_page:
512+
free_percpu(hv_ghcb_pg);
461513
free_vp_assist_page:
462514
kfree(hv_vp_assist_page);
463515
hv_vp_assist_page = NULL;
@@ -476,6 +528,7 @@ void hyperv_cleanup(void)
476528

477529
/* Reset our OS id */
478530
wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
531+
hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
479532

480533
/*
481534
* Reset hypercall page reference before reset the page,
@@ -546,16 +599,3 @@ bool hv_is_hyperv_initialized(void)
546599
return hypercall_msr.enable;
547600
}
548601
EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
549-
550-
enum hv_isolation_type hv_get_isolation_type(void)
551-
{
552-
if (!(ms_hyperv.priv_high & HV_ISOLATION))
553-
return HV_ISOLATION_TYPE_NONE;
554-
return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b);
555-
}
556-
EXPORT_SYMBOL_GPL(hv_get_isolation_type);
557-
558-
bool hv_is_isolation_supported(void)
559-
{
560-
return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE;
561-
}

0 commit comments

Comments
 (0)