1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * AMD Encrypted Register State Support 4 * 5 * Author: Joerg Roedel <jroedel@suse.de> 6 */ 7 8 #ifndef __ASM_ENCRYPTED_STATE_H 9 #define __ASM_ENCRYPTED_STATE_H 10 11 #include <linux/types.h> 12 #include <asm/insn.h> 13 #include <asm/sev-common.h> 14 15 #define GHCB_PROTO_OUR 0x0001UL 16 #define GHCB_PROTOCOL_MAX 1ULL 17 #define GHCB_DEFAULT_USAGE 0ULL 18 19 #define VMGEXIT() { asm volatile("rep; vmmcall\n\r"); } 20 21 enum es_result { 22 ES_OK, /* All good */ 23 ES_UNSUPPORTED, /* Requested operation not supported */ 24 ES_VMM_ERROR, /* Unexpected state from the VMM */ 25 ES_DECODE_FAILED, /* Instruction decoding failed */ 26 ES_EXCEPTION, /* Instruction caused exception */ 27 ES_RETRY, /* Retry instruction emulation */ 28 }; 29 30 struct es_fault_info { 31 unsigned long vector; 32 unsigned long error_code; 33 unsigned long cr2; 34 }; 35 36 struct pt_regs; 37 38 /* ES instruction emulation context */ 39 struct es_em_ctxt { 40 struct pt_regs *regs; 41 struct insn insn; 42 struct es_fault_info fi; 43 }; 44 45 void do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code); 46 47 static inline u64 lower_bits(u64 val, unsigned int bits) 48 { 49 u64 mask = (1ULL << bits) - 1; 50 51 return (val & mask); 52 } 53 54 struct real_mode_header; 55 enum stack_type; 56 struct ghcb; 57 58 /* Early IDT entry points for #VC handler */ 59 extern void vc_no_ghcb(void); 60 extern void vc_boot_ghcb(void); 61 extern bool handle_vc_boot_ghcb(struct pt_regs *regs); 62 63 #ifdef CONFIG_AMD_MEM_ENCRYPT 64 extern struct static_key_false sev_es_enable_key; 65 extern void __sev_es_ist_enter(struct pt_regs *regs); 66 extern void __sev_es_ist_exit(void); 67 static __always_inline void sev_es_ist_enter(struct pt_regs *regs) 68 { 69 if (static_branch_unlikely(&sev_es_enable_key)) 70 __sev_es_ist_enter(regs); 71 } 72 static __always_inline void sev_es_ist_exit(void) 73 { 74 if (static_branch_unlikely(&sev_es_enable_key)) 75 __sev_es_ist_exit(); 76 } 77 extern int sev_es_setup_ap_jump_table(struct real_mode_header *rmh); 78 extern void __sev_es_nmi_complete(void); 79 static __always_inline void sev_es_nmi_complete(void) 80 { 81 if (static_branch_unlikely(&sev_es_enable_key)) 82 __sev_es_nmi_complete(); 83 } 84 extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd); 85 extern enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb, 86 bool set_ghcb_msr, 87 struct es_em_ctxt *ctxt, 88 u64 exit_code, u64 exit_info_1, 89 u64 exit_info_2); 90 #else 91 static inline void sev_es_ist_enter(struct pt_regs *regs) { } 92 static inline void sev_es_ist_exit(void) { } 93 static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; } 94 static inline void sev_es_nmi_complete(void) { } 95 static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; } 96 #endif 97 98 #endif 99