Skip to content

Commit bc56695

Browse files
authored
drivers: hv: Support for SNP Secure AVIC
2 parents ec12dfc + 4d255b3 commit bc56695

17 files changed

Lines changed: 782 additions & 226 deletions

File tree

Microsoft/hcl-x64.config

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,20 @@
22
# Automatically generated file; DO NOT EDIT.
33
# Linux/x86_64 6.18.0 Kernel Configuration
44
#
5-
CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
5+
CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0"
66
CONFIG_CC_IS_GCC=y
7-
CONFIG_GCC_VERSION=130300
7+
CONFIG_GCC_VERSION=90400
88
CONFIG_CLANG_VERSION=0
99
CONFIG_AS_IS_GNU=y
10-
CONFIG_AS_VERSION=24200
10+
CONFIG_AS_VERSION=23400
1111
CONFIG_LD_IS_BFD=y
12-
CONFIG_LD_VERSION=24200
12+
CONFIG_LD_VERSION=23400
1313
CONFIG_LLD_VERSION=0
14-
CONFIG_RUSTC_VERSION=109101
15-
CONFIG_RUSTC_LLVM_VERSION=210102
14+
CONFIG_RUSTC_VERSION=109500
15+
CONFIG_RUSTC_LLVM_VERSION=220102
1616
CONFIG_CC_CAN_LINK=y
17-
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
18-
CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
19-
CONFIG_TOOLS_SUPPORT_RELR=y
17+
CONFIG_GCC_ASM_GOTO_OUTPUT_BROKEN=y
2018
CONFIG_CC_HAS_ASM_INLINE=y
21-
CONFIG_CC_HAS_ASSUME=y
2219
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
2320
CONFIG_LD_CAN_USE_KEEP_IN_OVERLAY=y
2421
CONFIG_RUSTC_HAS_COERCE_POINTEE=y
@@ -305,6 +302,7 @@ CONFIG_ARCH_CPUIDLE_HALTPOLL=y
305302
# CONFIG_JAILHOUSE_GUEST is not set
306303
# CONFIG_ACRN_GUEST is not set
307304
# CONFIG_BHYVE_GUEST is not set
305+
# CONFIG_INTEL_TDX_GUEST is not set
308306
CONFIG_CC_HAS_MARCH_NATIVE=y
309307
# CONFIG_X86_NATIVE_CPU is not set
310308
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
@@ -356,6 +354,7 @@ CONFIG_MICROCODE=y
356354
CONFIG_X86_MSR=y
357355
# CONFIG_X86_CPUID is not set
358356
CONFIG_X86_DIRECT_GBPAGES=y
357+
# CONFIG_AMD_MEM_ENCRYPT is not set
359358
CONFIG_NUMA=y
360359
CONFIG_AMD_NUMA=y
361360
CONFIG_NODES_SHIFT=6
@@ -410,26 +409,16 @@ CONFIG_X86_BUS_LOCK_DETECT=y
410409
CONFIG_CC_HAS_NAMED_AS=y
411410
CONFIG_CC_HAS_NAMED_AS_FIXED_SANITIZERS=y
412411
CONFIG_USE_X86_SEG_SUPPORT=y
413-
CONFIG_CC_HAS_SLS=y
414412
CONFIG_CC_HAS_RETURN_THUNK=y
415413
CONFIG_CC_HAS_ENTRY_PADDING=y
416414
CONFIG_FUNCTION_PADDING_CFI=11
417415
CONFIG_FUNCTION_PADDING_BYTES=16
418-
CONFIG_CALL_PADDING=y
419-
CONFIG_HAVE_CALL_THUNKS=y
420-
CONFIG_CALL_THUNKS=y
421-
CONFIG_PREFIX_SYMBOLS=y
422416
CONFIG_CPU_MITIGATIONS=y
423417
# CONFIG_MITIGATION_PAGE_TABLE_ISOLATION is not set
424418
CONFIG_MITIGATION_RETPOLINE=y
425419
# CONFIG_MITIGATION_RETHUNK is not set
426-
# CONFIG_MITIGATION_UNRET_ENTRY is not set
427-
# CONFIG_MITIGATION_CALL_DEPTH_TRACKING is not set
428-
# CONFIG_CALL_THUNKS_DEBUG is not set
429420
CONFIG_MITIGATION_IBPB_ENTRY=y
430421
CONFIG_MITIGATION_IBRS_ENTRY=y
431-
# CONFIG_MITIGATION_SRSO is not set
432-
# CONFIG_MITIGATION_SLS is not set
433422
# CONFIG_MITIGATION_GDS is not set
434423
# CONFIG_MITIGATION_RFDS is not set
435424
# CONFIG_MITIGATION_SPECTRE_BHI is not set
@@ -442,7 +431,6 @@ CONFIG_MITIGATION_IBRS_ENTRY=y
442431
# CONFIG_MITIGATION_SPECTRE_V2 is not set
443432
# CONFIG_MITIGATION_SRBDS is not set
444433
# CONFIG_MITIGATION_SSB is not set
445-
# CONFIG_MITIGATION_ITS is not set
446434
# CONFIG_MITIGATION_TSA is not set
447435
CONFIG_ARCH_HAS_ADD_PAGES=y
448436

