@@ -37,6 +37,8 @@
#include <asm/setup.h> /* For COMMAND_LINE_SIZE */
#undef _SETUP
+#include <asm/sev.h> /* For ConfidentialComputing blob */
+
extern unsigned long get_cmd_line_ptr(void);
/* Used by PAGE_KERN* macros: */
@@ -106,6 +108,27 @@ static void add_identity_map(unsigned long start, unsigned long end)
error("Error: kernel_ident_mapping_init() failed\n");
}
+void sev_prep_identity_maps(void)
+{
+ /*
+ * The ConfidentialComputing blob is used very early in uncompressed
+ * kernel to find the in-memory cpuid table to handle cpuid
+ * instructions. Make sure an identity-mapping exists so it can be
+ * accessed after switchover.
+ */
+ if (sev_snp_enabled()) {
+ struct cc_blob_sev_info *cc_info =
+ (void *)(unsigned long)boot_params->cc_blob_address;
+
+ add_identity_map((unsigned long)cc_info,
+ (unsigned long)cc_info + sizeof(*cc_info));
+ add_identity_map((unsigned long)cc_info->cpuid_phys,
+ (unsigned long)cc_info->cpuid_phys + cc_info->cpuid_len);
+ }
+
+ sev_verify_cbit(top_level_pgt);
+}
+
/* Locates and clears a region for a new top level page table. */
void initialize_identity_maps(void *rmode)
{
@@ -163,8 +186,9 @@ void initialize_identity_maps(void *rmode)
cmdline = get_cmd_line_ptr();
add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE);
+ sev_prep_identity_maps();
+
/* Load the new page-table. */
- sev_verify_cbit(top_level_pgt);
write_cr3(top_level_pgt);
}
@@ -125,6 +125,7 @@ extern bool sev_es_check_ghcb_fault(unsigned long address);
void snp_set_page_private(unsigned long paddr);
void snp_set_page_shared(unsigned long paddr);
void snp_cpuid_init_boot(struct boot_params *bp);
+bool sev_snp_enabled(void);
#else
static inline void sev_es_shutdown_ghcb(void) { }
@@ -135,6 +136,7 @@ static inline bool sev_es_check_ghcb_fault(unsigned long address)
static inline void snp_set_page_private(unsigned long paddr) { }
static inline void snp_set_page_shared(unsigned long paddr) { }
static inline void snp_cpuid_init_boot(struct boot_params *bp) { }
+static inline bool sev_snp_enabled(void) { return false; }
#endif
@@ -120,7 +120,7 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
/* Include code for early handlers */
#include "../../kernel/sev-shared.c"
-static inline bool sev_snp_enabled(void)
+bool sev_snp_enabled(void)
{
return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
}