cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dmar.h (8247B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (c) 2006, Intel Corporation.
      4 *
      5 * Copyright (C) Ashok Raj <ashok.raj@intel.com>
      6 * Copyright (C) Shaohua Li <shaohua.li@intel.com>
      7 */
      8
      9#ifndef __DMAR_H__
     10#define __DMAR_H__
     11
     12#include <linux/acpi.h>
     13#include <linux/types.h>
     14#include <linux/msi.h>
     15#include <linux/irqreturn.h>
     16#include <linux/rwsem.h>
     17#include <linux/rculist.h>
     18
     19struct acpi_dmar_header;
     20
     21#ifdef	CONFIG_X86
     22# define	DMAR_UNITS_SUPPORTED	MAX_IO_APICS
     23#else
     24# define	DMAR_UNITS_SUPPORTED	64
     25#endif
     26
     27/* DMAR Flags */
     28#define DMAR_INTR_REMAP		0x1
     29#define DMAR_X2APIC_OPT_OUT	0x2
     30#define DMAR_PLATFORM_OPT_IN	0x4
     31
     32struct intel_iommu;
     33
     34struct dmar_dev_scope {
     35	struct device __rcu *dev;
     36	u8 bus;
     37	u8 devfn;
     38};
     39
     40#ifdef CONFIG_DMAR_TABLE
     41extern struct acpi_table_header *dmar_tbl;
     42struct dmar_drhd_unit {
     43	struct list_head list;		/* list of drhd units	*/
     44	struct  acpi_dmar_header *hdr;	/* ACPI header		*/
     45	u64	reg_base_addr;		/* register base address*/
     46	struct	dmar_dev_scope *devices;/* target device array	*/
     47	int	devices_cnt;		/* target device count	*/
     48	u16	segment;		/* PCI domain		*/
     49	u8	ignored:1; 		/* ignore drhd		*/
     50	u8	include_all:1;
     51	u8	gfx_dedicated:1;	/* graphic dedicated	*/
     52	struct intel_iommu *iommu;
     53};
     54
     55struct dmar_pci_path {
     56	u8 bus;
     57	u8 device;
     58	u8 function;
     59};
     60
     61struct dmar_pci_notify_info {
     62	struct pci_dev			*dev;
     63	unsigned long			event;
     64	int				bus;
     65	u16				seg;
     66	u16				level;
     67	struct dmar_pci_path		path[];
     68}  __attribute__((packed));
     69
     70extern struct rw_semaphore dmar_global_lock;
     71extern struct list_head dmar_drhd_units;
     72
     73#define for_each_drhd_unit(drhd)					\
     74	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list,		\
     75				dmar_rcu_check())
     76
     77#define for_each_active_drhd_unit(drhd)					\
     78	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list,		\
     79				dmar_rcu_check())			\
     80		if (drhd->ignored) {} else
     81
     82#define for_each_active_iommu(i, drhd)					\
     83	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list,		\
     84				dmar_rcu_check())			\
     85		if (i=drhd->iommu, drhd->ignored) {} else
     86
     87#define for_each_iommu(i, drhd)						\
     88	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list,		\
     89				dmar_rcu_check())			\
     90		if (i=drhd->iommu, 0) {} else 
     91
     92static inline bool dmar_rcu_check(void)
     93{
     94	return rwsem_is_locked(&dmar_global_lock) ||
     95	       system_state == SYSTEM_BOOTING;
     96}
     97
     98#define	dmar_rcu_dereference(p)	rcu_dereference_check((p), dmar_rcu_check())
     99
    100#define for_each_dev_scope(devs, cnt, i, tmp)				\
    101	for ((i) = 0; ((tmp) = (i) < (cnt) ?				\
    102	    dmar_rcu_dereference((devs)[(i)].dev) : NULL, (i) < (cnt)); \
    103	    (i)++)
    104
    105#define for_each_active_dev_scope(devs, cnt, i, tmp)			\
    106	for_each_dev_scope((devs), (cnt), (i), (tmp))			\
    107		if (!(tmp)) { continue; } else
    108
    109extern int dmar_table_init(void);
    110extern int dmar_dev_scope_init(void);
    111extern void dmar_register_bus_notifier(void);
    112extern int dmar_parse_dev_scope(void *start, void *end, int *cnt,
    113				struct dmar_dev_scope **devices, u16 segment);
    114extern void *dmar_alloc_dev_scope(void *start, void *end, int *cnt);
    115extern void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt);
    116extern int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
    117				 void *start, void*end, u16 segment,
    118				 struct dmar_dev_scope *devices,
    119				 int devices_cnt);
    120extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info,
    121				 u16 segment, struct dmar_dev_scope *devices,
    122				 int count);
    123/* Intel IOMMU detection */
    124void detect_intel_iommu(void);
    125extern int enable_drhd_fault_handling(void);
    126extern int dmar_device_add(acpi_handle handle);
    127extern int dmar_device_remove(acpi_handle handle);
    128
    129static inline int dmar_res_noop(struct acpi_dmar_header *hdr, void *arg)
    130{
    131	return 0;
    132}
    133
    134#ifdef CONFIG_DMAR_DEBUG
    135void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
    136			  unsigned long long addr, u32 pasid);
    137#else
    138static inline void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
    139					unsigned long long addr, u32 pasid) {}
    140#endif
    141
    142#ifdef CONFIG_INTEL_IOMMU
    143extern int iommu_detected, no_iommu;
    144extern int intel_iommu_init(void);
    145extern void intel_iommu_shutdown(void);
    146extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg);
    147extern int dmar_parse_one_atsr(struct acpi_dmar_header *header, void *arg);
    148extern int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg);
    149extern int dmar_parse_one_satc(struct acpi_dmar_header *hdr, void *arg);
    150extern int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg);
    151extern int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert);
    152extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info);
    153#else /* !CONFIG_INTEL_IOMMU: */
    154static inline int intel_iommu_init(void) { return -ENODEV; }
    155static inline void intel_iommu_shutdown(void) { }
    156
    157#define	dmar_parse_one_rmrr		dmar_res_noop
    158#define	dmar_parse_one_atsr		dmar_res_noop
    159#define	dmar_check_one_atsr		dmar_res_noop
    160#define	dmar_release_one_atsr		dmar_res_noop
    161#define	dmar_parse_one_satc		dmar_res_noop
    162
    163static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
    164{
    165	return 0;
    166}
    167
    168static inline int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
    169{
    170	return 0;
    171}
    172#endif /* CONFIG_INTEL_IOMMU */
    173
    174#ifdef CONFIG_IRQ_REMAP
    175extern int dmar_ir_hotplug(struct dmar_drhd_unit *dmaru, bool insert);
    176#else  /* CONFIG_IRQ_REMAP */
    177static inline int dmar_ir_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
    178{ return 0; }
    179#endif /* CONFIG_IRQ_REMAP */
    180
    181extern bool dmar_platform_optin(void);
    182
    183#else /* CONFIG_DMAR_TABLE */
    184
    185static inline int dmar_device_add(void *handle)
    186{
    187	return 0;
    188}
    189
    190static inline int dmar_device_remove(void *handle)
    191{
    192	return 0;
    193}
    194
    195static inline bool dmar_platform_optin(void)
    196{
    197	return false;
    198}
    199
    200static inline void detect_intel_iommu(void)
    201{
    202}
    203
    204#endif /* CONFIG_DMAR_TABLE */
    205
    206struct irte {
    207	union {
    208		/* Shared between remapped and posted mode*/
    209		struct {
    210			__u64	present		: 1,  /*  0      */
    211				fpd		: 1,  /*  1      */
    212				__res0		: 6,  /*  2 -  6 */
    213				avail		: 4,  /*  8 - 11 */
    214				__res1		: 3,  /* 12 - 14 */
    215				pst		: 1,  /* 15      */
    216				vector		: 8,  /* 16 - 23 */
    217				__res2		: 40; /* 24 - 63 */
    218		};
    219
    220		/* Remapped mode */
    221		struct {
    222			__u64	r_present	: 1,  /*  0      */
    223				r_fpd		: 1,  /*  1      */
    224				dst_mode	: 1,  /*  2      */
    225				redir_hint	: 1,  /*  3      */
    226				trigger_mode	: 1,  /*  4      */
    227				dlvry_mode	: 3,  /*  5 -  7 */
    228				r_avail		: 4,  /*  8 - 11 */
    229				r_res0		: 4,  /* 12 - 15 */
    230				r_vector	: 8,  /* 16 - 23 */
    231				r_res1		: 8,  /* 24 - 31 */
    232				dest_id		: 32; /* 32 - 63 */
    233		};
    234
    235		/* Posted mode */
    236		struct {
    237			__u64	p_present	: 1,  /*  0      */
    238				p_fpd		: 1,  /*  1      */
    239				p_res0		: 6,  /*  2 -  7 */
    240				p_avail		: 4,  /*  8 - 11 */
    241				p_res1		: 2,  /* 12 - 13 */
    242				p_urgent	: 1,  /* 14      */
    243				p_pst		: 1,  /* 15      */
    244				p_vector	: 8,  /* 16 - 23 */
    245				p_res2		: 14, /* 24 - 37 */
    246				pda_l		: 26; /* 38 - 63 */
    247		};
    248		__u64 low;
    249	};
    250
    251	union {
    252		/* Shared between remapped and posted mode*/
    253		struct {
    254			__u64	sid		: 16,  /* 64 - 79  */
    255				sq		: 2,   /* 80 - 81  */
    256				svt		: 2,   /* 82 - 83  */
    257				__res3		: 44;  /* 84 - 127 */
    258		};
    259
    260		/* Posted mode*/
    261		struct {
    262			__u64	p_sid		: 16,  /* 64 - 79  */
    263				p_sq		: 2,   /* 80 - 81  */
    264				p_svt		: 2,   /* 82 - 83  */
    265				p_res3		: 12,  /* 84 - 95  */
    266				pda_h		: 32;  /* 96 - 127 */
    267		};
    268		__u64 high;
    269	};
    270};
    271
    272static inline void dmar_copy_shared_irte(struct irte *dst, struct irte *src)
    273{
    274	dst->present	= src->present;
    275	dst->fpd	= src->fpd;
    276	dst->avail	= src->avail;
    277	dst->pst	= src->pst;
    278	dst->vector	= src->vector;
    279	dst->sid	= src->sid;
    280	dst->sq		= src->sq;
    281	dst->svt	= src->svt;
    282}
    283
    284#define PDA_LOW_BIT    26
    285#define PDA_HIGH_BIT   32
    286
    287/* Can't use the common MSI interrupt functions
    288 * since DMAR is not a pci device
    289 */
    290struct irq_data;
    291extern void dmar_msi_unmask(struct irq_data *data);
    292extern void dmar_msi_mask(struct irq_data *data);
    293extern void dmar_msi_read(int irq, struct msi_msg *msg);
    294extern void dmar_msi_write(int irq, struct msi_msg *msg);
    295extern int dmar_set_interrupt(struct intel_iommu *iommu);
    296extern irqreturn_t dmar_fault(int irq, void *dev_id);
    297extern int dmar_alloc_hwirq(int id, int node, void *arg);
    298extern void dmar_free_hwirq(int irq);
    299
    300#endif /* __DMAR_H__ */