Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e5648b7
iommu/amd: Update struct iommu_dev_data definition
hegdevasant Jul 6, 2022
f813292
iommu/amd: Introduce pci segment structure
hegdevasant Jul 6, 2022
2375f1f
iommu/amd: Introduce per PCI segment device table
ssuthiku-amd Jul 6, 2022
0f09f47
iommu/amd: Introduce per PCI segment rlookup table
ssuthiku-amd Jul 6, 2022
e82b87e
iommu/amd: Introduce per PCI segment irq_lookup_table
hegdevasant Jul 6, 2022
85a8e73
iommu/amd: Introduce per PCI segment dev_data_list
hegdevasant Jul 6, 2022
d63b654
iommu/amd: Introduce per PCI segment old_dev_tbl_cpy
ssuthiku-amd Jul 6, 2022
e5c1a9b
iommu/amd: Introduce per PCI segment alias_table
ssuthiku-amd Jul 6, 2022
420d42d
iommu/amd: Introduce per PCI segment unity map list
hegdevasant Jul 6, 2022
ffee380
iommu/amd: Introduce per PCI segment last_bdf
hegdevasant Jul 6, 2022
377791a
iommu/amd: Introduce per PCI segment device table size
hegdevasant Jul 6, 2022
014b6a0
iommu/amd: Introduce per PCI segment alias table size
hegdevasant Jul 6, 2022
3885fd8
iommu/amd: Introduce per PCI segment rlookup table size
hegdevasant Jul 6, 2022
fca9ab6
iommu/amd: Convert to use per PCI segment irq_lookup_table
hegdevasant Jul 6, 2022
3cb1e00
iommu/amd: Convert to use rlookup_amd_iommu helper function
ssuthiku-amd Jul 6, 2022
b3eeaa1
iommu/amd: Update irq_remapping_alloc to use IOMMU lookup helper func…
ssuthiku-amd Jul 6, 2022
b88a023
iommu/amd: Introduce struct amd_ir_data.iommu
ssuthiku-amd Jul 6, 2022
408205e
iommu/amd: Update amd_irte_ops functions
ssuthiku-amd Jul 6, 2022
554e90e
iommu/amd: Update alloc_irq_table and alloc_irq_index
ssuthiku-amd Jul 6, 2022
b72d371
iommu/amd: Convert to use per PCI segment rlookup_table
hegdevasant Jul 6, 2022
32fb75e
iommu/amd: Update set_dte_entry and clear_dte_entry
ssuthiku-amd Jul 6, 2022
e964fd3
iommu/amd: Update iommu_ignore_device
ssuthiku-amd Jul 6, 2022
ce23b3d
iommu/amd: Update dump_dte_entry
ssuthiku-amd Jul 6, 2022
3c978f6
iommu/amd: Update set_dte_irq_entry
ssuthiku-amd Jul 6, 2022
af5c99c
iommu/amd: Update (un)init_device_table_dma()
ssuthiku-amd Jul 6, 2022
9f97b12
iommu/amd: Update set_dev_entry_bit() and get_dev_entry_bit()
ssuthiku-amd Jul 6, 2022
4451a13
iommu/amd: Remove global amd_iommu_[dev_table/alias_table/last_bdf]
ssuthiku-amd Jul 6, 2022
c3a95fa
iommu/amd: Flush upto last_bdf only
hegdevasant Jul 6, 2022
d238ec7
iommu/amd: Introduce get_device_sbdf_id() helper function
ssuthiku-amd Jul 6, 2022
fdb0a39
iommu/amd: Include PCI segment ID when initialize IOMMU
ssuthiku-amd Jul 6, 2022
e390ab0
iommu/amd: Specify PCI segment ID when getting pci device
ssuthiku-amd Jul 6, 2022
04a1148
iommu/amd: Print PCI segment ID in error log messages
hegdevasant Jul 6, 2022
c841ec2
iommu/amd: Update device_state structure to include PCI seg ID
hegdevasant Jul 6, 2022
f914799
iommu/amd: Update amd_iommu_fault structure to include PCI seg ID
hegdevasant Jul 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions drivers/iommu/amd/amd_iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@