@@ -471,7 +459,6 @@ CONFIG_ARCH_SUPPORTS_ACPI=y
471459
# Bus options (PCI etc.)
472460
#
473461
CONFIG_PCI_DIRECT=y
474-
# CONFIG_PCI_CNB20LE_QUIRK is not set
475462
# CONFIG_ISA_BUS is not set
476463
# CONFIG_ISA_DMA_API is not set
477464
CONFIG_AMD_NB=y
@@ -508,6 +495,9 @@ CONFIG_X86_DISABLED_FEATURE_CENTAUR_MCR=y
508495
CONFIG_X86_DISABLED_FEATURE_PKU=y
509496
CONFIG_X86_DISABLED_FEATURE_OSPKE=y
510497
CONFIG_X86_DISABLED_FEATURE_PTI=y
498+
CONFIG_X86_DISABLED_FEATURE_RETHUNK=y
499+
CONFIG_X86_DISABLED_FEATURE_UNRET=y
500+
CONFIG_X86_DISABLED_FEATURE_CALL_DEPTH=y
511501
CONFIG_X86_DISABLED_FEATURE_LAM=y
512502
CONFIG_X86_DISABLED_FEATURE_ENQCMD=y
513503
CONFIG_X86_DISABLED_FEATURE_SGX=y
@@ -544,6 +534,7 @@ CONFIG_JUMP_LABEL=y
544534
# CONFIG_STATIC_CALL_SELFTEST is not set
545535
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
546536
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
537+
CONFIG_USER_RETURN_NOTIFIER=y
547538
CONFIG_HAVE_IOREMAP_PROT=y
548539
CONFIG_HAVE_KPROBES=y
549540
CONFIG_HAVE_KRETPROBES=y
@@ -1909,16 +1900,9 @@ CONFIG_DEFAULT_SECURITY_DAC=y
19091900
#
19101901
# Memory initialization
19111902
#
1912-
CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y
1913-
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y
1914-
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y
19151903
CONFIG_INIT_STACK_NONE=y
1916-
# CONFIG_INIT_STACK_ALL_PATTERN is not set
1917-
# CONFIG_INIT_STACK_ALL_ZERO is not set
19181904
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
19191905
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
1920-
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
1921-
# CONFIG_ZERO_CALL_USED_REGS is not set
19221906
# end of Memory initialization
19231907

19241908
#
@@ -2213,7 +2197,6 @@ CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
22132197
# CONFIG_DEBUG_INFO_REDUCED is not set
22142198
CONFIG_DEBUG_INFO_COMPRESSED_NONE=y
22152199
# CONFIG_DEBUG_INFO_COMPRESSED_ZLIB is not set
2216-
# CONFIG_DEBUG_INFO_COMPRESSED_ZSTD is not set
22172200
# CONFIG_DEBUG_INFO_SPLIT is not set
22182201
CONFIG_GDB_SCRIPTS=y
22192202
CONFIG_FRAME_WARN=2048
@@ -2242,8 +2225,6 @@ CONFIG_HAVE_ARCH_KGDB=y
22422225
CONFIG_ARCH_HAS_UBSAN=y
22432226
# CONFIG_UBSAN is not set
22442227
CONFIG_HAVE_ARCH_KCSAN=y
2245-
CONFIG_HAVE_KCSAN_COMPILER=y
2246-
# CONFIG_KCSAN is not set
22472228
# end of Generic Kernel Debugging Instruments
22482229

22492230
#

arch/x86/hyperv/hv_apic.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/clockchips.h>
2626
#include <linux/slab.h>
2727
#include <linux/cpuhotplug.h>
28+
#include <linux/cc_platform.h>
2829
#include <asm/hypervisor.h>
2930
#include <asm/mshyperv.h>
3031
#include <asm/apic.h>
@@ -53,6 +54,11 @@ static void hv_apic_icr_write(u32 low, u32 id)
5354
wrmsrq(HV_X64_MSR_ICR, reg_val);
5455
}
5556

