mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
iommu/amd: Adhere to IVINFO[VASIZE] for address limits
ACPI IVRS IVHD’s IVINFO field reports the maximum virtual address size (VASIZE) supported by the IOMMU. The AMD IOMMU driver currently caps this with pagetable level reported by EFR[HATS] when configuring paging domains (hw_max_vasz_lg2). On systems where firmware or VM advertises smaller or different limits, the driver may over-advertise capabilities and create domains outside the hardware’s actual bounds. Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
d9f759704b
commit
33730f0688
|
|
@ -44,7 +44,7 @@ int amd_iommu_enable_faulting(unsigned int cpu);
|
|||
extern int amd_iommu_guest_ir;
|
||||
extern enum protection_domain_mode amd_iommu_pgtable;
|
||||
extern int amd_iommu_gpt_level;
|
||||
extern u8 amd_iommu_hpt_level;
|
||||
extern u8 amd_iommu_hpt_vasize;
|
||||
extern unsigned long amd_iommu_pgsize_bitmap;
|
||||
extern bool amd_iommu_hatdis;
|
||||
|
||||
|
|
|
|||
|
|
@ -400,6 +400,7 @@
|
|||
#define IOMMU_IVINFO_OFFSET 36
|
||||
#define IOMMU_IVINFO_EFRSUP BIT(0)
|
||||
#define IOMMU_IVINFO_DMA_REMAP BIT(1)
|
||||
#define IOMMU_IVINFO_VASIZE GENMASK_ULL(21, 15)
|
||||
|
||||
/* IOMMU Feature Reporting Field (for IVHD type 10h */
|
||||
#define IOMMU_FEAT_GASUP_SHIFT 6
|
||||
|
|
|
|||
|
|
@ -155,8 +155,8 @@ bool amd_iommu_dump;
|
|||
bool amd_iommu_irq_remap __read_mostly;
|
||||
|
||||
enum protection_domain_mode amd_iommu_pgtable = PD_MODE_V1;
|
||||
/* Host page table level */
|
||||
u8 amd_iommu_hpt_level;
|
||||
/* Virtual address size */
|
||||
u8 amd_iommu_hpt_vasize;
|
||||
/* Guest page table level */
|
||||
int amd_iommu_gpt_level = PAGE_MODE_4_LEVEL;
|
||||
|
||||
|
|
@ -3202,7 +3202,7 @@ static int __init early_amd_iommu_init(void)
|
|||
struct acpi_table_header *ivrs_base;
|
||||
int ret;
|
||||
acpi_status status;
|
||||
u8 efr_hats;
|
||||
u8 efr_hats, max_vasize;
|
||||
|
||||
if (!amd_iommu_detected)
|
||||
return -ENODEV;
|
||||
|
|
@ -3232,6 +3232,10 @@ static int __init early_amd_iommu_init(void)
|
|||
|
||||
ivinfo_init(ivrs_base);
|
||||
|
||||
max_vasize = FIELD_GET(IOMMU_IVINFO_VASIZE, amd_iommu_ivinfo);
|
||||
if (!max_vasize)
|
||||
max_vasize = 64;
|
||||
|
||||
amd_iommu_target_ivhd_type = get_highest_supported_ivhd_type(ivrs_base);
|
||||
DUMP_printk("Using IVHD type %#x\n", amd_iommu_target_ivhd_type);
|
||||
|
||||
|
|
@ -3254,7 +3258,8 @@ static int __init early_amd_iommu_init(void)
|
|||
* efr[HATS] bits specify the maximum host translation level
|
||||
* supported, with LEVEL 4 being initial max level.
|
||||
*/
|
||||
amd_iommu_hpt_level = efr_hats + PAGE_MODE_4_LEVEL;
|
||||
amd_iommu_hpt_vasize = min_t(unsigned int, max_vasize,
|
||||
(efr_hats + PAGE_MODE_4_LEVEL - 1) * 9 + 21);
|
||||
} else {
|
||||
pr_warn_once(FW_BUG "Disable host address translation due to invalid translation level (%#x).\n",
|
||||
efr_hats);
|
||||
|
|
|
|||
|
|
@ -2714,8 +2714,7 @@ static struct iommu_domain *amd_iommu_domain_alloc_paging_v1(struct device *dev,
|
|||
else
|
||||
cfg.common.features |= BIT(PT_FEAT_FLUSH_RANGE);
|
||||
|
||||
cfg.common.hw_max_vasz_lg2 =
|
||||
min(64, (amd_iommu_hpt_level - 1) * 9 + 21);
|
||||
cfg.common.hw_max_vasz_lg2 = amd_iommu_hpt_vasize;
|
||||
cfg.common.hw_max_oasz_lg2 = 52;
|
||||
cfg.starting_level = 2;
|
||||
domain->domain.ops = &amdv1_ops;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user