From 6757a17b2aaac00dbcb12d1a32adcd76e7b68be6 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Fri, 11 Nov 2011 12:04:10 +0100 Subject: [PATCH] amd iommu: Simplify IVHD device flag handling These bits are aligned to corresponding fields in device table entry. They can be updated by a single device entry write. Signed-off-by: Wei Wang Committed-by: Jan Beulich --- xen/drivers/passthrough/amd/iommu_acpi.c | 28 ++------------- xen/drivers/passthrough/amd/iommu_init.c | 24 ++----------- xen/drivers/passthrough/amd/iommu_map.c | 35 +++++++------------ xen/include/asm-x86/amd-iommu.h | 9 ++--- xen/include/asm-x86/hvm/svm/amd-iommu-defs.h | 13 ++----- xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 4 +-- 6 files changed, 22 insertions(+), 91 deletions(-) diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c index a26914b6e9..67d98131ad 100644 --- a/xen/drivers/passthrough/amd/iommu_acpi.c +++ b/xen/drivers/passthrough/amd/iommu_acpi.c @@ -31,38 +31,14 @@ static void __init add_ivrs_mapping_entry( u16 bdf, u16 alias_id, u8 flags, struct amd_iommu *iommu) { struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(iommu->seg); - u8 sys_mgt, lint1_pass, lint0_pass, nmi_pass, ext_int_pass, init_pass; + ASSERT( ivrs_mappings != NULL ); /* setup requestor id */ ivrs_mappings[bdf].dte_requestor_id = alias_id; /* override flags for range of devices */ - sys_mgt = get_field_from_byte(flags, - AMD_IOMMU_ACPI_SYS_MGT_MASK, - AMD_IOMMU_ACPI_SYS_MGT_SHIFT); - lint1_pass = get_field_from_byte(flags, - AMD_IOMMU_ACPI_LINT1_PASS_MASK, - AMD_IOMMU_ACPI_LINT1_PASS_SHIFT); - lint0_pass = get_field_from_byte(flags, - AMD_IOMMU_ACPI_LINT0_PASS_MASK, - AMD_IOMMU_ACPI_LINT0_PASS_SHIFT); - nmi_pass = get_field_from_byte(flags, - AMD_IOMMU_ACPI_NMI_PASS_MASK, - AMD_IOMMU_ACPI_NMI_PASS_SHIFT); - ext_int_pass = get_field_from_byte(flags, - AMD_IOMMU_ACPI_EINT_PASS_MASK, - AMD_IOMMU_ACPI_EINT_PASS_SHIFT); - init_pass = get_field_from_byte(flags, - AMD_IOMMU_ACPI_INIT_PASS_MASK, - AMD_IOMMU_ACPI_INIT_PASS_SHIFT); - - ivrs_mappings[bdf].dte_sys_mgt_enable = sys_mgt; - ivrs_mappings[bdf].dte_lint1_pass = lint1_pass; - ivrs_mappings[bdf].dte_lint0_pass = lint0_pass; - ivrs_mappings[bdf].dte_nmi_pass = nmi_pass; - ivrs_mappings[bdf].dte_ext_int_pass = ext_int_pass; - ivrs_mappings[bdf].dte_init_pass = init_pass; + ivrs_mappings[bdf].device_flags = flags; if (ivrs_mappings[alias_id].intremap_table == NULL ) { diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c index 397df5f66f..a6ee4a0431 100644 --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -790,18 +790,12 @@ static int __init alloc_ivrs_mappings(u16 seg) for ( bdf = 0; bdf < ivrs_bdf_entries; bdf++ ) { ivrs_mappings[bdf].dte_requestor_id = bdf; - ivrs_mappings[bdf].dte_sys_mgt_enable = - IOMMU_DEV_TABLE_SYS_MGT_MSG_FORWARDED; ivrs_mappings[bdf].dte_allow_exclusion = IOMMU_CONTROL_DISABLED; ivrs_mappings[bdf].unity_map_enable = IOMMU_CONTROL_DISABLED; ivrs_mappings[bdf].iommu = NULL; ivrs_mappings[bdf].intremap_table = NULL; - ivrs_mappings[bdf].dte_lint1_pass = IOMMU_CONTROL_DISABLED; - ivrs_mappings[bdf].dte_lint0_pass = IOMMU_CONTROL_DISABLED; - ivrs_mappings[bdf].dte_nmi_pass = IOMMU_CONTROL_DISABLED; - ivrs_mappings[bdf].dte_ext_int_pass = IOMMU_CONTROL_DISABLED; - ivrs_mappings[bdf].dte_init_pass = IOMMU_CONTROL_DISABLED; + ivrs_mappings[bdf].device_flags = 0; if ( amd_iommu_perdev_intremap ) spin_lock_init(&ivrs_mappings[bdf].intremap_lock); @@ -817,8 +811,6 @@ static int __init amd_iommu_setup_device_table( { int bdf; void *intr_tb, *dte; - int sys_mgt, dev_ex, lint1_pass, lint0_pass, - nmi_pass, ext_int_pass, init_pass; BUG_ON( (ivrs_bdf_entries == 0) ); @@ -840,21 +832,9 @@ static int __init amd_iommu_setup_device_table( if ( intr_tb ) { - sys_mgt = ivrs_mappings[bdf].dte_sys_mgt_enable; - dev_ex = ivrs_mappings[bdf].dte_allow_exclusion; - - /* get interrupt remapping settings */ - lint1_pass = ivrs_mappings[bdf].dte_lint1_pass; - lint0_pass = ivrs_mappings[bdf].dte_lint0_pass; - nmi_pass = ivrs_mappings[bdf].dte_nmi_pass; - ext_int_pass = ivrs_mappings[bdf].dte_ext_int_pass; - init_pass = ivrs_mappings[bdf].dte_init_pass; - /* add device table entry */ dte = device_table.buffer + (bdf * IOMMU_DEV_TABLE_ENTRY_SIZE); - amd_iommu_add_dev_table_entry( - dte, sys_mgt, dev_ex, lint1_pass, lint0_pass, - nmi_pass, ext_int_pass, init_pass); + iommu_dte_add_device_entry(dte, &ivrs_mappings[bdf]); amd_iommu_set_intremap_table( dte, (u64)virt_to_maddr(intr_tb), iommu_intremap); diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthrough/amd/iommu_map.c index f51b3429a4..2b249226bb 100644 --- a/xen/drivers/passthrough/amd/iommu_map.c +++ b/xen/drivers/passthrough/amd/iommu_map.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "../ats.h" #include @@ -419,35 +420,23 @@ void __init amd_iommu_set_intremap_table( dte[4] = entry; } -void __init amd_iommu_add_dev_table_entry( - u32 *dte, u8 sys_mgt, u8 dev_ex, u8 lint1_pass, u8 lint0_pass, - u8 nmi_pass, u8 ext_int_pass, u8 init_pass) +void __init iommu_dte_add_device_entry(u32 *dte, struct ivrs_mappings *ivrs_dev) { u32 entry; + u8 sys_mgt, dev_ex, flags; + u8 mask = ~(0x7 << 3); dte[7] = dte[6] = dte[4] = dte[2] = dte[1] = dte[0] = 0; + flags = ivrs_dev->device_flags; + sys_mgt = get_field_from_byte(flags, AMD_IOMMU_ACPI_SYS_MGT_MASK, + AMD_IOMMU_ACPI_SYS_MGT_SHIFT); + dev_ex = ivrs_dev->dte_allow_exclusion; - set_field_in_reg_u32(init_pass ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, 0, - IOMMU_DEV_TABLE_INIT_PASSTHRU_MASK, - IOMMU_DEV_TABLE_INIT_PASSTHRU_SHIFT, &entry); - set_field_in_reg_u32(ext_int_pass ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_EINT_PASSTHRU_MASK, - IOMMU_DEV_TABLE_EINT_PASSTHRU_SHIFT, &entry); - set_field_in_reg_u32(nmi_pass ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_NMI_PASSTHRU_MASK, - IOMMU_DEV_TABLE_NMI_PASSTHRU_SHIFT, &entry); - set_field_in_reg_u32(lint0_pass ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_LINT0_ENABLE_MASK, - IOMMU_DEV_TABLE_LINT0_ENABLE_SHIFT, &entry); - set_field_in_reg_u32(lint1_pass ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_LINT1_ENABLE_MASK, - IOMMU_DEV_TABLE_LINT1_ENABLE_SHIFT, &entry); + flags &= mask; + set_field_in_reg_u32(flags, 0, + IOMMU_DEV_TABLE_IVHD_FLAGS_MASK, + IOMMU_DEV_TABLE_IVHD_FLAGS_SHIFT, &entry); dte[5] = entry; set_field_in_reg_u32(sys_mgt, 0, diff --git a/xen/include/asm-x86/amd-iommu.h b/xen/include/asm-x86/amd-iommu.h index df36fe25ac..2719e3a72d 100644 --- a/xen/include/asm-x86/amd-iommu.h +++ b/xen/include/asm-x86/amd-iommu.h @@ -86,7 +86,6 @@ struct amd_iommu { struct ivrs_mappings { u16 dte_requestor_id; - u8 dte_sys_mgt_enable; u8 dte_allow_exclusion; u8 unity_map_enable; u8 write_permission; @@ -99,12 +98,8 @@ struct ivrs_mappings { void *intremap_table; spinlock_t intremap_lock; - /* interrupt remapping settings */ - u8 dte_lint1_pass; - u8 dte_lint0_pass; - u8 dte_nmi_pass; - u8 dte_ext_int_pass; - u8 dte_init_pass; + /* ivhd device data settings */ + u8 device_flags; }; extern unsigned short ivrs_bdf_entries; diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h index dfcf4d77b9..b5c35b0027 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h @@ -158,18 +158,11 @@ /* DeviceTable Entry[191:160] */ #define IOMMU_DEV_TABLE_INT_TABLE_PTR_HIGH_MASK 0x000FFFFF #define IOMMU_DEV_TABLE_INT_TABLE_PTR_HIGH_SHIFT 0 -#define IOMMU_DEV_TABLE_INIT_PASSTHRU_MASK 0x01000000 -#define IOMMU_DEV_TABLE_INIT_PASSTHRU_SHIFT 24 -#define IOMMU_DEV_TABLE_EINT_PASSTHRU_MASK 0x02000000 -#define IOMMU_DEV_TABLE_EINT_PASSTHRU_SHIFT 25 -#define IOMMU_DEV_TABLE_NMI_PASSTHRU_MASK 0x04000000 -#define IOMMU_DEV_TABLE_NMI_PASSTHRU_SHIFT 26 +#define IOMMU_DEV_TABLE_IVHD_FLAGS_SHIFT 24 +#define IOMMU_DEV_TABLE_IVHD_FLAGS_MASK 0xC7000000 #define IOMMU_DEV_TABLE_INT_CONTROL_MASK 0x30000000 #define IOMMU_DEV_TABLE_INT_CONTROL_SHIFT 28 -#define IOMMU_DEV_TABLE_LINT0_ENABLE_MASK 0x40000000 -#define IOMMU_DEV_TABLE_LINT0_ENABLE_SHIFT 30 -#define IOMMU_DEV_TABLE_LINT1_ENABLE_MASK 0x80000000 -#define IOMMU_DEV_TABLE_LINT1_ENABLE_SHIFT 31 + /* Command Buffer */ #define IOMMU_CMD_BUFFER_BASE_LOW_OFFSET 0x08 diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h index 7e2d8f56e6..1268a287f8 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h @@ -68,14 +68,12 @@ void amd_iommu_share_p2m(struct domain *d); /* device table functions */ int get_dma_requestor_id(u16 seg, u16 bdf); -void amd_iommu_add_dev_table_entry( - u32 *dte, u8 sys_mgt, u8 dev_ex, u8 lint1_pass, u8 lint0_pass, - u8 nmi_pass, u8 ext_int_pass, u8 init_pass); void amd_iommu_set_intremap_table( u32 *dte, u64 intremap_ptr, u8 int_valid); void amd_iommu_set_root_page_table( u32 *dte, u64 root_ptr, u16 domain_id, u8 paging_mode, u8 valid); void iommu_dte_set_iotlb(u32 *dte, u8 i); +void iommu_dte_add_device_entry(u32 *dte, struct ivrs_mappings *ivrs_dev); void invalidate_dev_table_entry(struct amd_iommu *iommu, u16 devic_id); /* send cmd to iommu */ -- 2.30.2