57+
void hv_enable_coco_interrupt(unsigned int cpu, unsigned int vector, bool set)
58+
{
59+
apic_update_vector(cpu, vector, set);
60+
}
61+
5662
static u32 hv_apic_read(u32 reg)
5763
{
5864
u32 reg_val, hi;
@@ -293,6 +299,9 @@ static void hv_send_ipi_self(int vector)
293299

294300
void __init hv_apic_init(void)
295301
{
302+
if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
303+
return;
304+
296305
if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
297306
pr_info("Hyper-V: Using IPI hypercalls\n");
298307
/*

arch/x86/hyperv/hv_init.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static inline void hv_set_hypercall_pg(void *ptr)
7676
EXPORT_SYMBOL_GPL(hv_hypercall_pg);
7777
#endif
7878

79+
void *hv_vp_early_input_arg;
7980
union hv_ghcb * __percpu *hv_ghcb_pg;
8081

8182
/* Storage to save the hypercall page temporarily for hibernation */
@@ -120,6 +121,10 @@ static int hv_cpu_init(unsigned int cpu)
120121
if (ret)
121122
return ret;
122123

124+
/* Allow Hyper-V stimer vector to be injected from Hypervisor. */
125+
if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE)
126+
apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, true);
127+
123128
return hyperv_init_ghcb();
124129
}
125130

@@ -227,6 +232,9 @@ static int hv_cpu_die(unsigned int cpu)
227232
*ghcb_va = NULL;
228233
}
229234

235+
if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE)
236+
apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, false);
237+
230238
hv_common_cpu_die(cpu);
231239

232240
if (hv_reenlightenment_cb == NULL)
@@ -375,13 +383,32 @@ void __init hyperv_init(void)
375383
u64 guest_id;
376384
union hv_x64_msr_hypercall_contents hypercall_msr;
377385
int cpuhp;
386+
int ret;
378387

379388
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
380389
return;
381390

382391
if (hv_common_init())
383392
return;
384393

394+
if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) {
395+
hv_vp_early_input_arg = (void *)__get_free_pages(
396+
GFP_KERNEL | __GFP_ZERO,
397+
get_order(num_possible_cpus() * PAGE_SIZE));
398+
if (hv_vp_early_input_arg) {
399+
ret = set_memory_decrypted((u64)hv_vp_early_input_arg,
400+
num_possible_cpus());
401+
if (ret) {
402+
free_pages((unsigned long)hv_vp_early_input_arg,
403+
get_order(num_possible_cpus() * PAGE_SIZE));
404+
hv_vp_early_input_arg = NULL;
405+
goto common_free;
406+
}
407+
} else {
408+
goto common_free;
409+
}
410+
}
411+
385412
if (ms_hyperv.paravisor_present && hv_isolation_type_snp()) {
386413
/* Negotiate GHCB Version. */
387414
if (!hv_ghcb_negotiate_protocol())
@@ -519,6 +546,16 @@ void __init hyperv_init(void)
519546
free_vp_assist_page:
520547
kfree(hv_vp_assist_page);
521548
hv_vp_assist_page = NULL;
549+
free_vp_early_input_arg:
550+
if (hv_vp_early_input_arg) {
551+
set_memory_encrypted((u64)hv_vp_early_input_arg,
552+
num_possible_cpus());
553+
free_pages((unsigned long)hv_vp_early_input_arg,
554+
get_order(num_possible_cpus() * PAGE_SIZE));
555+
hv_vp_early_input_arg = NULL;
556+
}
557+
common_free:
558+
hv_common_free();
522559
}
523560

