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 <wei.wang2@amd.com>
Committed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Wei Wang committed 2011-11-11 12:04:10 +01:00
1 parent 756273ab10
commit 6757a17b2a
6 files changed
+22 -91

No files matched your search

+2 -26
View File
@@ -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 )
{
+2 -22
View File
@@ -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);
+12 -23
View File
@@ -23,6 +23,7 @@
#include <xen/hvm/iommu.h>
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
#include <asm/hvm/svm/amd-iommu-acpi.h>
#include "../ats.h"
#include <xen/pci.h>
@@ -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,
+2 -7
View File
@@ -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;
+3 -10
View File
@@ -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
@@ -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 */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.