mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
iommu/amd: Fix illegal device-id access in IOMMU debugfs
In the current AMD IOMMU debugFS, when multiple processes use the IOMMU debugFS process simultaneously, illegal access issues can occur in the following execution flow: 1. CPU1: Sets a valid sbdf via devid_write, then checks the sbdf's validity in execution flows such as devid_show, iommu_devtbl_show, and iommu_irqtbl_show. 2. CPU2: Sets an invalid sbdf via devid_write, at which point the sbdf value is -1. 3. CPU1: accesses the IOMMU device table, IRQ table, based on the invalid SBDF value of -1, resulting in illegal access. This is especially problematic in monitoring scripts, where multiple scripts may access debugFS simultaneously, and some scripts may unexpectedly set invalid values, which triggers illegal access in debugfs. This patch modifies the execution flow of devid_show, iommu_devtbl_show, and iommu_irqtbl_show to ensure that these processes determine the validity and access based on the same device-id, thus guaranteeing correctness and robustness. Signed-off-by: Guanghui Feng <guanghuifeng@linux.alibaba.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
1e0c8d6b69
commit
e4172c5b53
|
|
@ -197,10 +197,11 @@ static ssize_t devid_write(struct file *filp, const char __user *ubuf,
|
|||
static int devid_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
u16 devid;
|
||||
int sbdf_shadow = sbdf;
|
||||
|
||||
if (sbdf >= 0) {
|
||||
devid = PCI_SBDF_TO_DEVID(sbdf);
|
||||
seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf),
|
||||
if (sbdf_shadow >= 0) {
|
||||
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
|
||||
seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf_shadow),
|
||||
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid));
|
||||
} else
|
||||
seq_puts(m, "No or Invalid input provided\n");
|
||||
|
|
@ -237,13 +238,14 @@ static int iommu_devtbl_show(struct seq_file *m, void *unused)
|
|||
{
|
||||
struct amd_iommu_pci_seg *pci_seg;
|
||||
u16 seg, devid;
|
||||
int sbdf_shadow = sbdf;
|
||||
|
||||
if (sbdf < 0) {
|
||||
if (sbdf_shadow < 0) {
|
||||
seq_puts(m, "Enter a valid device ID to 'devid' file\n");
|
||||
return 0;
|
||||
}
|
||||
seg = PCI_SBDF_TO_SEGID(sbdf);
|
||||
devid = PCI_SBDF_TO_DEVID(sbdf);
|
||||
seg = PCI_SBDF_TO_SEGID(sbdf_shadow);
|
||||
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
|
||||
|
||||
for_each_pci_segment(pci_seg) {
|
||||
if (pci_seg->id != seg)
|
||||
|
|
@ -336,19 +338,20 @@ static int iommu_irqtbl_show(struct seq_file *m, void *unused)
|
|||
{
|
||||
struct amd_iommu_pci_seg *pci_seg;
|
||||
u16 devid, seg;
|
||||
int sbdf_shadow = sbdf;
|
||||
|
||||
if (!irq_remapping_enabled) {
|
||||
seq_puts(m, "Interrupt remapping is disabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sbdf < 0) {
|
||||
if (sbdf_shadow < 0) {
|
||||
seq_puts(m, "Enter a valid device ID to 'devid' file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
seg = PCI_SBDF_TO_SEGID(sbdf);
|
||||
devid = PCI_SBDF_TO_DEVID(sbdf);
|
||||
seg = PCI_SBDF_TO_SEGID(sbdf_shadow);
|
||||
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
|
||||
|
||||
for_each_pci_segment(pci_seg) {
|
||||
if (pci_seg->id != seg)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user