On 5/11/21 4:23 AM, Borislav Petkov wrote: > On Fri, Apr 30, 2021 at 07:15:58AM -0500, Brijesh Singh wrote: >> The SEV-ES guest calls the sev_es_negotiate_protocol() to negotiate the >> GHCB protocol version before establishing the GHCB. Cache the negotiated >> GHCB version so that it can be used later. >> >> Signed-off-by: Brijesh Singh <brijesh.singh@xxxxxxx> >> --- >> arch/x86/include/asm/sev.h | 2 +- >> arch/x86/kernel/sev-shared.c | 15 ++++++++++++--- >> 2 files changed, 13 insertions(+), 4 deletions(-) >> >> diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h >> index fa5cd05d3b5b..7ec91b1359df 100644 >> --- a/arch/x86/include/asm/sev.h >> +++ b/arch/x86/include/asm/sev.h >> @@ -12,7 +12,7 @@ >> #include <asm/insn.h> >> #include <asm/sev-common.h> >> >> -#define GHCB_PROTO_OUR 0x0001UL >> +#define GHCB_PROTOCOL_MIN 1ULL >> #define GHCB_PROTOCOL_MAX 1ULL >> #define GHCB_DEFAULT_USAGE 0ULL >> >> diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c >> index 6ec8b3bfd76e..48a47540b85f 100644 >> --- a/arch/x86/kernel/sev-shared.c >> +++ b/arch/x86/kernel/sev-shared.c >> @@ -14,6 +14,13 @@ >> #define has_cpuflag(f) boot_cpu_has(f) >> #endif >> >> +/* >> + * Since feature negotitation related variables are set early in the boot >> + * process they must reside in the .data section so as not to be zeroed >> + * out when the .bss section is later cleared. > * > * GHCB protocol version negotiated with the hypervisor. > */ > >> +static u16 ghcb_version __section(".data") = 0; > Did you not see this when running checkpatch.pl on your patch? > > ERROR: do not initialise statics to 0 > #141: FILE: arch/x86/kernel/sev-shared.c:22: > +static u16 ghcb_version __section(".data") = 0; > I ignored it, because I thought I still need to initialize the value to zero because it does not go into .bss section which gets initialized to zero by kernel on boot. I guess I was wrong, maybe compiler or kernel build ensures that ghcb_version variable to be init'ed to zero because its marked static ? >> static bool __init sev_es_check_cpu_features(void) >> { >> if (!has_cpuflag(X86_FEATURE_RDRAND)) { >> @@ -54,10 +61,12 @@ static bool sev_es_negotiate_protocol(void) >> if (GHCB_MSR_INFO(val) != GHCB_MSR_SEV_INFO_RESP) >> return false; >> >> - if (GHCB_MSR_PROTO_MAX(val) < GHCB_PROTO_OUR || >> - GHCB_MSR_PROTO_MIN(val) > GHCB_PROTO_OUR) >> + if (GHCB_MSR_PROTO_MAX(val) < GHCB_PROTOCOL_MIN || >> + GHCB_MSR_PROTO_MIN(val) > GHCB_PROTOCOL_MAX) >> return false; >> >> + ghcb_version = min_t(size_t, GHCB_MSR_PROTO_MAX(val), GHCB_PROTOCOL_MAX); > How is that even supposed to work? GHCB_PROTOCOL_MAX is 1 so > ghcb_version will be always 1 when you do min_t() on values one of which > is 1. > > Maybe I'm missing something... In patch #4, you will see that I increase the GHCB max protocol version to 2, and then min_t() will choose the lower value. I didn't combine version bump and caching into same patch because I felt I will be asked to break them into two logical patches. >