Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 270322
b: refs/heads/master
c: 086ac11
h: refs/heads/master
v: v3
  • Loading branch information
Joerg Roedel authored and Jesse Barnes committed Oct 14, 2011
1 parent 7f0c3e0 commit 389717e
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c320b976d7837c561ce4aa49dfe0a64f0e527ce4
refs/heads/master: 086ac11f6435c9dc2fe5025fc8ea3a1dbca273d6
13 changes: 13 additions & 0 deletions trunk/drivers/pci/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@ config PCI_PRI

If unsure, say N.

config PCI_PASID
bool "PCI PASID support"
depends on PCI
select PCI_ATS
help
Process Address Space Identifiers (PASIDs) can be used by PCI devices
to access more than one IO address space at the same time. To make
use of this feature an IOMMU is required which also supports PASIDs.
Select this option if you have such an IOMMU and want to compile the
driver for it into your kernel.

If unsure, say N.

config PCI_IOAPIC
bool
depends on PCI
Expand Down
113 changes: 113 additions & 0 deletions trunk/drivers/pci/ats.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* PCI Express I/O Virtualization (IOV) support.
* Address Translation Service 1.0
* Page Request Interface added by Joerg Roedel <joerg.roedel@amd.com>
* PASID support added by Joerg Roedel <joerg.roedel@amd.com>
*/

#include <linux/pci-ats.h>
Expand Down Expand Up @@ -323,3 +324,115 @@ int pci_pri_status(struct pci_dev *pdev)
}
EXPORT_SYMBOL_GPL(pci_pri_status);
#endif /* CONFIG_PCI_PRI */

#ifdef CONFIG_PCI_PASID
/**
* pci_enable_pasid - Enable the PASID capability
* @pdev: PCI device structure
* @features: Features to enable
*
* Returns 0 on success, negative value on error. This function checks
* whether the features are actually supported by the device and returns
* an error if not.
*/
int pci_enable_pasid(struct pci_dev *pdev, int features)
{
u16 control, supported;
int pos;

pos = pci_find_ext_capability(pdev, PCI_PASID_CAP);
if (!pos)
return -EINVAL;

pci_read_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, &control);
pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF, &supported);

if (!(supported & PCI_PASID_ENABLE))
return -EINVAL;

supported &= PCI_PASID_EXEC | PCI_PASID_PRIV;

/* User wants to enable anything unsupported? */
if ((supported & features) != features)
return -EINVAL;

control = PCI_PASID_ENABLE | features;

pci_write_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, control);

return 0;
}
EXPORT_SYMBOL_GPL(pci_enable_pasid);

/**
* pci_disable_pasid - Disable the PASID capability
* @pdev: PCI device structure
*
*/
void pci_disable_pasid(struct pci_dev *pdev)
{
u16 control = 0;
int pos;

pos = pci_find_ext_capability(pdev, PCI_PASID_CAP);
if (!pos)
return;

pci_write_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, control);
}
EXPORT_SYMBOL_GPL(pci_disable_pasid);

/**
* pci_pasid_features - Check which PASID features are supported
* @pdev: PCI device structure
*
* Returns a negative value when no PASI capability is present.
* Otherwise is returns a bitmask with supported features. Current
* features reported are:
* PCI_PASID_ENABLE - PASID capability can be enabled
* PCI_PASID_EXEC - Execute permission supported
* PCI_PASID_PRIV - Priviledged mode supported
*/
int pci_pasid_features(struct pci_dev *pdev)
{
u16 supported;
int pos;

pos = pci_find_ext_capability(pdev, PCI_PASID_CAP);
if (!pos)
return -EINVAL;

pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF, &supported);

supported &= PCI_PASID_ENABLE | PCI_PASID_EXEC | PCI_PASID_PRIV;

return supported;
}
EXPORT_SYMBOL_GPL(pci_pasid_features);

#define PASID_NUMBER_SHIFT 8
#define PASID_NUMBER_MASK (0x1f << PASID_NUMBER_SHIFT)
/**
* pci_max_pasid - Get maximum number of PASIDs supported by device
* @pdev: PCI device structure
*
* Returns negative value when PASID capability is not present.
* Otherwise it returns the numer of supported PASIDs.
*/
int pci_max_pasids(struct pci_dev *pdev)
{
u16 supported;
int pos;

pos = pci_find_ext_capability(pdev, PCI_PASID_CAP);
if (!pos)
return -EINVAL;

pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF, &supported);

supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT;

return (1 << supported);
}
EXPORT_SYMBOL_GPL(pci_max_pasids);
#endif /* CONFIG_PCI_PASID */
31 changes: 31 additions & 0 deletions trunk/include/linux/pci-ats.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,35 @@ static inline int pci_pri_status(struct pci_dev *pdev)
}
#endif /* CONFIG_PCI_PRI */

#ifdef CONFIG_PCI_PASID

extern int pci_enable_pasid(struct pci_dev *pdev, int features);
extern void pci_disable_pasid(struct pci_dev *pdev);
extern int pci_pasid_features(struct pci_dev *pdev);
extern int pci_max_pasids(struct pci_dev *pdev);

#else /* CONFIG_PCI_PASID */

static inline int pci_enable_pasid(struct pci_dev *pdev, int features)
{
return -EINVAL;
}

static inline void pci_disable_pasid(struct pci_dev *pdev)
{
}

static inline int pci_pasid_features(struct pci_dev *pdev)
{
return -EINVAL;
}

static inline int pci_max_pasids(struct pci_dev *pdev)
{
return -EINVAL;
}

#endif /* CONFIG_PCI_PASID */


#endif /* LINUX_PCI_ATS_H*/
8 changes: 8 additions & 0 deletions trunk/include/linux/pci_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,14 @@
#define PCI_PRI_MAX_REQ_OFF 0x08 /* Cap offset for max reqs supported */
#define PCI_PRI_ALLOC_REQ_OFF 0x0c /* Cap offset for max reqs allowed */

/* PASID capability */
#define PCI_PASID_CAP 0x1b /* PASID capability ID */
#define PCI_PASID_CAP_OFF 0x04 /* PASID feature register */
#define PCI_PASID_CONTROL_OFF 0x06 /* PASID control register */
#define PCI_PASID_ENABLE 0x01 /* Enable/Supported bit */
#define PCI_PASID_EXEC 0x02 /* Exec permissions Enable/Supported */
#define PCI_PASID_PRIV 0x04 /* Priviledge Mode Enable/Support */

/* Single Root I/O Virtualization */
#define PCI_SRIOV_CAP 0x04 /* SR-IOV Capabilities */
#define PCI_SRIOV_CAP_VFM 0x01 /* VF Migration Capable */
Expand Down

0 comments on commit 389717e

Please sign in to comment.