524561
/*

arch/x86/hyperv/ivm.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,45 @@ static void snp_cleanup_vmsa(struct sev_es_save_area *vmsa)
291291
free_page((unsigned long)vmsa);
292292
}
293293

294+
enum es_result hv_set_savic_backing_page(u64 gfn)
295+
{
296+
u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_SET_VP_REGISTERS;
297+
struct hv_set_vp_registers_input *input =
298+
(struct hv_set_vp_registers_input *)
299+
((u8 *)hv_vp_early_input_arg + smp_processor_id() * PAGE_SIZE);
300+
union hv_x64_register_sev_gpa_page value;
301+
unsigned long flags;
302+
int retry = 5;
303+
u64 ret;
304+
305+
local_irq_save(flags);
306+
307+
value.enabled = 1;
308+
value.reserved = 0;
309+
value.pagenumber = gfn;
310+
311+
memset(input, 0, struct_size(input, element, 1));
312+
input->header.partitionid = HV_PARTITION_ID_SELF;
313+
input->header.vpindex = HV_VP_INDEX_SELF;
314+
input->header.inputvtl = ms_hyperv.vtl;
315+
input->element[0].name = HV_X64_REGISTER_SEV_AVIC_GPA;
316+
input->element[0].value.reg64 = value.u64;
317+
318+
do {
319+
ret = hv_do_hypercall(control, input, NULL);
320+
} while (ret == HV_STATUS_TIME_OUT && retry--);
321+
322+
if (!hv_result_success(ret))
323+
pr_err("Failed to set secure AVIC backing page %llx.\n", ret);
324+
325+
local_irq_restore(flags);
326+
327+
if (hv_result_success(ret))
328+
return ES_OK;
329+
else
330+
return ES_VMM_ERROR;
331+
}
332+
294333
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu)
295334
{
296335
struct sev_es_save_area *vmsa = (struct sev_es_save_area *)

arch/x86/include/asm/apic.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@ static inline u64 native_x2apic_icr_read(void)
241241
return val;
242242
}
243243

244+
#if defined(CONFIG_AMD_SECURE_AVIC)
245+
extern void x2apic_savic_init_backing_page(void *backing_page);
246+
#else
247+
static inline void x2apic_savic_init_backing_page(void *backing_page) {}
248+
#endif
249+
244250
extern int x2apic_mode;
245251
extern int x2apic_phys;
246252
extern void __init x2apic_set_max_apicid(u32 apicid);

arch/x86/include/asm/mshyperv.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extern u64 hv_std_hypercall(u64 control, u64 param1, u64 param2);
4444

4545
#if IS_ENABLED(CONFIG_HYPERV)
4646
extern void *hv_hypercall_pg;
47+
extern void *hv_vp_early_input_arg;
4748

4849
extern union hv_ghcb * __percpu *hv_ghcb_pg;
4950

@@ -197,6 +198,7 @@ int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
197198
bool hv_ghcb_negotiate_protocol(void);
198199
void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
199200
int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu);
201+
enum es_result hv_set_savic_backing_page(u64 gfn);
200202
#else
201203
static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
202204
static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
@@ -300,6 +302,20 @@ static inline void hv_vtl_idle(void)
300302
native_safe_halt();
301303
}
302304

305+
/*
306+
* Registers are only accessible via HVCALL_GET_VP_REGISTERS hvcall and
307+
* there is not associated MSR address.
308+
*/
309+
#ifndef HV_X64_REGISTER_VSM_VP_STATUS
310+
#define HV_X64_REGISTER_VSM_VP_STATUS 0x000D0003
311+
#endif
312+
#ifndef HV_X64_VTL_MASK
313+
#define HV_X64_VTL_MASK GENMASK(3, 0)
314+
#endif
315+
#ifndef HV_X64_REGISTER_SEV_AVIC_GPA
316+
#define HV_X64_REGISTER_SEV_AVIC_GPA 0x00090043
317+
#endif
318+
303319
#ifdef CONFIG_HYPERV_VTL_MODE
304320
void __init hv_vtl_init_platform(void);
305321
int __init hv_vtl_early_init(void);

arch/x86/include/asm/sev.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,12 @@ struct rmp_state {
141141
u32 asid;
142142
} __packed;
143143

144-
#define RMPADJUST_VMSA_PAGE_BIT BIT(16)
144+
/* Target VMPL takes the first byte */
145+
#define RMPADJUST_ENABLE_READ BIT(8)
146+
#define RMPADJUST_ENABLE_WRITE BIT(9)
147+
#define RMPADJUST_USER_EXECUTE BIT(10)
148+
#define RMPADJUST_KERNEL_EXECUTE BIT(11)
149+
#define RMPADJUST_VMSA_PAGE_BIT BIT(16)
145150

146151
/* SNP Guest message request */
147152
struct snp_req_data {

arch/x86/include/asm/svm.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
190190
#define V_GIF_SHIFT 9
191191
#define V_GIF_MASK (1 << V_GIF_SHIFT)
192192

193+
#define V_INT_SHADOW_SHIFT 10
194+
#define V_INT_SHADOW_MASK (1 << V_INT_SHADOW_SHIFT)
195+
193196
#define V_NMI_PENDING_SHIFT 11
194197
#define V_NMI_PENDING_MASK (1 << V_NMI_PENDING_SHIFT)
195198

@@ -202,6 +205,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
202205
#define V_IGN_TPR_SHIFT 20
203206
#define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT)
204207

208+
#define V_GUEST_BUSY_SHIFT 63
209+
#define V_GUEST_BUSY_MASK (1ULL << V_GUEST_BUSY_SHIFT)
210+
205211
#define V_IRQ_INJECTION_BITS_MASK (V_IRQ_MASK | V_INTR_PRIO_MASK | V_IGN_TPR_MASK)
206212

207213
#define V_INTR_MASKING_SHIFT 24

0 commit comments

Comments
 (0)