1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun/* 3*4882a593Smuzhiyun * AMD Memory Encryption Support 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2017 Advanced Micro Devices, Inc. 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Author: Tom Lendacky <thomas.lendacky@amd.com> 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun#include <linux/linkage.h> 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun#include <asm/processor-flags.h> 13*4882a593Smuzhiyun#include <asm/msr.h> 14*4882a593Smuzhiyun#include <asm/asm-offsets.h> 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun .text 17*4882a593Smuzhiyun .code32 18*4882a593SmuzhiyunSYM_FUNC_START(get_sev_encryption_bit) 19*4882a593Smuzhiyun xor %eax, %eax 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun#ifdef CONFIG_AMD_MEM_ENCRYPT 22*4882a593Smuzhiyun push %ebx 23*4882a593Smuzhiyun push %ecx 24*4882a593Smuzhiyun push %edx 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun movl $0x80000000, %eax /* CPUID to check the highest leaf */ 27*4882a593Smuzhiyun cpuid 28*4882a593Smuzhiyun cmpl $0x8000001f, %eax /* See if 0x8000001f is available */ 29*4882a593Smuzhiyun jb .Lno_sev 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun /* 32*4882a593Smuzhiyun * Check for the SEV feature: 33*4882a593Smuzhiyun * CPUID Fn8000_001F[EAX] - Bit 1 34*4882a593Smuzhiyun * CPUID Fn8000_001F[EBX] - Bits 5:0 35*4882a593Smuzhiyun * Pagetable bit position used to indicate encryption 36*4882a593Smuzhiyun */ 37*4882a593Smuzhiyun movl $0x8000001f, %eax 38*4882a593Smuzhiyun cpuid 39*4882a593Smuzhiyun bt $1, %eax /* Check if SEV is available */ 40*4882a593Smuzhiyun jnc .Lno_sev 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ 43*4882a593Smuzhiyun rdmsr 44*4882a593Smuzhiyun bt $MSR_AMD64_SEV_ENABLED_BIT, %eax /* Check if SEV is active */ 45*4882a593Smuzhiyun jnc .Lno_sev 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun movl %ebx, %eax 48*4882a593Smuzhiyun andl $0x3f, %eax /* Return the encryption bit location */ 49*4882a593Smuzhiyun jmp .Lsev_exit 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun.Lno_sev: 52*4882a593Smuzhiyun xor %eax, %eax 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun.Lsev_exit: 55*4882a593Smuzhiyun pop %edx 56*4882a593Smuzhiyun pop %ecx 57*4882a593Smuzhiyun pop %ebx 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun#endif /* CONFIG_AMD_MEM_ENCRYPT */ 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun RET 62*4882a593SmuzhiyunSYM_FUNC_END(get_sev_encryption_bit) 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun .code64 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun#include "../../kernel/sev_verify_cbit.S" 67*4882a593Smuzhiyun 68*4882a593SmuzhiyunSYM_FUNC_START(set_sev_encryption_mask) 69*4882a593Smuzhiyun#ifdef CONFIG_AMD_MEM_ENCRYPT 70*4882a593Smuzhiyun push %rbp 71*4882a593Smuzhiyun push %rdx 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun movq %rsp, %rbp /* Save current stack pointer */ 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun call get_sev_encryption_bit /* Get the encryption bit position */ 76*4882a593Smuzhiyun testl %eax, %eax 77*4882a593Smuzhiyun jz .Lno_sev_mask 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun bts %rax, sme_me_mask(%rip) /* Create the encryption mask */ 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun /* 82*4882a593Smuzhiyun * Read MSR_AMD64_SEV again and store it to sev_status. Can't do this in 83*4882a593Smuzhiyun * get_sev_encryption_bit() because this function is 32-bit code and 84*4882a593Smuzhiyun * shared between 64-bit and 32-bit boot path. 85*4882a593Smuzhiyun */ 86*4882a593Smuzhiyun movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */ 87*4882a593Smuzhiyun rdmsr 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun /* Store MSR value in sev_status */ 90*4882a593Smuzhiyun shlq $32, %rdx 91*4882a593Smuzhiyun orq %rdx, %rax 92*4882a593Smuzhiyun movq %rax, sev_status(%rip) 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun.Lno_sev_mask: 95*4882a593Smuzhiyun movq %rbp, %rsp /* Restore original stack pointer */ 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun pop %rdx 98*4882a593Smuzhiyun pop %rbp 99*4882a593Smuzhiyun#endif 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun xor %rax, %rax 102*4882a593Smuzhiyun RET 103*4882a593SmuzhiyunSYM_FUNC_END(set_sev_encryption_mask) 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun .data 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun#ifdef CONFIG_AMD_MEM_ENCRYPT 108*4882a593Smuzhiyun .balign 8 109*4882a593SmuzhiyunSYM_DATA(sme_me_mask, .quad 0) 110*4882a593SmuzhiyunSYM_DATA(sev_status, .quad 0) 111*4882a593SmuzhiyunSYM_DATA(sev_check_data, .quad 0) 112*4882a593Smuzhiyun#endif 113