[RFC Part1 PATCH 11/13] x86/kernel: validate rom memory before accessing when SEV-SNP is active

Brijesh Singh
2021-03-24T16:45:30Z

The probe_roms() access the memory range (0xc0000 - 0x10000) to probe
various ROMs. The memory range is not part of the E820 system RAM
range. The memory range is mapped as private (i.e encrypted) in page
table.

When SEV-SNP is active, all the private memory must be validated before
the access. The ROM range was not part of E820 map, so the guest BIOS
did not validate it. An access to invalidated memory will cause a VC
exception. We don't have VC exception handler ready to validate the
memory on-demand. Lets validate the ROM memory region before it is
assessed.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Joerg Roedel <jroedel@suse.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: x86@kernel.org
Cc: kvm@vger.kernel.org
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
arch/x86/kernel/probe_roms.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/arch/x86/kernel/probe_roms.c b/arch/x86/kernel/probe_roms.c
index 9e1def3744f2..65640b401b9c 100644
--- a/arch/x86/kernel/probe_roms.c
+++ b/arch/x86/kernel/probe_roms.c
@@ -21,6 +21,8 @@
#include <asm/sections.h>
#include <asm/io.h>
#include <asm/setup_arch.h>
+#include <asm/mem_encrypt.h>
+#include <asm/sev-snp.h>

static struct resource system_rom_resource = {
.name = "System ROM",
@@ -202,6 +204,19 @@ void __init probe_roms(void)
unsigned char c;
int i;

+ /*
+ * The ROM memory is not part of the E820 system RAM and is not prevalidated by the BIOS.
+ * The kernel page table maps the ROM region as encrypted memory, the SEV-SNP requires
+ * the all the encrypted memory must be validated before the access.
+ */
+ if (sev_snp_active()) {
+ unsigned long n, paddr;
+
+ n = ((system_rom_resource.end + 1) - video_rom_resource.start) >> PAGE_SHIFT;
+ paddr = video_rom_resource.start;
+ early_snp_set_memory_private((unsigned long)__va(paddr), paddr, n);
+ }
+
/* video rom */
upper = adapter_rom_resources[0].start;
for (start = video_rom_resource.start; start < upper; start += 2048) {
--
2.17.1