|
14 | 14 | #define has_cpuflag(f) boot_cpu_has(f) |
15 | 15 | #endif |
16 | 16 |
|
| 17 | +/* |
| 18 | + * Since feature negotiation related variables are set early in the boot |
| 19 | + * process they must reside in the .data section so as not to be zeroed |
| 20 | + * out when the .bss section is later cleared. |
| 21 | + * |
| 22 | + * GHCB protocol version negotiated with the hypervisor. |
| 23 | + */ |
| 24 | +static u16 ghcb_version __ro_after_init; |
| 25 | + |
17 | 26 | static bool __init sev_es_check_cpu_features(void) |
18 | 27 | { |
19 | 28 | if (!has_cpuflag(X86_FEATURE_RDRAND)) { |
@@ -51,10 +60,12 @@ static bool sev_es_negotiate_protocol(void) |
51 | 60 | if (GHCB_MSR_INFO(val) != GHCB_MSR_SEV_INFO_RESP) |
52 | 61 | return false; |
53 | 62 |
|
54 | | - if (GHCB_MSR_PROTO_MAX(val) < GHCB_PROTO_OUR || |
55 | | - GHCB_MSR_PROTO_MIN(val) > GHCB_PROTO_OUR) |
| 63 | + if (GHCB_MSR_PROTO_MAX(val) < GHCB_PROTOCOL_MIN || |
| 64 | + GHCB_MSR_PROTO_MIN(val) > GHCB_PROTOCOL_MAX) |
56 | 65 | return false; |
57 | 66 |
|
| 67 | + ghcb_version = min_t(size_t, GHCB_MSR_PROTO_MAX(val), GHCB_PROTOCOL_MAX); |
| 68 | + |
58 | 69 | return true; |
59 | 70 | } |
60 | 71 |
|
@@ -127,7 +138,7 @@ enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb, bool set_ghcb_msr, |
127 | 138 | u64 exit_info_1, u64 exit_info_2) |
128 | 139 | { |
129 | 140 | /* Fill in protocol and format specifiers */ |
130 | | - ghcb->protocol_version = GHCB_PROTOCOL_MAX; |
| 141 | + ghcb->protocol_version = ghcb_version; |
131 | 142 | ghcb->ghcb_usage = GHCB_DEFAULT_USAGE; |
132 | 143 |
|
133 | 144 | ghcb_set_sw_exit_code(ghcb, exit_code); |
|
0 commit comments