mem_encrypt.S 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * AMD Memory Encryption Support
  3. *
  4. * Copyright (C) 2017 Advanced Micro Devices, Inc.
  5. *
  6. * Author: Tom Lendacky <thomas.lendacky@amd.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/linkage.h>
  13. #include <asm/processor-flags.h>
  14. #include <asm/msr.h>
  15. #include <asm/asm-offsets.h>
  16. .text
  17. .code32
  18. ENTRY(get_sev_encryption_bit)
  19. xor %eax, %eax
  20. #ifdef CONFIG_AMD_MEM_ENCRYPT
  21. push %ebx
  22. push %ecx
  23. push %edx
  24. /* Check if running under a hypervisor */
  25. movl $1, %eax
  26. cpuid
  27. bt $31, %ecx /* Check the hypervisor bit */
  28. jnc .Lno_sev
  29. movl $0x80000000, %eax /* CPUID to check the highest leaf */
  30. cpuid
  31. cmpl $0x8000001f, %eax /* See if 0x8000001f is available */
  32. jb .Lno_sev
  33. /*
  34. * Check for the SEV feature:
  35. * CPUID Fn8000_001F[EAX] - Bit 1
  36. * CPUID Fn8000_001F[EBX] - Bits 5:0
  37. * Pagetable bit position used to indicate encryption
  38. */
  39. movl $0x8000001f, %eax
  40. cpuid
  41. bt $1, %eax /* Check if SEV is available */
  42. jnc .Lno_sev
  43. movl $MSR_AMD64_SEV, %ecx /* Read the SEV MSR */
  44. rdmsr
  45. bt $MSR_AMD64_SEV_ENABLED_BIT, %eax /* Check if SEV is active */
  46. jnc .Lno_sev
  47. movl %ebx, %eax
  48. andl $0x3f, %eax /* Return the encryption bit location */
  49. jmp .Lsev_exit
  50. .Lno_sev:
  51. xor %eax, %eax
  52. .Lsev_exit:
  53. pop %edx
  54. pop %ecx
  55. pop %ebx
  56. #endif /* CONFIG_AMD_MEM_ENCRYPT */
  57. ret
  58. ENDPROC(get_sev_encryption_bit)
  59. .code64
  60. ENTRY(set_sev_encryption_mask)
  61. #ifdef CONFIG_AMD_MEM_ENCRYPT
  62. push %rbp
  63. push %rdx
  64. movq %rsp, %rbp /* Save current stack pointer */
  65. call get_sev_encryption_bit /* Get the encryption bit position */
  66. testl %eax, %eax
  67. jz .Lno_sev_mask
  68. bts %rax, sme_me_mask(%rip) /* Create the encryption mask */
  69. .Lno_sev_mask:
  70. movq %rbp, %rsp /* Restore original stack pointer */
  71. pop %rdx
  72. pop %rbp
  73. #endif
  74. xor %rax, %rax
  75. ret
  76. ENDPROC(set_sev_encryption_mask)
  77. .data
  78. #ifdef CONFIG_AMD_MEM_ENCRYPT
  79. .balign 8
  80. GLOBAL(sme_me_mask)
  81. .quad 0
  82. #endif