^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AMD Encrypted Register State Support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Joerg Roedel <jroedel@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifndef __ASM_ENCRYPTED_STATE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define __ASM_ENCRYPTED_STATE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/insn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define GHCB_SEV_INFO 0x001UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define GHCB_SEV_INFO_REQ 0x002UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define GHCB_INFO(v) ((v) & 0xfffUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define GHCB_PROTO_MAX(v) (((v) >> 48) & 0xffffUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define GHCB_PROTO_MIN(v) (((v) >> 32) & 0xffffUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define GHCB_PROTO_OUR 0x0001UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define GHCB_SEV_CPUID_REQ 0x004UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define GHCB_CPUID_REQ_EAX 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define GHCB_CPUID_REQ_EBX 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define GHCB_CPUID_REQ_ECX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define GHCB_CPUID_REQ_EDX 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define GHCB_CPUID_REQ(fn, reg) (GHCB_SEV_CPUID_REQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) (((unsigned long)reg & 3) << 30) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) (((unsigned long)fn) << 32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define GHCB_PROTOCOL_MAX 0x0001UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define GHCB_DEFAULT_USAGE 0x0000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define GHCB_SEV_CPUID_RESP 0x005UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define GHCB_SEV_TERMINATE 0x100UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define GHCB_SEV_TERMINATE_REASON(reason_set, reason_val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) (((((u64)reason_set) & 0x7) << 12) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ((((u64)reason_val) & 0xff) << 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define GHCB_SEV_ES_REASON_GENERAL_REQUEST 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define GHCB_SEV_ES_REASON_PROTOCOL_UNSUPPORTED 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define GHCB_SEV_GHCB_RESP_CODE(v) ((v) & 0xfff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define VMGEXIT() { asm volatile("rep; vmmcall\n\r"); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) enum es_result {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ES_OK, /* All good */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ES_UNSUPPORTED, /* Requested operation not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ES_VMM_ERROR, /* Unexpected state from the VMM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ES_DECODE_FAILED, /* Instruction decoding failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ES_EXCEPTION, /* Instruction caused exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ES_RETRY, /* Retry instruction emulation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct es_fault_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned long vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned long error_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned long cr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct pt_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* ES instruction emulation context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct es_em_ctxt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct pt_regs *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct insn insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct es_fault_info fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) void do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static inline u64 lower_bits(u64 val, unsigned int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u64 mask = (1ULL << bits) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return (val & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct real_mode_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) enum stack_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Early IDT entry points for #VC handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) extern void vc_no_ghcb(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) extern void vc_boot_ghcb(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) extern bool handle_vc_boot_ghcb(struct pt_regs *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #ifdef CONFIG_AMD_MEM_ENCRYPT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) extern struct static_key_false sev_es_enable_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) extern void __sev_es_ist_enter(struct pt_regs *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) extern void __sev_es_ist_exit(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static __always_inline void sev_es_ist_enter(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (static_branch_unlikely(&sev_es_enable_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) __sev_es_ist_enter(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static __always_inline void sev_es_ist_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (static_branch_unlikely(&sev_es_enable_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) __sev_es_ist_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) extern int sev_es_setup_ap_jump_table(struct real_mode_header *rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) extern void __sev_es_nmi_complete(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static __always_inline void sev_es_nmi_complete(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (static_branch_unlikely(&sev_es_enable_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __sev_es_nmi_complete();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static inline void sev_es_ist_enter(struct pt_regs *regs) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static inline void sev_es_ist_exit(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static inline void sev_es_nmi_complete(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #endif