extern irqreturn_t amd_iommu_int_thread(int irq, void *data);
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
extern void amd_iommu_apply_erratum_63(u16 devid);
extern void amd_iommu_apply_erratum_63(struct amd_iommu *iommu, u16 devid);
extern void amd_iommu_restart_event_logging(struct amd_iommu *iommu);
extern void amd_iommu_restart_ga_log(struct amd_iommu *iommu);
extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
extern int amd_iommu_init_devices(void);
extern void amd_iommu_uninit_devices(void);
extern void amd_iommu_init_notifier(void);
extern int amd_iommu_init_api(void);
extern void amd_iommu_set_rlookup_table(struct amd_iommu *iommu, u16 devid);

#ifdef CONFIG_AMD_IOMMU_DEBUGFS
void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
Expand Down Expand Up @@ -116,11 +117,18 @@ void amd_iommu_domain_clr_pt_root(struct protection_domain *domain)
amd_iommu_domain_set_pt_root(domain, 0);
}

static inline int get_pci_sbdf_id(struct pci_dev *pdev)
{
int seg = pci_domain_nr(pdev->bus);
u16 devid = pci_dev_id(pdev);

return PCI_SEG_DEVID_TO_SBDF(seg, devid);
}

extern bool translation_pre_enabled(struct amd_iommu *iommu);
extern bool amd_iommu_is_attach_deferred(struct iommu_domain *domain,
struct device *dev);
extern int __init add_special_device(u8 type, u8 id, u16 *devid,
extern int __init add_special_device(u8 type, u8 id, u32 *devid,
bool cmd_line);

#ifdef CONFIG_DMI
Expand All @@ -131,4 +139,5 @@ static inline void amd_iommu_apply_ivrs_quirks(void) { }

extern void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
u64 *root, int mode);
extern struct dev_table_entry *get_dev_table(struct amd_iommu *iommu);
#endif
133 changes: 96 additions & 37 deletions drivers/iommu/amd/amd_iommu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,14 +443,22 @@ struct irq_remap_table {
u32 *table;
};

extern struct irq_remap_table **irq_lookup_table;

/* Interrupt remapping feature used? */
extern bool amd_iommu_irq_remap;

/* kmem_cache to get tables with 128 byte alignement */
extern struct kmem_cache *amd_iommu_irq_cache;

#define PCI_SBDF_TO_SEGID(sbdf) (((sbdf) >> 16) & 0xffff)
#define PCI_SBDF_TO_DEVID(sbdf) ((sbdf) & 0xffff)
#define PCI_SEG_DEVID_TO_SBDF(seg, devid) ((((u32)(seg) & 0xffff) << 16) | \
((devid) & 0xffff))

/* Make iterating over all pci segment easier */
#define for_each_pci_segment(pci_seg) \
list_for_each_entry((pci_seg), &amd_iommu_pci_seg_list, list)
#define for_each_pci_segment_safe(pci_seg, next) \
list_for_each_entry_safe((pci_seg), (next), &amd_iommu_pci_seg_list, list)
/*
* Make iterating over all IOMMUs easier
*/
Expand All @@ -473,13 +481,14 @@ extern struct kmem_cache *amd_iommu_irq_cache;
struct amd_iommu_fault {
u64 address; /* IO virtual address of the fault*/
u32 pasid; /* Address space identifier */
u16 device_id; /* Originating PCI device id */
u32 sbdf; /* Originating PCI device id */
u16 tag; /* PPR tag */
u16 flags; /* Fault flags */

};


struct amd_iommu;
struct iommu_domain;
struct irq_domain;
struct amd_irte_ops;
Expand Down Expand Up @@ -525,6 +534,75 @@ struct protection_domain {
unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
};

/*
* This structure contains information about one PCI segment in the system.
*/
struct amd_iommu_pci_seg {
/* List with all PCI segments in the system */
struct list_head list;

/* List of all available dev_data structures */
struct llist_head dev_data_list;

/* PCI segment number */
u16 id;

/* Largest PCI device id we expect translation requests for */
u16 last_bdf;

/* Size of the device table */
u32 dev_table_size;

/* Size of the alias table */
u32 alias_table_size;

/* Size of the rlookup table */
u32 rlookup_table_size;

/*
* device table virtual address
*
* Pointer to the per PCI segment device table.
* It is indexed by the PCI device id or the HT unit id and contains
* information about the domain the device belongs to as well as the
* page table root pointer.
*/
struct dev_table_entry *dev_table;

/*
* The rlookup iommu table is used to find the IOMMU which is
* responsible for a specific device. It is indexed by the PCI
* device id.
*/
struct amd_iommu **rlookup_table;

/*
* This table is used to find the irq remapping table for a given
* device id quickly.
*/
struct irq_remap_table **irq_lookup_table;

/*
* Pointer to a device table which the content of old device table
* will be copied to. It's only be used in kdump kernel.
*/
struct dev_table_entry *old_dev_tbl_cpy;

/*
* The alias table is a driver specific data structure which contains the
* mappings of the PCI device ids to the actual requestor ids on the IOMMU.
* More than one device can share the same requestor id.
*/
u16 *alias_table;

/*
* A list of required unity mappings we find in ACPI. It is not locked
* because as runtime it is only read. It is created at ACPI table
* parsing time.
*/
struct list_head unity_map;
};

