mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Many of the integrity guarantees of SEV-SNP are enforced through the Reverse Map Table (RMP). Each RMP entry contains the GPA at which a particular page of DRAM should be mapped. The VMs can request the hypervisor to add pages in the RMP table via the Page State Change VMGEXIT defined in the GHCB specification. Inside each RMP entry is a Validated flag; this flag is automatically cleared to 0 by the CPU hardware when a new RMP entry is created for a guest. Each VM page can be either validated or invalidated, as indicated by the Validated flag in the RMP entry. Memory access to a private page that is not validated generates a #VC. A VM must use the PVALIDATE instruction to validate a private page before using it. To maintain the security guarantee of SEV-SNP guests, when transitioning pages from private to shared, the guest must invalidate the pages before asking the hypervisor to change the page state to shared in the RMP table. After the pages are mapped private in the page table, the guest must issue a page state change VMGEXIT to mark the pages private in the RMP table and validate them. Upon boot, BIOS should have validated the entire system memory. During the kernel decompression stage, early_setup_ghcb() uses set_page_decrypted() to make the GHCB page shared (i.e. clear encryption attribute). And while exiting from the decompression, it calls set_page_encrypted() to make the page private. Add snp_set_page_{private,shared}() helpers that are used by set_page_{decrypted,encrypted}() to change the page state in the RMP table. [ bp: Massage commit message and comments. ] Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lore.kernel.org/r/20220307213356.2797205-16-brijesh.singh@amd.com
179 lines
4.4 KiB
C
179 lines
4.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef BOOT_COMPRESSED_MISC_H
|
|
#define BOOT_COMPRESSED_MISC_H
|
|
|
|
/*
|
|
* Special hack: we have to be careful, because no indirections are allowed here,
|
|
* and paravirt_ops is a kind of one. As it will only run in baremetal anyway,
|
|
* we just keep it from happening. (This list needs to be extended when new
|
|
* paravirt and debugging variants are added.)
|
|
*/
|
|
#undef CONFIG_PARAVIRT
|
|
#undef CONFIG_PARAVIRT_XXL
|
|
#undef CONFIG_PARAVIRT_SPINLOCKS
|
|
#undef CONFIG_KASAN
|
|
#undef CONFIG_KASAN_GENERIC
|
|
|
|
#define __NO_FORTIFY
|
|
|
|
/* cpu_feature_enabled() cannot be used this early */
|
|
#define USE_EARLY_PGTABLE_L5
|
|
|
|
#include <linux/linkage.h>
|
|
#include <linux/screen_info.h>
|
|
#include <linux/elf.h>
|
|
#include <linux/io.h>
|
|
#include <asm/page.h>
|
|
#include <asm/boot.h>
|
|
#include <asm/bootparam.h>
|
|
#include <asm/desc_defs.h>
|
|
|
|
#define BOOT_CTYPE_H
|
|
#include <linux/acpi.h>
|
|
|
|
#define BOOT_BOOT_H
|
|
#include "../ctype.h"
|
|
|
|
#ifdef CONFIG_X86_64
|
|
#define memptr long
|
|
#else
|
|
#define memptr unsigned
|
|
#endif
|
|
|
|
/* boot/compressed/vmlinux start and end markers */
|
|
extern char _head[], _end[];
|
|
|
|
/* misc.c */
|
|
extern memptr free_mem_ptr;
|
|
extern memptr free_mem_end_ptr;
|
|
void *malloc(int size);
|
|
void free(void *where);
|
|
extern struct boot_params *boot_params;
|
|
void __putstr(const char *s);
|
|
void __puthex(unsigned long value);
|
|
#define error_putstr(__x) __putstr(__x)
|
|
#define error_puthex(__x) __puthex(__x)
|
|
|
|
#ifdef CONFIG_X86_VERBOSE_BOOTUP
|
|
|
|
#define debug_putstr(__x) __putstr(__x)
|
|
#define debug_puthex(__x) __puthex(__x)
|
|
#define debug_putaddr(__x) { \
|
|
debug_putstr(#__x ": 0x"); \
|
|
debug_puthex((unsigned long)(__x)); \
|
|
debug_putstr("\n"); \
|
|
}
|
|
|
|
#else
|
|
|
|
static inline void debug_putstr(const char *s)
|
|
{ }
|
|
static inline void debug_puthex(unsigned long value)
|
|
{ }
|
|
#define debug_putaddr(x) /* */
|
|
|
|
#endif
|
|
|
|
/* cmdline.c */
|
|
int cmdline_find_option(const char *option, char *buffer, int bufsize);
|
|
int cmdline_find_option_bool(const char *option);
|
|
|
|
struct mem_vector {
|
|
u64 start;
|
|
u64 size;
|
|
};
|
|
|
|
#ifdef CONFIG_RANDOMIZE_BASE
|
|
/* kaslr.c */
|
|
void choose_random_location(unsigned long input,
|
|
unsigned long input_size,
|
|
unsigned long *output,
|
|
unsigned long output_size,
|
|
unsigned long *virt_addr);
|
|
#else
|
|
static inline void choose_random_location(unsigned long input,
|
|
unsigned long input_size,
|
|
unsigned long *output,
|
|
unsigned long output_size,
|
|
unsigned long *virt_addr)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
/* cpuflags.c */
|
|
bool has_cpuflag(int flag);
|
|
|
|
#ifdef CONFIG_X86_64
|
|
extern int set_page_decrypted(unsigned long address);
|
|
extern int set_page_encrypted(unsigned long address);
|
|
extern int set_page_non_present(unsigned long address);
|
|
extern unsigned char _pgtable[];
|
|
#endif
|
|
|
|
#ifdef CONFIG_EARLY_PRINTK
|
|
/* early_serial_console.c */
|
|
extern int early_serial_base;
|
|
void console_init(void);
|
|
#else
|
|
static const int early_serial_base;
|
|
static inline void console_init(void)
|
|
{ }
|
|
#endif
|
|
|
|
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
|
void sev_enable(struct boot_params *bp);
|
|
void sev_es_shutdown_ghcb(void);
|
|
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);
|
|
#else
|
|
static inline void sev_enable(struct boot_params *bp) { }
|
|
static inline void sev_es_shutdown_ghcb(void) { }
|
|
static inline bool sev_es_check_ghcb_fault(unsigned long address)
|
|
{
|
|
return false;
|
|
}
|
|
static inline void snp_set_page_private(unsigned long paddr) { }
|
|
static inline void snp_set_page_shared(unsigned long paddr) { }
|
|
#endif
|
|
|
|
/* acpi.c */
|
|
#ifdef CONFIG_ACPI
|
|
acpi_physical_address get_rsdp_addr(void);
|
|
#else
|
|
static inline acpi_physical_address get_rsdp_addr(void) { return 0; }
|
|
#endif
|
|
|
|
#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE) && defined(CONFIG_ACPI)
|
|
extern struct mem_vector immovable_mem[MAX_NUMNODES*2];
|
|
int count_immovable_mem_regions(void);
|
|
#else
|
|
static inline int count_immovable_mem_regions(void) { return 0; }
|
|
#endif
|
|
|
|
/* ident_map_64.c */
|
|
#ifdef CONFIG_X86_5LEVEL
|
|
extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d;
|
|
#endif
|
|
|
|
/* Used by PAGE_KERN* macros: */
|
|
extern pteval_t __default_kernel_pte_mask;
|
|
|
|
/* idt_64.c */
|
|
extern gate_desc boot_idt[BOOT_IDT_ENTRIES];
|
|
extern struct desc_ptr boot_idt_desc;
|
|
|
|
#ifdef CONFIG_X86_64
|
|
void cleanup_exception_handling(void);
|
|
#else
|
|
static inline void cleanup_exception_handling(void) { }
|
|
#endif
|
|
|
|
/* IDT Entry Points */
|
|
void boot_page_fault(void);
|
|
void boot_stage1_vc(void);
|
|
void boot_stage2_vc(void);
|
|
|
|
unsigned long sev_verify_cbit(unsigned long cr3);
|
|
|
|
#endif /* BOOT_COMPRESSED_MISC_H */
|