Message ID | 20210707181506.30489-4-brijesh.singh@amd.com (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | Herbert Xu |
Headers | show |
Series | Add AMD Secure Nested Paging (SEV-SNP) Guest Support | expand |
On Wed, Jul 07, 2021 at 01:14:33PM -0500, Brijesh Singh wrote: > diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h > index 11b7d9cea775..23929a3010df 100644 > --- a/arch/x86/include/asm/sev-common.h > +++ b/arch/x86/include/asm/sev-common.h > @@ -45,6 +45,15 @@ > (((unsigned long)reg & GHCB_MSR_CPUID_REG_MASK) << GHCB_MSR_CPUID_REG_POS) | \ > (((unsigned long)fn) << GHCB_MSR_CPUID_FUNC_POS)) > > +/* GHCB Hypervisor Feature Request */ > +#define GHCB_MSR_HV_FT_REQ 0x080 > +#define GHCB_MSR_HV_FT_RESP 0x081 > +#define GHCB_MSR_HV_FT_POS 12 > +#define GHCB_MSR_HV_FT_MASK GENMASK_ULL(51, 0) > + > +#define GHCB_MSR_HV_FT_RESP_VAL(v) \ > + (((unsigned long)((v) >> GHCB_MSR_HV_FT_POS) & GHCB_MSR_HV_FT_MASK)) As I suggested... > @@ -215,6 +216,7 @@ > { SVM_VMGEXIT_NMI_COMPLETE, "vmgexit_nmi_complete" }, \ > { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, \ > { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, \ > + { SVM_VMGEXIT_HYPERVISOR_FEATURES, "vmgexit_hypervisor_feature" }, \ SVM_VMGEXIT_HV_FEATURES > { SVM_EXIT_ERR, "invalid_guest_state" } > > > diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c > index 19c2306ac02d..34821da5f05e 100644 > --- a/arch/x86/kernel/sev-shared.c > +++ b/arch/x86/kernel/sev-shared.c > @@ -23,6 +23,9 @@ > */ > static u16 ghcb_version __section(".data..ro_after_init"); > > +/* Bitmap of SEV features supported by the hypervisor */ > +u64 sev_hv_features __section(".data..ro_after_init") = 0; __ro_after_init > diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c > index 66b7f63ad041..540b81ac54c9 100644 > --- a/arch/x86/kernel/sev.c > +++ b/arch/x86/kernel/sev.c > @@ -96,6 +96,9 @@ struct ghcb_state { > static DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data); > DEFINE_STATIC_KEY_FALSE(sev_es_enable_key); > > +/* Bitmap of SEV features supported by the hypervisor */ > +EXPORT_SYMBOL(sev_hv_features); Why is this exported and why not a _GPL export?
On 8/10/21 6:22 AM, Borislav Petkov wrote: > > SVM_VMGEXIT_HV_FEATURES > Noted. >> >> +/* Bitmap of SEV features supported by the hypervisor */ >> +u64 sev_hv_features __section(".data..ro_after_init") = 0; > > __ro_after_init Noted. > >> diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c >> index 66b7f63ad041..540b81ac54c9 100644 >> --- a/arch/x86/kernel/sev.c >> +++ b/arch/x86/kernel/sev.c >> @@ -96,6 +96,9 @@ struct ghcb_state { >> static DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data); >> DEFINE_STATIC_KEY_FALSE(sev_es_enable_key); >> >> +/* Bitmap of SEV features supported by the hypervisor */ >> +EXPORT_SYMBOL(sev_hv_features); > > Why is this exported and why not a _GPL export? > I was thinking that some driver may need it in future, but nothing in my series needs it yet. I will drop it and we can revisit it later. -Brijesh
On Tue, Aug 10, 2021 at 08:39:02AM -0500, Brijesh Singh wrote: > I was thinking that some driver may need it in future, but nothing in my > series needs it yet. I will drop it and we can revisit it later. Yeah, please never do such exports in anticipation. And if we *ever* need them, they should be _GPL ones - not EXPORT_SYMBOL. And then the API needs to be discussed and potentially proper accessors added instead of exporting naked variables... Thx.
diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h index 9c80c68d75b5..8cc2fd308f65 100644 --- a/arch/x86/include/asm/mem_encrypt.h +++ b/arch/x86/include/asm/mem_encrypt.h @@ -20,6 +20,7 @@ extern u64 sme_me_mask; extern u64 sev_status; +extern u64 sev_hv_features; void sme_encrypt_execute(unsigned long encrypted_kernel_vaddr, unsigned long decrypted_kernel_vaddr, @@ -59,6 +60,7 @@ bool sev_es_active(void); #else /* !CONFIG_AMD_MEM_ENCRYPT */ #define sme_me_mask 0ULL +#define sev_hv_features 0ULL static inline void __init sme_early_encrypt(resource_size_t paddr, unsigned long size) { } diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h index 11b7d9cea775..23929a3010df 100644 --- a/arch/x86/include/asm/sev-common.h +++ b/arch/x86/include/asm/sev-common.h @@ -45,6 +45,15 @@ (((unsigned long)reg & GHCB_MSR_CPUID_REG_MASK) << GHCB_MSR_CPUID_REG_POS) | \ (((unsigned long)fn) << GHCB_MSR_CPUID_FUNC_POS)) +/* GHCB Hypervisor Feature Request */ +#define GHCB_MSR_HV_FT_REQ 0x080 +#define GHCB_MSR_HV_FT_RESP 0x081 +#define GHCB_MSR_HV_FT_POS 12 +#define GHCB_MSR_HV_FT_MASK GENMASK_ULL(51, 0) + +#define GHCB_MSR_HV_FT_RESP_VAL(v) \ + (((unsigned long)((v) >> GHCB_MSR_HV_FT_POS) & GHCB_MSR_HV_FT_MASK)) + #define GHCB_MSR_TERM_REQ 0x100 #define GHCB_MSR_TERM_REASON_SET_POS 12 #define GHCB_MSR_TERM_REASON_SET_MASK 0xf diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h index 7ec91b1359df..134a7c9d91b6 100644 --- a/arch/x86/include/asm/sev.h +++ b/arch/x86/include/asm/sev.h @@ -13,7 +13,7 @@ #include <asm/sev-common.h> #define GHCB_PROTOCOL_MIN 1ULL -#define GHCB_PROTOCOL_MAX 1ULL +#define GHCB_PROTOCOL_MAX 2ULL #define GHCB_DEFAULT_USAGE 0ULL #define VMGEXIT() { asm volatile("rep; vmmcall\n\r"); } diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h index 554f75fe013c..7fbc311e2de1 100644 --- a/arch/x86/include/uapi/asm/svm.h +++ b/arch/x86/include/uapi/asm/svm.h @@ -108,6 +108,7 @@ #define SVM_VMGEXIT_AP_JUMP_TABLE 0x80000005 #define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0 #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 +#define SVM_VMGEXIT_HYPERVISOR_FEATURES 0x8000fffd #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff #define SVM_EXIT_ERR -1 @@ -215,6 +216,7 @@ { SVM_VMGEXIT_NMI_COMPLETE, "vmgexit_nmi_complete" }, \ { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, \ { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, \ + { SVM_VMGEXIT_HYPERVISOR_FEATURES, "vmgexit_hypervisor_feature" }, \ { SVM_EXIT_ERR, "invalid_guest_state" } diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c index 19c2306ac02d..34821da5f05e 100644 --- a/arch/x86/kernel/sev-shared.c +++ b/arch/x86/kernel/sev-shared.c @@ -23,6 +23,9 @@ */ static u16 ghcb_version __section(".data..ro_after_init"); +/* Bitmap of SEV features supported by the hypervisor */ +u64 sev_hv_features __section(".data..ro_after_init") = 0; + static bool __init sev_es_check_cpu_features(void) { if (!has_cpuflag(X86_FEATURE_RDRAND)) { @@ -51,6 +54,22 @@ static void __noreturn sev_es_terminate(unsigned int reason) asm volatile("hlt\n" : : : "memory"); } +static bool get_hv_features(void) +{ + u64 val; + + sev_es_wr_ghcb_msr(GHCB_MSR_HV_FT_REQ); + VMGEXIT(); + + val = sev_es_rd_ghcb_msr(); + if (GHCB_RESP_CODE(val) != GHCB_MSR_HV_FT_RESP) + return false; + + sev_hv_features = GHCB_MSR_HV_FT_RESP_VAL(val); + + return true; +} + static bool sev_es_negotiate_protocol(void) { u64 val; @@ -69,6 +88,10 @@ static bool sev_es_negotiate_protocol(void) ghcb_version = min_t(size_t, GHCB_MSR_PROTO_MAX(val), GHCB_PROTOCOL_MAX); + /* The hypervisor features are available from version 2 onward. */ + if ((ghcb_version >= 2) && !get_hv_features()) + return false; + return true; } diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index 66b7f63ad041..540b81ac54c9 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -96,6 +96,9 @@ struct ghcb_state { static DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data); DEFINE_STATIC_KEY_FALSE(sev_es_enable_key); +/* Bitmap of SEV features supported by the hypervisor */ +EXPORT_SYMBOL(sev_hv_features); + /* Needed in vc_early_forward_exception */ void do_early_exception(struct pt_regs *regs, int trapnr);