Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/amd: Don't rely on external callers to enable IOMMU SNP support

Currently, the expectation is that the kernel will call
amd_iommu_snp_enable() to perform various checks and set the
amd_iommu_snp_en flag that the IOMMU uses to adjust its setup routines
to account for additional requirements on hosts where SNP is enabled.

This is somewhat fragile as it relies on this call being done prior to
IOMMU setup. It is more robust to just do this automatically as part of
IOMMU initialization, so rework the code accordingly.

There is still a need to export information about whether or not the
IOMMU is configured in a manner compatible with SNP, so relocate the
existing amd_iommu_snp_en flag so it can be used to convey that
information in place of the return code that was previously provided by
calls to amd_iommu_snp_enable().

While here, also adjust the kernel messages related to IOMMU SNP
enablement for consistency/grammar/clarity.

Suggested-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Joerg Roedel <jroedel@suse.de>
Link: https://lore.kernel.org/r/20240126041126.1927228-4-michael.roth@amd.com

authored by

Ashish Kalra and committed by
Borislav Petkov (AMD)
04d65a9d acaa4b5c

+32 -43
+1
arch/x86/include/asm/iommu.h
··· 10 10 extern int iommu_detected; 11 11 extern int iommu_merge; 12 12 extern int panic_on_overflow; 13 + extern bool amd_iommu_snp_en; 13 14 14 15 #ifdef CONFIG_SWIOTLB 15 16 extern bool x86_swiotlb_enable;
-1
drivers/iommu/amd/amd_iommu.h
··· 164 164 u64 *root, int mode); 165 165 struct dev_table_entry *get_dev_table(struct amd_iommu *iommu); 166 166 167 - extern bool amd_iommu_snp_en; 168 167 #endif
+31 -38
drivers/iommu/amd/init.c
··· 3221 3221 return true; 3222 3222 } 3223 3223 3224 + static void iommu_snp_enable(void) 3225 + { 3226 + #ifdef CONFIG_KVM_AMD_SEV 3227 + if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) 3228 + return; 3229 + /* 3230 + * The SNP support requires that IOMMU must be enabled, and is 3231 + * not configured in the passthrough mode. 3232 + */ 3233 + if (no_iommu || iommu_default_passthrough()) { 3234 + pr_err("SNP: IOMMU disabled or configured in passthrough mode, SNP cannot be supported.\n"); 3235 + return; 3236 + } 3237 + 3238 + amd_iommu_snp_en = check_feature(FEATURE_SNP); 3239 + if (!amd_iommu_snp_en) { 3240 + pr_err("SNP: IOMMU SNP feature not enabled, SNP cannot be supported.\n"); 3241 + return; 3242 + } 3243 + 3244 + pr_info("IOMMU SNP support enabled.\n"); 3245 + 3246 + /* Enforce IOMMU v1 pagetable when SNP is enabled. */ 3247 + if (amd_iommu_pgtable != AMD_IOMMU_V1) { 3248 + pr_warn("Forcing use of AMD IOMMU v1 page table due to SNP.\n"); 3249 + amd_iommu_pgtable = AMD_IOMMU_V1; 3250 + } 3251 + #endif 3252 + } 3253 + 3224 3254 /**************************************************************************** 3225 3255 * 3226 3256 * AMD IOMMU Initialization State Machine ··· 3286 3256 break; 3287 3257 case IOMMU_ENABLED: 3288 3258 register_syscore_ops(&amd_iommu_syscore_ops); 3259 + iommu_snp_enable(); 3289 3260 ret = amd_iommu_init_pci(); 3290 3261 init_state = ret ? IOMMU_INIT_ERROR : IOMMU_PCI_INIT; 3291 3262 break; ··· 3797 3766 3798 3767 return iommu_pc_get_set_reg(iommu, bank, cntr, fxn, value, true); 3799 3768 } 3800 - 3801 - #ifdef CONFIG_AMD_MEM_ENCRYPT 3802 - int amd_iommu_snp_enable(void) 3803 - { 3804 - /* 3805 - * The SNP support requires that IOMMU must be enabled, and is 3806 - * not configured in the passthrough mode. 3807 - */ 3808 - if (no_iommu || iommu_default_passthrough()) { 3809 - pr_err("SNP: IOMMU is disabled or configured in passthrough mode, SNP cannot be supported"); 3810 - return -EINVAL; 3811 - } 3812 - 3813 - /* 3814 - * Prevent enabling SNP after IOMMU_ENABLED state because this process 3815 - * affect how IOMMU driver sets up data structures and configures 3816 - * IOMMU hardware. 3817 - */ 3818 - if (init_state > IOMMU_ENABLED) { 3819 - pr_err("SNP: Too late to enable SNP for IOMMU.\n"); 3820 - return -EINVAL; 3821 - } 3822 - 3823 - amd_iommu_snp_en = check_feature(FEATURE_SNP); 3824 - if (!amd_iommu_snp_en) 3825 - return -EINVAL; 3826 - 3827 - pr_info("SNP enabled\n"); 3828 - 3829 - /* Enforce IOMMU v1 pagetable when SNP is enabled. */ 3830 - if (amd_iommu_pgtable != AMD_IOMMU_V1) { 3831 - pr_warn("Force to using AMD IOMMU v1 page table due to SNP\n"); 3832 - amd_iommu_pgtable = AMD_IOMMU_V1; 3833 - } 3834 - 3835 - return 0; 3836 - } 3837 - #endif
-4
include/linux/amd-iommu.h
··· 85 85 u64 *value); 86 86 struct amd_iommu *get_amd_iommu(unsigned int idx); 87 87 88 - #ifdef CONFIG_AMD_MEM_ENCRYPT 89 - int amd_iommu_snp_enable(void); 90 - #endif 91 - 92 88 #endif /* _ASM_X86_AMD_IOMMU_H */