Use RIP-relative addressing to access cpuid maxes and ghcb version

Change-Id: Ifaac89a0a435bce2e2bf14f65fd98046a235c1f7
diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
index 20c43e4..63c44d0 100644
--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/kernel/sev-shared.c
@@ -63,6 +63,17 @@
  */
 static u16 ghcb_version __ro_after_init;
 
+static u16 *get_ghcb_version(void)
+{
+	void *ptr;
+
+	asm ("lea ghcb_version(%%rip), %0"
+	     : "=r" (ptr)
+	     : "p" (&ghcb_version));
+
+	return (u16*)ptr;
+}
+
 /* Copy of the SNP firmware's CPUID page. */
 static struct snp_cpuid_table cpuid_table_copy __ro_after_init;
 
@@ -72,9 +83,13 @@
  * invalid/out-of-range leaves. This is needed since all-zero leaves
  * still need to be post-processed.
  */
-static u32 cpuid_std_range_max __ro_after_init;
-static u32 cpuid_hyp_range_max __ro_after_init;
-static u32 cpuid_ext_range_max __ro_after_init;
+struct cpuid_maxes {
+	u32 std_range;
+	u32 hyp_range;
+	u32 ext_range;
+};
+
+static struct cpuid_maxes cpuid_range_maxes __ro_after_init;
 
 static bool __init sev_es_check_cpu_features(void)
 {
@@ -108,7 +123,7 @@
 {
 	u64 val;
 
-	if (ghcb_version < 2)
+	if (*get_ghcb_version() < 2)
 		return 0;
 
 	sev_es_wr_ghcb_msr(GHCB_MSR_HV_FT_REQ);
@@ -153,7 +168,7 @@
 	    GHCB_MSR_PROTO_MIN(val) > GHCB_PROTOCOL_MAX)
 		return false;
 
-	ghcb_version = min_t(size_t, GHCB_MSR_PROTO_MAX(val), GHCB_PROTOCOL_MAX);
+	*get_ghcb_version() = min_t(size_t, GHCB_MSR_PROTO_MAX(val), GHCB_PROTOCOL_MAX);
 
 	return true;
 }
@@ -291,6 +306,17 @@
 	return ptr;
 }
 
+static const struct cpuid_maxes *snp_cpuid_get_maxes(void)
+{
+	void *ptr;
+
+	asm ("lea cpuid_range_maxes(%%rip), %0"
+	     : "=r" (ptr)
+	     : "p" (&cpuid_range_maxes));
+
+	return ptr;
+}
+
 /*
  * The SNP Firmware ABI, Revision 0.9, Section 7.1, details the use of
  * XCR0_IN and XSS_IN to encode multiple versions of 0xD subfunctions 0
@@ -486,6 +512,7 @@
 static int snp_cpuid(struct cpuid_leaf *leaf)
 {
 	const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
+	const struct cpuid_maxes *maxes = snp_cpuid_get_maxes();
 
 	if (!cpuid_table->count)
 		return -EOPNOTSUPP;
@@ -511,9 +538,9 @@
 		leaf->eax = leaf->ebx = leaf->ecx = leaf->edx = 0;
 
 		/* Skip post-processing for out-of-range zero leafs. */
-		if (!(leaf->fn <= cpuid_std_range_max ||
-		      (leaf->fn >= 0x40000000 && leaf->fn <= cpuid_hyp_range_max) ||
-		      (leaf->fn >= 0x80000000 && leaf->fn <= cpuid_ext_range_max)))
+		if (!(leaf->fn <= maxes->std_range ||
+		      (leaf->fn >= 0x40000000 && leaf->fn <= maxes->hyp_range) ||
+		      (leaf->fn >= 0x80000000 && leaf->fn <= maxes->ext_range)))
 			return 0;
 	}
 
@@ -965,6 +992,8 @@
 static void __init setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
 {
 	const struct snp_cpuid_table *cpuid_table_fw, *cpuid_table;
+	const struct cpuid_maxes *range_maxes;
+	struct cpuid_maxes local;
 	int i;
 
 	if (!cc_info || !cc_info->cpuid_phys || cc_info->cpuid_len < PAGE_SIZE)
@@ -975,6 +1004,7 @@
 		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID);
 
 	cpuid_table = snp_cpuid_get_table();
+	range_maxes = snp_cpuid_get_maxes();
 	memcpy((void *)cpuid_table, cpuid_table_fw, sizeof(*cpuid_table));
 
 	/* Initialize CPUID ranges for range-checking. */
@@ -982,10 +1012,11 @@
 		const struct snp_cpuid_fn *fn = &cpuid_table->fn[i];
 
 		if (fn->eax_in == 0x0)
-			cpuid_std_range_max = fn->eax;
+			local.std_range = fn->eax;
 		else if (fn->eax_in == 0x40000000)
-			cpuid_hyp_range_max = fn->eax;
+			local.hyp_range = fn->eax;
 		else if (fn->eax_in == 0x80000000)
-			cpuid_ext_range_max = fn->eax;
+			local.ext_range = fn->eax;
 	}
+	memcpy((void *)range_maxes, &local, sizeof(*range_maxes));
 }