/*
* Structure where we save information about one hardware AMD IOMMU in the
* system.
Expand Down Expand Up @@ -576,7 +654,7 @@ struct amd_iommu {
u16 cap_ptr;

/* pci domain of this IOMMU */
u16 pci_seg;
struct amd_iommu_pci_seg *pci_seg;

/* start of exclusion range of that IOMMU */
u64 exclusion_start;
Expand Down Expand Up @@ -664,16 +742,16 @@ struct acpihid_map_entry {
struct list_head list;
u8 uid[ACPIHID_UID_LEN];
u8 hid[ACPIHID_HID_LEN];
u16 devid;
u16 root_devid;
u32 devid;
u32 root_devid;
bool cmd_line;
struct iommu_group *group;
};

struct devid_map {
struct list_head list;
u8 id;
u16 devid;
u32 devid;
bool cmd_line;
};

Expand All @@ -687,7 +765,7 @@ struct iommu_dev_data {
struct list_head list; /* For domain->dev_list */
struct llist_node dev_data_list; /* For global dev_data_list */
struct protection_domain *domain; /* Domain the device is bound to */
struct pci_dev *pdev;
struct device *dev;
u16 devid; /* PCI Device ID */
bool iommu_v2; /* Device can make use of IOMMUv2 */
struct {
Expand All @@ -707,6 +785,12 @@ extern struct list_head ioapic_map;
extern struct list_head hpet_map;
extern struct list_head acpihid_map;

/*
* List with all PCI segments in the system. This list is not locked because
* it is only written at driver initialization time
*/
extern struct list_head amd_iommu_pci_seg_list;

/*
* List with all IOMMUs in the system. This list is not locked because it is
* only written and read at driver initialization or suspend time
Expand Down Expand Up @@ -746,39 +830,13 @@ struct unity_map_entry {
int prot;
};

/*
* List of all unity mappings. It is not locked because as runtime it is only
* read. It is created at ACPI table parsing time.
*/
extern struct list_head amd_iommu_unity_map;

/*
* Data structures for device handling
*/

/*
* Device table used by hardware. Read and write accesses by software are
* locked with the amd_iommu_pd_table lock.
*/
extern struct dev_table_entry *amd_iommu_dev_table;

/*
* Alias table to find requestor ids to device ids. Not locked because only
* read on runtime.
*/
extern u16 *amd_iommu_alias_table;

/*
* Reverse lookup table to find the IOMMU which translates a specific device.
*/
extern struct amd_iommu **amd_iommu_rlookup_table;

/* size of the dma_ops aperture as power of 2 */
extern unsigned amd_iommu_aperture_order;

/* largest PCI device id we expect translation requests for */
extern u16 amd_iommu_last_bdf;

/* allocation bitmap for domain ids */
extern unsigned long *amd_iommu_pd_alloc_bitmap;

Expand Down Expand Up @@ -911,6 +969,7 @@ struct irq_2_irte {

struct amd_ir_data {
u32 cached_ga_tag;
struct amd_iommu *iommu;
struct irq_2_irte irq_2_irte;
struct msi_msg msi_entry;
void *entry; /* Pointer to union irte or struct irte_ga */
Expand All @@ -927,9 +986,9 @@ struct amd_ir_data {

struct amd_irte_ops {
void (*prepare)(void *, u32, bool, u8, u32, int);
void (*activate)(void *, u16, u16);
void (*deactivate)(void *, u16, u16);
void (*set_affinity)(void *, u16, u16, u8, u32);
void (*activate)(struct amd_iommu *iommu, void *, u16, u16);
void (*deactivate)(struct amd_iommu *iommu, void *, u16, u16);
void (*set_affinity)(struct amd_iommu *iommu, void *, u16, u16, u8, u32);
void *(*get)(struct irq_remap_table *, int);
void (*set_allocated)(struct irq_remap_table *, int);
bool (*is_allocated)(struct irq_remap_table *, int);
Expand Down
Loading