Skip to content

Commit d3a9d7e

Browse files
dcuiliuw
authored andcommitted
x86/hyperv: Introduce a global variable hyperv_paravisor_present
The new variable hyperv_paravisor_present is set only when the VM is a SNP/TDX VM with the paravisor running: see ms_hyperv_init_platform(). We introduce hyperv_paravisor_present because we can not use ms_hyperv.paravisor_present in arch/x86/include/asm/mshyperv.h: struct ms_hyperv_info is defined in include/asm-generic/mshyperv.h, which is included at the end of arch/x86/include/asm/mshyperv.h, but at the beginning of arch/x86/include/asm/mshyperv.h, we would already need to use struct ms_hyperv_info in hv_do_hypercall(). We use hyperv_paravisor_present only in include/asm-generic/mshyperv.h, and use ms_hyperv.paravisor_present elsewhere. In the future, we'll introduce a hypercall function structure for different VM types, and at boot time, the right function pointers would be written into the structure so that runtime testing of TDX vs. SNP vs. normal will be avoided and hyperv_paravisor_present will no longer be needed. Call hv_vtom_init() when it's a VBS VM or when ms_hyperv.paravisor_present is true, i.e. the VM is a SNP VM or TDX VM with the paravisor. Enhance hv_vtom_init() for a TDX VM with the paravisor. In hv_common_cpu_init(), don't decrypt the hyperv_pcpu_input_arg for a TDX VM with the paravisor, just like we don't decrypt the page for a SNP VM with the paravisor. Signed-off-by: Dexuan Cui <decui@microsoft.com> Reviewed-by: Tianyu Lan <tiala@microsoft.com> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Signed-off-by: Wei Liu <wei.liu@kernel.org> Link: https://lore.kernel.org/r/20230824080712.30327-7-decui@microsoft.com
1 parent cceb4e0 commit d3a9d7e

File tree

7 files changed

+72
-22
lines changed

7 files changed

+72
-22
lines changed

arch/x86/hyperv/hv_init.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,8 +658,8 @@ bool hv_is_hyperv_initialized(void)
658658
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
659659
return false;
660660

661-
/* A TDX guest uses the GHCI call rather than hv_hypercall_pg. */
662-
if (hv_isolation_type_tdx())
661+
/* A TDX VM with no paravisor uses TDX GHCI call rather than hv_hypercall_pg */
662+
if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present)
663663
return true;
664664
/*
665665
* Verify that earlier initialization succeeded by checking

arch/x86/hyperv/ivm.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
248248
}
249249
EXPORT_SYMBOL_GPL(hv_ghcb_msr_read);
250250

251+
#endif /* CONFIG_AMD_MEM_ENCRYPT */
252+
253+
#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
251254
/*
252255
* hv_mark_gpa_visibility - Set pages visible to host via hvcall.
253256
*
@@ -368,6 +371,10 @@ static bool hv_is_private_mmio(u64 addr)
368371
return false;
369372
}
370373

374+
#endif /* defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST) */
375+
376+
#ifdef CONFIG_AMD_MEM_ENCRYPT
377+
371378
#define hv_populate_vmcb_seg(seg, gdtr_base) \
372379
do { \
373380
if (seg.selector) { \
@@ -495,15 +502,40 @@ int hv_snp_boot_ap(int cpu, unsigned long start_ip)
495502
return ret;
496503
}
497504

505+
#endif /* CONFIG_AMD_MEM_ENCRYPT */
506+
507+
#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
508+
498509
void __init hv_vtom_init(void)
499510
{
511+
enum hv_isolation_type type = hv_get_isolation_type();
512+
513+
switch (type) {
514+
case HV_ISOLATION_TYPE_VBS:
515+
fallthrough;
500516
/*
501517
* By design, a VM using vTOM doesn't see the SEV setting,
502518
* so SEV initialization is bypassed and sev_status isn't set.
503519
* Set it here to indicate a vTOM VM.
520+
*
521+
* Note: if CONFIG_AMD_MEM_ENCRYPT is not set, sev_status is
522+
* defined as 0ULL, to which we can't assigned a value.
504523
*/
505-
sev_status = MSR_AMD64_SNP_VTOM;
506-
cc_vendor = CC_VENDOR_AMD;
524+
#ifdef CONFIG_AMD_MEM_ENCRYPT
525+
case HV_ISOLATION_TYPE_SNP:
526+
sev_status = MSR_AMD64_SNP_VTOM;
527+
cc_vendor = CC_VENDOR_AMD;
528+
break;
529+
#endif
530+
531+
case HV_ISOLATION_TYPE_TDX:
532+
cc_vendor = CC_VENDOR_INTEL;
533+
break;
534+
535+
default:
536+
panic("hv_vtom_init: unsupported isolation type %d\n", type);
537+
}
538+
507539
cc_set_mask(ms_hyperv.shared_gpa_boundary);
508540
physical_mask &= ms_hyperv.shared_gpa_boundary - 1;
509541

@@ -516,7 +548,7 @@ void __init hv_vtom_init(void)
516548
mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK);
517549
}
518550

