-
Notifications
You must be signed in to change notification settings - Fork 21
drivers: hv: mshv_vtl: Support for Secure AVIC #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b62553c
d090e4f
f156598
029056b
aa4dc17
0955f99
aab4c1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -44,6 +44,7 @@ extern u64 hv_std_hypercall(u64 control, u64 param1, u64 param2); | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #if IS_ENABLED(CONFIG_HYPERV) | ||||||||||||||||||||||||||||||
| extern void *hv_hypercall_pg; | ||||||||||||||||||||||||||||||
| extern void *hv_vp_early_input_arg; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| extern union hv_ghcb * __percpu *hv_ghcb_pg; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -197,6 +198,7 @@ int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry); | |||||||||||||||||||||||||||||
| bool hv_ghcb_negotiate_protocol(void); | ||||||||||||||||||||||||||||||
| void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason); | ||||||||||||||||||||||||||||||
| int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu); | ||||||||||||||||||||||||||||||
| enum es_result hv_set_savic_backing_page(u64 gfn); | ||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||
| static inline bool hv_ghcb_negotiate_protocol(void) { return false; } | ||||||||||||||||||||||||||||||
| static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {} | ||||||||||||||||||||||||||||||
|
|
@@ -300,6 +302,20 @@ static inline void hv_vtl_idle(void) | |||||||||||||||||||||||||||||
| native_safe_halt(); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||||
| * Registers are only accessible via HVCALL_GET_VP_REGISTERS hvcall and | ||||||||||||||||||||||||||||||
| * there is not associated MSR address. | ||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||
| #ifndef HV_X64_REGISTER_VSM_VP_STATUS | ||||||||||||||||||||||||||||||
| #define HV_X64_REGISTER_VSM_VP_STATUS 0x000D0003 | ||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||
| #ifndef HV_X64_VTL_MASK | ||||||||||||||||||||||||||||||
| #define HV_X64_VTL_MASK GENMASK(3, 0) | ||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||
| #ifndef HV_X64_REGISTER_SEV_AVIC_GPA | ||||||||||||||||||||||||||||||
| #define HV_X64_REGISTER_SEV_AVIC_GPA 0x00090043 | ||||||||||||||||||||||||||||||
|
Comment on lines
+308
to
+316
|
||||||||||||||||||||||||||||||
| */ | |
| #define HV_X64_REGISTER_VSM_VP_STATUS 0x000D0003 | |
| #define HV_X64_VTL_MASK GENMASK(3, 0) | |
| #define HV_X64_REGISTER_SEV_AVIC_GPA 0x00090043 | |
| */ | |
| #ifndef HV_X64_REGISTER_VSM_VP_STATUS | |
| #define HV_X64_REGISTER_VSM_VP_STATUS 0x000D0003 | |
| #endif | |
| #ifndef HV_X64_VTL_MASK | |
| #define HV_X64_VTL_MASK GENMASK(3, 0) | |
| #endif | |
| #ifndef HV_X64_REGISTER_SEV_AVIC_GPA | |
| #define HV_X64_REGISTER_SEV_AVIC_GPA 0x00090043 | |
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
|
|
||
| #include <asm/apic.h> | ||
| #include <asm/sev.h> | ||
| #include <asm/mshyperv.h> | ||
|
|
||
| #include "local.h" | ||
|
|
||
|
|
@@ -330,6 +331,18 @@ static void savic_eoi(void) | |
| } | ||
| } | ||
|
|
||
| void x2apic_savic_init_backing_page(void *ap) | ||
| { | ||
| u32 apic_id; | ||
|
|
||
| /* | ||
| * Before Secure AVIC is enabled, APIC msr reads are intercepted. | ||
| * APIC_ID msr read returns the value from the Hypervisor. | ||
| */ | ||
| apic_id = native_apic_msr_read(APIC_ID); | ||
| apic_set_reg(ap, APIC_ID, apic_id); | ||
| } | ||
|
|
||
| static void savic_teardown(void) | ||
| { | ||
| /* Disable Secure AVIC */ | ||
|
|
@@ -342,15 +355,16 @@ static void savic_setup(void) | |
| void *ap = this_cpu_ptr(savic_page); | ||
| enum es_result res; | ||
| unsigned long gpa; | ||
| unsigned long gfn; | ||
|
|
||
| /* | ||
| * Before Secure AVIC is enabled, APIC MSR reads are intercepted. | ||
| * APIC_ID MSR read returns the value from the hypervisor. | ||
| */ | ||
| apic_set_reg(ap, APIC_ID, native_apic_msr_read(APIC_ID)); | ||
| if (!cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) | ||
| return; | ||
|
|
||
| x2apic_savic_init_backing_page(ap); | ||
| gpa = __pa(ap); | ||
|
|
||
| gfn = gpa >> PAGE_SHIFT; | ||
|
|
||
| /* | ||
| * The NPT entry for a vCPU's APIC backing page must always be | ||
| * present when the vCPU is running in order for Secure AVIC to | ||
|
|
@@ -361,7 +375,11 @@ static void savic_setup(void) | |
| * VMRUN, the hypervisor makes use of this information to make sure | ||
| * the APIC backing page is mapped in NPT. | ||
| */ | ||
| res = savic_register_gpa(gpa); | ||
| if (hv_isolation_type_snp()) | ||
| res = hv_set_savic_backing_page(gfn); | ||
| else | ||
| res = savic_register_gpa(gpa); | ||
|
|
||
| if (res != ES_OK) | ||
| sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SAVIC_FAIL); | ||
|
Comment on lines
355
to
384
|
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hv_vp_early_input_argis allocated with kcalloc() and then passed to set_memory_decrypted(). set_memory_decrypted() warns and rounds down misaligned addresses, so this needs a PAGE_SIZE-aligned allocation to avoid converting the wrong pages. Consider allocating with a page-aligned API (e.g., __get_free_pages()/alloc_pages_exact()) rather than kcalloc().