From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 16:59:54
This patch series provides a generic helper function, prot_guest_has(),
to replace the sme_active(), sev_active(), sev_es_active() and
mem_encrypt_active() functions.
It is expected that as new protected virtualization technologies are
added to the kernel, they can all be covered by a single function call
instead of a collection of specific function calls all called from the
same locations.
The powerpc and s390 patches have been compile tested only. Can the
folks copied on this series verify that nothing breaks for them.
Cc: Andi Kleen <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Baoquan He <redacted>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Christian Borntraeger <redacted>
Cc: Daniel Vetter <redacted>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dave Young <redacted>
Cc: David Airlie <redacted>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <redacted>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: VMware Graphics <redacted>
Cc: Will Deacon <will@kernel.org>
---
Patches based on:
https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git master
0b52902cd2d9 ("Merge branch 'efi/urgent'")
Changes since v1:
- Move some arch ioremap functions within #ifdef CONFIG_AMD_MEM_ENCRYPT
in prep for use of prot_guest_has() by TDX.
- Add type includes to the the protected_guest.h header file to prevent
build errors outside of x86.
- Make amd_prot_guest_has() EXPORT_SYMBOL_GPL
- Use amd_prot_guest_has() in place of checking sme_me_mask in the
arch/x86/mm/mem_encrypt.c file.
Tom Lendacky (12):
x86/ioremap: Selectively build arch override encryption functions
mm: Introduce a function to check for virtualization protection
features
x86/sev: Add an x86 version of prot_guest_has()
powerpc/pseries/svm: Add a powerpc version of prot_guest_has()
x86/sme: Replace occurrences of sme_active() with prot_guest_has()
x86/sev: Replace occurrences of sev_active() with prot_guest_has()
x86/sev: Replace occurrences of sev_es_active() with prot_guest_has()
treewide: Replace the use of mem_encrypt_active() with
prot_guest_has()
mm: Remove the now unused mem_encrypt_active() function
x86/sev: Remove the now unused mem_encrypt_active() function
powerpc/pseries/svm: Remove the now unused mem_encrypt_active()
function
s390/mm: Remove the now unused mem_encrypt_active() function
arch/Kconfig | 3 ++
arch/powerpc/include/asm/mem_encrypt.h | 5 --
arch/powerpc/include/asm/protected_guest.h | 30 +++++++++++
arch/powerpc/platforms/pseries/Kconfig | 1 +
arch/s390/include/asm/mem_encrypt.h | 2 -
arch/x86/Kconfig | 1 +
arch/x86/include/asm/io.h | 8 +++
arch/x86/include/asm/kexec.h | 2 +-
arch/x86/include/asm/mem_encrypt.h | 13 +----
arch/x86/include/asm/protected_guest.h | 29 +++++++++++
arch/x86/kernel/crash_dump_64.c | 4 +-
arch/x86/kernel/head64.c | 4 +-
arch/x86/kernel/kvm.c | 3 +-
arch/x86/kernel/kvmclock.c | 4 +-
arch/x86/kernel/machine_kexec_64.c | 19 +++----
arch/x86/kernel/pci-swiotlb.c | 9 ++--
arch/x86/kernel/relocate_kernel_64.S | 2 +-
arch/x86/kernel/sev.c | 6 +--
arch/x86/kvm/svm/svm.c | 3 +-
arch/x86/mm/ioremap.c | 18 +++----
arch/x86/mm/mem_encrypt.c | 60 +++++++++++++++-------
arch/x86/mm/mem_encrypt_identity.c | 3 +-
arch/x86/mm/pat/set_memory.c | 3 +-
arch/x86/platform/efi/efi_64.c | 9 ++--
arch/x86/realmode/init.c | 8 +--
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +-
drivers/gpu/drm/drm_cache.c | 4 +-
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 4 +-
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 +--
drivers/iommu/amd/init.c | 7 +--
drivers/iommu/amd/iommu.c | 3 +-
drivers/iommu/amd/iommu_v2.c | 3 +-
drivers/iommu/iommu.c | 3 +-
fs/proc/vmcore.c | 6 +--
include/linux/mem_encrypt.h | 4 --
include/linux/protected_guest.h | 40 +++++++++++++++
kernel/dma/swiotlb.c | 4 +-
37 files changed, 232 insertions(+), 105 deletions(-)
create mode 100644 arch/powerpc/include/asm/protected_guest.h
create mode 100644 arch/x86/include/asm/protected_guest.h
create mode 100644 include/linux/protected_guest.h
--
2.32.0
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:00:03
In prep for other uses of the prot_guest_has() function besides AMD's
memory encryption support, selectively build the AMD memory encryption
architecture override functions only when CONFIG_AMD_MEM_ENCRYPT=y. These
functions are:
- early_memremap_pgprot_adjust()
- arch_memremap_can_ram_remap()
Additionally, routines that are only invoked by these architecture
override functions can also be conditionally built. These functions are:
- memremap_should_map_decrypted()
- memremap_is_efi_data()
- memremap_is_setup_data()
- early_memremap_is_setup_data()
And finally, phys_mem_access_encrypted() is conditionally built as well,
but requires a static inline version of it when CONFIG_AMD_MEM_ENCRYPT is
not set.
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/x86/include/asm/io.h | 8 ++++++++
arch/x86/mm/ioremap.c | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:00:15
In prep for other protected virtualization technologies, introduce a
generic helper function, prot_guest_has(), that can be used to check
for specific protection attributes, like memory encryption. This is
intended to eliminate having to add multiple technology-specific checks
to the code (e.g. if (sev_active() || tdx_active())).
Reviewed-by: Joerg Roedel <redacted>
Co-developed-by: Andi Kleen <redacted>
Signed-off-by: Andi Kleen <redacted>
Co-developed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/Kconfig | 3 +++
include/linux/protected_guest.h | 35 +++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+)
create mode 100644 include/linux/protected_guest.h
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:00:18
Introduce an x86 version of the prot_guest_has() function. This will be
used in the more generic x86 code to replace vendor specific calls like
sev_active(), etc.
While the name suggests this is intended mainly for guests, it will
also be used for host memory encryption checks in place of sme_active().
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Joerg Roedel <redacted>
Co-developed-by: Andi Kleen <redacted>
Signed-off-by: Andi Kleen <redacted>
Co-developed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/x86/Kconfig | 1 +
arch/x86/include/asm/mem_encrypt.h | 2 ++
arch/x86/include/asm/protected_guest.h | 29 ++++++++++++++++++++++++++
arch/x86/mm/mem_encrypt.c | 25 ++++++++++++++++++++++
include/linux/protected_guest.h | 5 +++++
5 files changed, 62 insertions(+)
create mode 100644 arch/x86/include/asm/protected_guest.h
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:00:39
Introduce a powerpc version of the prot_guest_has() function. This will
be used to replace the powerpc mem_encrypt_active() implementation, so
the implementation will initially only support the PATTR_MEM_ENCRYPT
attribute.
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/powerpc/include/asm/protected_guest.h | 30 ++++++++++++++++++++++
arch/powerpc/platforms/pseries/Kconfig | 1 +
2 files changed, 31 insertions(+)
create mode 100644 arch/powerpc/include/asm/protected_guest.h
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:00:45
Replace occurrences of sme_active() with the more generic prot_guest_has()
using PATTR_HOST_MEM_ENCRYPT, except for in arch/x86/mm/mem_encrypt*.c
where PATTR_SME will be used. If future support is added for other memory
encryption technologies, the use of PATTR_HOST_MEM_ENCRYPT can be
updated, as required, to use PATTR_SME.
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <will@kernel.org>
Reviewed-by: Joerg Roedel <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/x86/include/asm/kexec.h | 2 +-
arch/x86/include/asm/mem_encrypt.h | 2 --
arch/x86/kernel/machine_kexec_64.c | 3 ++-
arch/x86/kernel/pci-swiotlb.c | 9 ++++-----
arch/x86/kernel/relocate_kernel_64.S | 2 +-
arch/x86/mm/ioremap.c | 6 +++---
arch/x86/mm/mem_encrypt.c | 10 +++++-----
arch/x86/mm/mem_encrypt_identity.c | 3 ++-
arch/x86/realmode/init.c | 5 +++--
drivers/iommu/amd/init.c | 7 ++++---
10 files changed, 25 insertions(+), 24 deletions(-)
@@ -144,7 +144,7 @@ void __init sme_unmap_bootdata(char *real_mode_data)structboot_params*boot_data;unsignedlongcmdline_paddr;-if(!sme_active())+if(!amd_prot_guest_has(PATTR_SME))return;/* Get the command line address before unmapping the real_mode_data */
@@ -965,7 +965,7 @@ static bool copy_device_table(void)pr_err("The address of old device table is above 4G, not trustworthy!\n");returnfalse;}-old_devtb=(sme_active()&&is_kdump_kernel())+old_devtb=(prot_guest_has(PATTR_HOST_MEM_ENCRYPT)&&is_kdump_kernel())?(__forcevoid*)ioremap_encrypted(old_devtb_phys,dev_table_size):memremap(old_devtb_phys,dev_table_size,MEMREMAP_WB);
@@ -3022,7 +3022,8 @@ static int __init amd_iommu_init(void)staticboolamd_iommu_sme_check(void){-if(!sme_active()||(boot_cpu_data.x86!=0x17))+if(!prot_guest_has(PATTR_HOST_MEM_ENCRYPT)||+(boot_cpu_data.x86!=0x17))returntrue;/* For Fam17h, a specific level of support is required */
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:00:51
Replace occurrences of sev_active() with the more generic prot_guest_has()
using PATTR_GUEST_MEM_ENCRYPT, except for in arch/x86/mm/mem_encrypt*.c
where PATTR_SEV will be used. If future support is added for other memory
encryption technologies, the use of PATTR_GUEST_MEM_ENCRYPT can be
updated, as required, to use PATTR_SEV.
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Joerg Roedel <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/x86/include/asm/mem_encrypt.h | 2 --
arch/x86/kernel/crash_dump_64.c | 4 +++-
arch/x86/kernel/kvm.c | 3 ++-
arch/x86/kernel/kvmclock.c | 4 ++--
arch/x86/kernel/machine_kexec_64.c | 16 ++++++++--------
arch/x86/kvm/svm/svm.c | 3 ++-
arch/x86/mm/ioremap.c | 6 +++---
arch/x86/mm/mem_encrypt.c | 15 +++++++--------
arch/x86/platform/efi/efi_64.c | 9 +++++----
9 files changed, 32 insertions(+), 30 deletions(-)
@@ -457,7 +458,7 @@ static int has_svm(void)return0;}-if(sev_active()){+if(prot_guest_has(PATTR_SEV)){pr_info("KVM is unsupported when running as an SEV guest\n");return0;}
@@ -92,7 +92,7 @@ static unsigned int __ioremap_check_ram(struct resource *res)*/staticunsignedint__ioremap_check_encrypted(structresource*res){-if(!sev_active())+if(!prot_guest_has(PATTR_GUEST_MEM_ENCRYPT))return0;switch(res->desc){
@@ -112,7 +112,7 @@ static unsigned int __ioremap_check_encrypted(struct resource *res)*/staticvoid__ioremap_check_other(resource_size_taddr,structioremap_desc*desc){-if(!sev_active())+if(!prot_guest_has(PATTR_GUEST_MEM_ENCRYPT))return;if(!IS_ENABLED(CONFIG_EFI))
@@ -556,7 +556,7 @@ static bool memremap_should_map_decrypted(resource_size_t phys_addr,caseE820_TYPE_NVS:caseE820_TYPE_UNUSABLE:/* For SEV, these areas are encrypted */-if(sev_active())+if(prot_guest_has(PATTR_GUEST_MEM_ENCRYPT))break;fallthrough;
@@ -373,7 +373,7 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)*upunderSMEthetrampolineareacannotbeencrypted,whereasunderSEV*thetrampolineareamustbeencrypted.*/-boolsev_active(void)+staticboolsev_active(void){returnsev_status&MSR_AMD64_SEV_ENABLED;}
@@ -382,7 +382,6 @@ static bool sme_active(void){returnsme_me_mask&&!sev_active();}-EXPORT_SYMBOL_GPL(sev_active);/* Needs to be called from non-instrumentable code */boolnoinstrsev_es_active(void)
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:00:56
Replace occurrences of sev_es_active() with the more generic
prot_guest_has() using PATTR_GUEST_PROT_STATE, except for in
arch/x86/kernel/sev*.c and arch/x86/mm/mem_encrypt*.c where PATTR_SEV_ES
will be used. If future support is added for other memory encyrption
techonologies, the use of PATTR_GUEST_PROT_STATE can be updated, as
required, to specifically use PATTR_SEV_ES.
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/x86/include/asm/mem_encrypt.h | 2 --
arch/x86/kernel/sev.c | 6 +++---
arch/x86/mm/mem_encrypt.c | 7 +++----
arch/x86/realmode/init.c | 3 +--
4 files changed, 7 insertions(+), 11 deletions(-)
@@ -383,8 +383,7 @@ static bool sme_active(void)returnsme_me_mask&&!sev_active();}-/* Needs to be called from non-instrumentable code */-boolnoinstrsev_es_active(void)+staticboolsev_es_active(void){returnsev_status&MSR_AMD64_SEV_ES_ENABLED;}
@@ -285,7 +285,7 @@ unsigned long __head __startup_64(unsigned long physaddr,*thereisnoneedtozeroitafterchangingthememoryencryption*attribute.*/-if(mem_encrypt_active()){+if(prot_guest_has(PATTR_MEM_ENCRYPT)){vaddr=(unsignedlong)__start_bss_decrypted;vaddr_end=(unsignedlong)__end_bss_decrypted;for(;vaddr<vaddr_end;vaddr+=PMD_SIZE){
@@ -364,8 +364,7 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)/**SMEandSEVareverysimilarbuttheyarenotthesame,sothereare*timesthatthekernelwillneedtodistinguishbetweenSMEandSEV.The-*sme_active()andsev_active()functionsareusedforthis.Whena-*distinctionisn'tneeded,themem_encrypt_active()functioncanbeused.+*sme_active()andsev_active()functionsareusedforthis.**Thetrampolinecodeisagoodexampleforthisrequirement.Before*pagingisactivated,SMEwillaccessallmemoryasdecrypted,butSEV
@@ -1986,7 +1987,7 @@ static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)intret;/* Nothing to do if memory encryption is not active */-if(!mem_encrypt_active())+if(!prot_guest_has(PATTR_MEM_ENCRYPT))return0;/* Should not be working on unaligned addresses */
@@ -1250,7 +1251,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,*however,SMErequiresanindirectIOMMUmappingbecausetheencryption*bitisbeyondtheDMAmaskofthechip.*/-if(mem_encrypt_active()&&((flags&AMD_ASIC_MASK)==CHIP_RAVEN)){+if(prot_guest_has(PATTR_MEM_ENCRYPT)&&+((flags&AMD_ASIC_MASK)==CHIP_RAVEN)){dev_info(&pdev->dev,"SME is not compatible with RAVEN\n");return-ENOTSUPP;
@@ -633,7 +633,7 @@ static int vmw_dma_select_mode(struct vmw_private *dev_priv)[vmw_dma_map_bind]="Giving up DMA mappings early."};/* TTM currently doesn't fully support SEV encryption. */-if(mem_encrypt_active())+if(prot_guest_has(PATTR_MEM_ENCRYPT))return-EINVAL;if(vmw_force_coherent)
@@ -741,7 +742,7 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)*Whenmemoryencryptionisactivethedeviceislikelynotina*direct-mappeddomain.ForbidusingIOMMUv2functionalityfornow.*/-if(mem_encrypt_active())+if(prot_guest_has(PATTR_MEM_ENCRYPT))return-ENODEV;if(!amd_iommu_v2_supported())
@@ -515,7 +515,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,if(!mem)panic("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer");-if(mem_encrypt_active())+if(prot_guest_has(PATTR_MEM_ENCRYPT))pr_warn_once("Memory encryption is active and system is using DMA bounce buffers\n");if(mapping_size>alloc_size){
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:01:32
The mem_encrypt_active() function has been replaced by prot_guest_has(),
so remove the implementation.
Reviewed-by: Joerg Roedel <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
include/linux/mem_encrypt.h | 4 ----
1 file changed, 4 deletions(-)
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:01:46
The mem_encrypt_active() function has been replaced by prot_guest_has(),
so remove the implementation.
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Reviewed-by: Joerg Roedel <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/x86/include/asm/mem_encrypt.h | 5 -----
1 file changed, 5 deletions(-)
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:01:54
The mem_encrypt_active() function has been replaced by prot_guest_has(),
so remove the implementation.
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/powerpc/include/asm/mem_encrypt.h | 5 -----
1 file changed, 5 deletions(-)
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:01:58
The mem_encrypt_active() function has been replaced by prot_guest_has(),
so remove the implementation. Since the default implementation of the
prot_guest_has() matches the s390 implementation of mem_encrypt_active(),
prot_guest_has() does not need to be implemented in s390 (the config
option ARCH_HAS_PROTECTED_GUEST is not set).
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/s390/include/asm/mem_encrypt.h | 2 --
1 file changed, 2 deletions(-)
In prep for other protected virtualization technologies, introduce a
generic helper function, prot_guest_has(), that can be used to check
for specific protection attributes, like memory encryption. This is
intended to eliminate having to add multiple technology-specific checks
to the code (e.g. if (sev_active() || tdx_active())).
Reviewed-by: Joerg Roedel<redacted>
Co-developed-by: Andi Kleen<redacted>
Signed-off-by: Andi Kleen<redacted>
Co-developed-by: Kuppuswamy Sathyanarayanan<sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan<sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Tom Lendacky<thomas.lendacky@amd.com>
---
arch/Kconfig | 3 +++
include/linux/protected_guest.h | 35 +++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+)
create mode 100644 include/linux/protected_guest.h
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-13 17:22:59
On 8/13/21 11:59 AM, Tom Lendacky wrote:
This patch series provides a generic helper function, prot_guest_has(),
to replace the sme_active(), sev_active(), sev_es_active() and
mem_encrypt_active() functions.
It is expected that as new protected virtualization technologies are
added to the kernel, they can all be covered by a single function call
instead of a collection of specific function calls all called from the
same locations.
The powerpc and s390 patches have been compile tested only. Can the
folks copied on this series verify that nothing breaks for them.
There are some patches related to PPC that added new calls to the
mem_encrypt_active() function that are not yet in the tip tree. After the
merge window, I'll need to send a v3 with those additional changes before
this series can be applied.
Thanks,
Tom
On Fri, Aug 13, 2021 at 11:59:20AM -0500, Tom Lendacky wrote:
In prep for other uses of the prot_guest_has() function besides AMD's
memory encryption support, selectively build the AMD memory encryption
architecture override functions only when CONFIG_AMD_MEM_ENCRYPT=y. These
functions are:
- early_memremap_pgprot_adjust()
- arch_memremap_can_ram_remap()
Additionally, routines that are only invoked by these architecture
override functions can also be conditionally built. These functions are:
- memremap_should_map_decrypted()
- memremap_is_efi_data()
- memremap_is_setup_data()
- early_memremap_is_setup_data()
And finally, phys_mem_access_encrypted() is conditionally built as well,
but requires a static inline version of it when CONFIG_AMD_MEM_ENCRYPT is
not set.
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/x86/include/asm/io.h | 8 ++++++++
arch/x86/mm/ioremap.c | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
On Fri, Aug 13, 2021 at 11:59:21AM -0500, Tom Lendacky wrote:
quoted hunk
In prep for other protected virtualization technologies, introduce a
generic helper function, prot_guest_has(), that can be used to check
for specific protection attributes, like memory encryption. This is
intended to eliminate having to add multiple technology-specific checks
to the code (e.g. if (sev_active() || tdx_active())).
Reviewed-by: Joerg Roedel <redacted>
Co-developed-by: Andi Kleen <redacted>
Signed-off-by: Andi Kleen <redacted>
Co-developed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/Kconfig | 3 +++
include/linux/protected_guest.h | 35 +++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+)
create mode 100644 include/linux/protected_guest.h
I think this can be simplified more, diff ontop below:
- no need for the ifdeffery as amd_prot_guest_has() has versions for
both when CONFIG_AMD_MEM_ENCRYPT is set or not.
- the sme_me_mask check is pushed there too.
- and since this is vendor-specific, I'm checking the vendor bit. Yeah,
yeah, cross-vendor but I don't really believe that.
---
I think this can be simplified more, diff ontop below:
- no need for the ifdeffery as amd_prot_guest_has() has versions for
both when CONFIG_AMD_MEM_ENCRYPT is set or not.
Ugh, yeah, not sure why I put that in for this version since I have the
static inline for when CONFIG_AMD_MEM_ENCRYPT is not set.
- the sme_me_mask check is pushed there too.
- and since this is vendor-specific, I'm checking the vendor bit. Yeah,
yeah, cross-vendor but I don't really believe that.
It's not a cross-vendor thing as opposed to a KVM or other hypervisor
thing where the family doesn't have to be reported as AMD or HYGON. That's
why I made the if check be for sme_me_mask. I think that is the safer way
to go.
Thanks,
Tom
On Sun, Aug 15, 2021 at 08:53:31AM -0500, Tom Lendacky wrote:
It's not a cross-vendor thing as opposed to a KVM or other hypervisor
thing where the family doesn't have to be reported as AMD or HYGON.
What would be the use case? A HV starts a guest which is supposed to be
encrypted using the AMD's confidential guest technology but the HV tells
the guest that it is not running on an AMD SVM HV but something else?
Is that even an actual use case?
Or am I way off?
I know we have talked about this in the past but this still sounds
insane.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On Fri, Aug 13, 2021 at 11:59:23AM -0500, Tom Lendacky wrote:
quoted hunk
Introduce a powerpc version of the prot_guest_has() function. This will
be used to replace the powerpc mem_encrypt_active() implementation, so
the implementation will initially only support the PATTR_MEM_ENCRYPT
attribute.
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/powerpc/include/asm/protected_guest.h | 30 ++++++++++++++++++++++
arch/powerpc/platforms/pseries/Kconfig | 1 +
2 files changed, 31 insertions(+)
create mode 100644 arch/powerpc/include/asm/protected_guest.h
@@ -144,7 +144,7 @@ void __init sme_unmap_bootdata(char *real_mode_data)structboot_params*boot_data;unsignedlongcmdline_paddr;-if(!sme_active())+if(!amd_prot_guest_has(PATTR_SME))return;/* Get the command line address before unmapping the real_mode_data */
@@ -364,8 +364,9 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)/**SMEandSEVareverysimilarbuttheyarenotthesame,sothereare*timesthatthekernelwillneedtodistinguishbetweenSMEandSEV.The-*sme_active()andsev_active()functionsareusedforthis.Whena-*distinctionisn'tneeded,themem_encrypt_active()functioncanbeused.+*PATTR_HOST_MEM_ENCRYPTandPATTR_GUEST_MEM_ENCRYPTflagsto+*amd_prot_guest_has()areusedforthis.Whenadistinctionisn'tneeded,+*themem_encrypt_active()functioncanbeused.**Thetrampolinecodeisagoodexampleforthisrequirement.Before*pagingisactivated,SMEwillaccessallmemoryasdecrypted,butSEV
@@ -377,11 +378,6 @@ bool sev_active(void){returnsev_status&MSR_AMD64_SEV_ENABLED;}--staticboolsme_active(void)-{-returnsme_me_mask&&!sev_active();-}EXPORT_SYMBOL_GPL(sev_active);/* Needs to be called from non-instrumentable code */
@@ -398,7 +394,7 @@ bool amd_prot_guest_has(unsigned int attr)casePATTR_SME:casePATTR_HOST_MEM_ENCRYPT:-returnsme_active();+returnsme_me_mask&&!sev_active();casePATTR_SEV:casePATTR_GUEST_MEM_ENCRYPT:
quoted hunk
{
return sme_me_mask && !sev_active();
}
@@ -428,7 +428,7 @@ bool force_dma_unencrypted(struct device *dev) * device does not support DMA to addresses that include the * encryption mask. */- if (sme_active()) {+ if (amd_prot_guest_has(PATTR_SME)) {
So I'm not sure: you add PATTR_SME which you call with
amd_prot_guest_has() and PATTR_HOST_MEM_ENCRYPT which you call with
prot_guest_has() and they both end up being the same thing on AMD.
So why even bother with PATTR_SME?
This is only going to cause confusion later and I'd say let's simply use
prot_guest_has(PATTR_HOST_MEM_ENCRYPT) everywhere...
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
@@ -583,12 +583,12 @@ int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, gfp_t gfp) void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) {- if (sev_active())+ if (!prot_guest_has(PATTR_HOST_MEM_ENCRYPT)) return; /*- * If SME is active we need to reset the pages back to being- * an encrypted mapping before freeing them.+ * If host memory encryption is active we need to reset the pages back+ * to being an encrypted mapping before freeing them. */ set_memory_encrypted((unsigned long)vaddr, pages); }
@@ -457,7 +458,7 @@ static int has_svm(void)return0;}-if(sev_active()){+if(prot_guest_has(PATTR_SEV)){pr_info("KVM is unsupported when running as an SEV guest\n");return0;
Same question as for PATTR_SME. PATTR_GUEST_MEM_ENCRYPT should be enough.
quoted hunk
@@ -373,7 +373,7 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size) * up under SME the trampoline area cannot be encrypted, whereas under SEV * the trampoline area must be encrypted. */-bool sev_active(void)+static bool sev_active(void) { return sev_status & MSR_AMD64_SEV_ENABLED; }
On Fri, Aug 13, 2021 at 11:59:26AM -0500, Tom Lendacky wrote:
Replace occurrences of sev_es_active() with the more generic
prot_guest_has() using PATTR_GUEST_PROT_STATE, except for in
arch/x86/kernel/sev*.c and arch/x86/mm/mem_encrypt*.c where PATTR_SEV_ES
will be used. If future support is added for other memory encyrption
techonologies, the use of PATTR_GUEST_PROT_STATE can be updated, as
required, to specifically use PATTR_SEV_ES.
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/x86/include/asm/mem_encrypt.h | 2 --
arch/x86/kernel/sev.c | 6 +++---
arch/x86/mm/mem_encrypt.c | 7 +++----
arch/x86/realmode/init.c | 3 +--
4 files changed, 7 insertions(+), 11 deletions(-)
On Fri, Aug 13, 2021 at 11:59:28AM -0500, Tom Lendacky wrote:
quoted hunk
The mem_encrypt_active() function has been replaced by prot_guest_has(),
so remove the implementation.
Reviewed-by: Joerg Roedel <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
include/linux/mem_encrypt.h | 4 ----
1 file changed, 4 deletions(-)
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2021-08-17 12:38:32
Tom Lendacky [off-list ref] writes:
quoted hunk
Introduce a powerpc version of the prot_guest_has() function. This will
be used to replace the powerpc mem_encrypt_active() implementation, so
the implementation will initially only support the PATTR_MEM_ENCRYPT
attribute.
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/powerpc/include/asm/protected_guest.h | 30 ++++++++++++++++++++++
arch/powerpc/platforms/pseries/Kconfig | 1 +
2 files changed, 31 insertions(+)
create mode 100644 arch/powerpc/include/asm/protected_guest.h
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-17 14:12:06
On 8/17/21 3:35 AM, Borislav Petkov wrote:
On Fri, Aug 13, 2021 at 11:59:23AM -0500, Tom Lendacky wrote:
quoted
Introduce a powerpc version of the prot_guest_has() function. This will
be used to replace the powerpc mem_encrypt_active() implementation, so
the implementation will initially only support the PATTR_MEM_ENCRYPT
attribute.
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
arch/powerpc/include/asm/protected_guest.h | 30 ++++++++++++++++++++++
arch/powerpc/platforms/pseries/Kconfig | 1 +
2 files changed, 31 insertions(+)
create mode 100644 arch/powerpc/include/asm/protected_guest.h
@@ -144,7 +144,7 @@ void __init sme_unmap_bootdata(char *real_mode_data)structboot_params*boot_data;unsignedlongcmdline_paddr;-if(!sme_active())+if(!amd_prot_guest_has(PATTR_SME))return;/* Get the command line address before unmapping the real_mode_data */
@@ -364,8 +364,9 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size)/**SMEandSEVareverysimilarbuttheyarenotthesame,sothereare*timesthatthekernelwillneedtodistinguishbetweenSMEandSEV.The-*sme_active()andsev_active()functionsareusedforthis.Whena-*distinctionisn'tneeded,themem_encrypt_active()functioncanbeused.+*PATTR_HOST_MEM_ENCRYPTandPATTR_GUEST_MEM_ENCRYPTflagsto+*amd_prot_guest_has()areusedforthis.Whenadistinctionisn'tneeded,+*themem_encrypt_active()functioncanbeused.**Thetrampolinecodeisagoodexampleforthisrequirement.Before*pagingisactivated,SMEwillaccessallmemoryasdecrypted,butSEV
@@ -377,11 +378,6 @@ bool sev_active(void){returnsev_status&MSR_AMD64_SEV_ENABLED;}--staticboolsme_active(void)-{-returnsme_me_mask&&!sev_active();-}EXPORT_SYMBOL_GPL(sev_active);/* Needs to be called from non-instrumentable code */
@@ -398,7 +394,7 @@ bool amd_prot_guest_has(unsigned int attr)casePATTR_SME:casePATTR_HOST_MEM_ENCRYPT:-returnsme_active();+returnsme_me_mask&&!sev_active();casePATTR_SEV:casePATTR_GUEST_MEM_ENCRYPT:
quoted
{
return sme_me_mask && !sev_active();
}
@@ -428,7 +428,7 @@ bool force_dma_unencrypted(struct device *dev) * device does not support DMA to addresses that include the * encryption mask. */- if (sme_active()) {+ if (amd_prot_guest_has(PATTR_SME)) {
So I'm not sure: you add PATTR_SME which you call with
amd_prot_guest_has() and PATTR_HOST_MEM_ENCRYPT which you call with
prot_guest_has() and they both end up being the same thing on AMD.
So why even bother with PATTR_SME?
This is only going to cause confusion later and I'd say let's simply use
prot_guest_has(PATTR_HOST_MEM_ENCRYPT) everywhere...
Ok, I can do that. I was trying to ensure that anything that is truly SME
or SEV specific would be called out now.
I'm ok with letting the TDX folks make changes to these calls to be SME or
SEV specific, if necessary, later.
Thanks,
Tom
From: Tom Lendacky <thomas.lendacky@amd.com> Date: 2021-08-17 15:23:01
On 8/15/21 9:39 AM, Borislav Petkov wrote:
On Sun, Aug 15, 2021 at 08:53:31AM -0500, Tom Lendacky wrote:
quoted
It's not a cross-vendor thing as opposed to a KVM or other hypervisor
thing where the family doesn't have to be reported as AMD or HYGON.
What would be the use case? A HV starts a guest which is supposed to be
encrypted using the AMD's confidential guest technology but the HV tells
the guest that it is not running on an AMD SVM HV but something else?
Is that even an actual use case?
Or am I way off?
I know we have talked about this in the past but this still sounds
insane.
Maybe the KVM folks have a better understanding of it...
I can change it to be an AMD/HYGON check... although, I'll have to check
to see if any (very) early use of the function will work with that.
At a minimum, the check in arch/x86/kernel/head64.c will have to be
changed or removed. I'll take a closer look.
Thanks,
Tom
That hunk belongs logically into the previous patch which removes
sme_active().
I was trying to keep the sev_active() changes separate... so even though
it's an SME thing, I kept it here. But I can move it to the previous
patch, it just might look strange.
@@ -583,12 +583,12 @@ int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, gfp_t gfp) void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) {- if (sev_active())+ if (!prot_guest_has(PATTR_HOST_MEM_ENCRYPT)) return; /*- * If SME is active we need to reset the pages back to being- * an encrypted mapping before freeing them.+ * If host memory encryption is active we need to reset the pages back+ * to being an encrypted mapping before freeing them. */ set_memory_encrypted((unsigned long)vaddr, pages); }
@@ -457,7 +458,7 @@ static int has_svm(void)return0;}-if(sev_active()){+if(prot_guest_has(PATTR_SEV)){pr_info("KVM is unsupported when running as an SEV guest\n");return0;
Same question as for PATTR_SME. PATTR_GUEST_MEM_ENCRYPT should be enough.
Yup, I'll change them all.
quoted
@@ -373,7 +373,7 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size) * up under SME the trampoline area cannot be encrypted, whereas under SEV * the trampoline area must be encrypted. */-bool sev_active(void)+static bool sev_active(void) { return sev_status & MSR_AMD64_SEV_ENABLED; }
On Tue, Aug 17, 2021 at 10:26:18AM -0500, Tom Lendacky wrote:
quoted
quoted
/*
- * If SME is active we need to be sure that kexec pages are
- * not encrypted because when we boot to the new kernel the
+ * If host memory encryption is active we need to be sure that kexec
+ * pages are not encrypted because when we boot to the new kernel the
* pages won't be accessed encrypted (initially).
*/
That hunk belongs logically into the previous patch which removes
sme_active().
I was trying to keep the sev_active() changes separate... so even though
it's an SME thing, I kept it here. But I can move it to the previous
patch, it just might look strange.
Why do we need reservations for a purely in-kernel namespace?
And why are you overoading a brand new generic API with weird details
of a specific implementation like this?
On Thu, Aug 19, 2021 at 10:52:53AM +0100, Christoph Hellwig wrote:
Which suggest that the name is not good to start with. Maybe protected
hardware, system or platform might be a better choice?
Yah, coming up with a proper name here hasn't been easy.
prot_guest_has() is not the first variant.
From all three things you suggest above, I guess calling it a "platform"
is the closest. As in, this is a confidential computing platform which
provides host and guest facilities etc.
So calling it
confidential_computing_platform_has()
is obviously too long.
ccp_has() clashes with the namespace of drivers/crypto/ccp/ which is
used by the technology too.
coco_platform_has() is too unserious.
So I guess
cc_platform_has()
ain't all that bad.
Unless you have a better idea, ofc.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
I did it as inline originally because the presence of the function will be
decided based on the ARCH_HAS_PROTECTED_GUEST config. For now, that is
only selected by the AMD memory encryption support, so if I went out of
line I could put in mem_encrypt.c. But with TDX wanting to also use it, it
would have to be in an always built file with some #ifdefs or in its own
file that is conditionally built based on the ARCH_HAS_PROTECTED_GUEST
setting (they've already tried building with ARCH_HAS_PROTECTED_GUEST=y
and AMD_MEM_ENCRYPT not set).
To take it out of line, I'm leaning towards the latter, creating a new
file that is built based on the ARCH_HAS_PROTECTED_GUEST setting.
Why do we need reservations for a purely in-kernel namespace?
And why are you overoading a brand new generic API with weird details
of a specific implementation like this?
There was some talk about this on the mailing list where TDX and SEV may
need to be differentiated, so we wanted to reserve a range of values per
technology. I guess I can remove them until they are actually needed.
Thanks,
Tom
There was some talk about this on the mailing list where TDX and SEV may
need to be differentiated, so we wanted to reserve a range of values per
technology. I guess I can remove them until they are actually needed.
In TDX also we have similar requirements and we need some flags for
TDX specific checks. So I think it is fine to leave some space for vendor
flags.
--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer
From: Christoph Hellwig <hch@infradead.org> Date: 2021-08-24 07:16:24
On Thu, Aug 19, 2021 at 01:33:09PM -0500, Tom Lendacky wrote:
I did it as inline originally because the presence of the function will be
decided based on the ARCH_HAS_PROTECTED_GUEST config. For now, that is
only selected by the AMD memory encryption support, so if I went out of
line I could put in mem_encrypt.c. But with TDX wanting to also use it, it
would have to be in an always built file with some #ifdefs or in its own
file that is conditionally built based on the ARCH_HAS_PROTECTED_GUEST
setting (they've already tried building with ARCH_HAS_PROTECTED_GUEST=y
and AMD_MEM_ENCRYPT not set).
To take it out of line, I'm leaning towards the latter, creating a new
file that is built based on the ARCH_HAS_PROTECTED_GUEST setting.
Yes. In general everytime architectures have to provide the prototype
and not just the implementation of something we end up with a giant mess
sooner or later. In a few cases that is still warranted due to
performance concerns, but i don't think that is the case here.
Why do we need reservations for a purely in-kernel namespace?
And why are you overoading a brand new generic API with weird details
of a specific implementation like this?
There was some talk about this on the mailing list where TDX and SEV may
need to be differentiated, so we wanted to reserve a range of values per
technology. I guess I can remove them until they are actually needed.
In that case add a flag for the differing behavior. And only add them
when actually needed. And either way there is absolutely no need to
reserve ranges.