519-
#endif /* CONFIG_AMD_MEM_ENCRYPT */
551+
#endif /* defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST) */
520552

521553
enum hv_isolation_type hv_get_isolation_type(void)
522554
{

arch/x86/include/asm/mshyperv.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static inline unsigned char hv_get_nmi_reason(void)
4242

4343
#if IS_ENABLED(CONFIG_HYPERV)
4444
extern int hyperv_init_cpuhp;
45+
extern bool hyperv_paravisor_present;
4546

4647
extern void *hv_hypercall_pg;
4748

@@ -75,7 +76,7 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
7576
u64 hv_status;
7677

7778
#ifdef CONFIG_X86_64
78-
if (hv_isolation_type_tdx())
79+
if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
7980
return hv_tdx_hypercall(control, input_address, output_address);
8081

8182
if (hv_isolation_type_en_snp()) {
@@ -131,7 +132,7 @@ static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
131132
u64 hv_status;
132133

133134
#ifdef CONFIG_X86_64
134-
if (hv_isolation_type_tdx())
135+
if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
135136
return hv_tdx_hypercall(control, input1, 0);
136137

137138
if (hv_isolation_type_en_snp()) {
@@ -185,7 +186,7 @@ static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
185186
u64 hv_status;
186187

187188
#ifdef CONFIG_X86_64
188-
if (hv_isolation_type_tdx())
189+
if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
189190
return hv_tdx_hypercall(control, input1, input2);
190191

191192
if (hv_isolation_type_en_snp()) {
@@ -278,19 +279,23 @@ void hv_ghcb_msr_write(u64 msr, u64 value);
278279
void hv_ghcb_msr_read(u64 msr, u64 *value);
279280
bool hv_ghcb_negotiate_protocol(void);
280281
void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
281-
void hv_vtom_init(void);
282282
int hv_snp_boot_ap(int cpu, unsigned long start_ip);
283283
#else
284284
static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
285285
static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
286286
static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
287287
static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
288-
static inline void hv_vtom_init(void) {}
289288
static inline int hv_snp_boot_ap(int cpu, unsigned long start_ip) { return 0; }
290289
#endif
291290

292291
extern bool hv_isolation_type_snp(void);
293292

293+
#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
294+
void hv_vtom_init(void);
295+
#else
296+
static inline void hv_vtom_init(void) {}
297+
#endif
298+
294299
static inline bool hv_is_synic_reg(unsigned int reg)
295300
{
296301
return (reg >= HV_REGISTER_SCONTROL) &&

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ bool hv_root_partition;
4040
bool hv_nested;
4141
struct ms_hyperv_info ms_hyperv;
4242

43+
/* Used in modules via hv_do_hypercall(): see arch/x86/include/asm/mshyperv.h */
44+
bool hyperv_paravisor_present __ro_after_init;
45+
EXPORT_SYMBOL_GPL(hyperv_paravisor_present);
46+
4347
#if IS_ENABLED(CONFIG_HYPERV)
4448
static inline unsigned int hv_get_nested_reg(unsigned int reg)
4549
{
@@ -429,6 +433,8 @@ static void __init ms_hyperv_init_platform(void)
429433
ms_hyperv.shared_gpa_boundary =
430434
BIT_ULL(ms_hyperv.shared_gpa_boundary_bits);
431435

436+
hyperv_paravisor_present = !!ms_hyperv.paravisor_present;
437+
432438
pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n",
433439
ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b);
434440

@@ -526,8 +532,7 @@ static void __init ms_hyperv_init_platform(void)
526532

527533
#if IS_ENABLED(CONFIG_HYPERV)
528534
if ((hv_get_isolation_type() == HV_ISOLATION_TYPE_VBS) ||
529-
((hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP) &&
530-
ms_hyperv.paravisor_present))
535+
ms_hyperv.paravisor_present)
531536
hv_vtom_init();
532537
/*
533538
* Setup the hook to get control post apic initialization.

drivers/hv/connection.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,17 @@ void vmbus_set_event(struct vmbus_channel *channel)
484484

485485
++channel->sig_events;
486486

487-
if (hv_isolation_type_snp())
488-
hv_ghcb_hypercall(HVCALL_SIGNAL_EVENT, &channel->sig_event,
489-
NULL, sizeof(channel->sig_event));
490-
else
487+
if (ms_hyperv.paravisor_present) {
488+
if (hv_isolation_type_snp())
489+
hv_ghcb_hypercall(HVCALL_SIGNAL_EVENT, &channel->sig_event,
490+
NULL, sizeof(channel->sig_event));
491+
else if (hv_isolation_type_tdx())
492+
hv_tdx_hypercall(HVCALL_SIGNAL_EVENT | HV_HYPERCALL_FAST_BIT,
493+
channel->sig_event, 0);
494+
else
495+
WARN_ON_ONCE(1);
496+
} else {
491497
hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
498+
}
492499
}
493500
EXPORT_SYMBOL_GPL(vmbus_set_event);

drivers/hv/hv.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ int hv_synic_alloc(void)
109109
* Synic message and event pages are allocated by paravisor.
110110
* Skip these pages allocation here.
111111
*/
112-
if (!hv_isolation_type_snp() && !hv_root_partition) {
112+
if (!ms_hyperv.paravisor_present && !hv_root_partition) {
113113
hv_cpu->synic_message_page =
114114
(void *)get_zeroed_page(GFP_ATOMIC);
115115
if (hv_cpu->synic_message_page == NULL) {
@@ -226,7 +226,7 @@ void hv_synic_enable_regs(unsigned int cpu)
226226
simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP);
227227
simp.simp_enabled = 1;
228228

229-
if (hv_isolation_type_snp() || hv_root_partition) {
229+
if (ms_hyperv.paravisor_present || hv_root_partition) {
230230
/* Mask out vTOM bit. ioremap_cache() maps decrypted */
231231
u64 base = (simp.base_simp_gpa << HV_HYP_PAGE_SHIFT) &
232232
~ms_hyperv.shared_gpa_boundary;
@@ -245,7 +245,7 @@ void hv_synic_enable_regs(unsigned int cpu)
245245
siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP);
246246
siefp.siefp_enabled = 1;
247247

248-
if (hv_isolation_type_snp() || hv_root_partition) {
248+
if (ms_hyperv.paravisor_present || hv_root_partition) {
249249
/* Mask out vTOM bit. ioremap_cache() maps decrypted */
250250
u64 base = (siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT) &
251251
~ms_hyperv.shared_gpa_boundary;
@@ -328,7 +328,7 @@ void hv_synic_disable_regs(unsigned int cpu)
328328
* addresses.
329329
*/
330330
simp.simp_enabled = 0;
331-
if (hv_isolation_type_snp() || hv_root_partition) {
331+
if (ms_hyperv.paravisor_present || hv_root_partition) {
332332
iounmap(hv_cpu->synic_message_page);
333333
hv_cpu->synic_message_page = NULL;
334334
} else {
@@ -340,7 +340,7 @@ void hv_synic_disable_regs(unsigned int cpu)
340340
siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP);
341341
siefp.siefp_enabled = 0;
342342

343-
if (hv_isolation_type_snp() || hv_root_partition) {
343+
if (ms_hyperv.paravisor_present || hv_root_partition) {
344344
iounmap(hv_cpu->synic_event_page);
345345
hv_cpu->synic_event_page = NULL;
346346
} else {

drivers/hv/hv_common.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,8 @@ int hv_common_cpu_init(unsigned int cpu)
382382
*outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
383383
}
384384

385-
if (hv_isolation_type_en_snp() || hv_isolation_type_tdx()) {
385+
if (!ms_hyperv.paravisor_present &&
386+
(hv_isolation_type_en_snp() || hv_isolation_type_tdx())) {
386387
ret = set_memory_decrypted((unsigned long)mem, pgcount);
387388
if (ret) {
388389
/* It may be unsafe to free 'mem' */

0 commit comments

Comments
 (0)