I am using kernel 5.4.60 at the moment with an override ACS patch which I used to try to bypass the navi reset bug but it still happens. I will attach the patch I used to the bottom.
Ive had to deal with this (5700xt, r9 270x, both using amdgpu) but since both your vendor and product ids are the same you're going to have to bind by the group / pci ID because both of those should be different. You want to put kernel command line arguments to stop the boot GPU from attaching to anything. in
/etc/default/grub use
Code: Select all
GRUB_CMDLINE_LINUX_DEFAULT="video=efifb:off iommu=pt amd_iommu=on kvm_amd=on pcie_acs_override=downstream,multifunction quiet default_hugepagesz=1G hugepagesz=1G hugepages=16"
video=efifb:off iommu=pt amd_iommu=on kvm_amd=on being the important switches,
obviously the hugepages stuff you don't have to do, that's just optimization, and
you don't have to use the pcie_acs_override if you have great grouping, I use it to separate a couple IOMMU groups on my b450-f so that I can pass through more items to my VM.
(Remember to
mount /boot; grub-mkconfig -o /boot/grub/grub.cfg after editing your default grub config, and also that your user is in the kvm, qemu, libvirt groups)
Then, you need to tell xorg which card to use for the host and just for ease of use I've set xdm to startup on boot, you can use whatever display manager.. but on gentoo w/ openrc
and my
~/.xinitrc is setup for kde/plasma/X11
Code: Select all
#!/bin/sh
exec dbus-launch --exit-with-session startplasma-x11
my
/etc/X11/xorg.conf:
Code: Select all
Section "Device"
Identifier "amdgpu"
Driver "amdgpu"
BusId "PCI:10:0:0"
EndSection
#pci bus 0x000a cardnum 0x00 function 0x00: vendor 0x1002 device 0x6810
# Advanced Micro Devices, Inc. [AMD/ATI] Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X]
#For multiple graphics cards specify the BusID in the form PCI:bus:device:function provided by scanpci.
That's me telling Xorg to use my r9 270x for host graphics, passing through the 5700xt to vfio-pci, you can see below that the r9 270x is 0a:00.0 and 0a:00.1 which is hex for 10 so I put 10 in the PCI part of the busID in the xorg.conf
the busID is the important part, when I do iommu.sh (which is just a script you already found I believe) i get this:
Code: Select all
** condensed for the important parts **
IOMMU Group 15 01:00.0 Non-Volatile memory controller [0108]: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201] (rev 03)
IOMMU Group 17 02:00.1 SATA controller [0106]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset SATA Controller [1022:43c8] (rev 01)
IOMMU Group 29 09:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] [1002:731f] (rev c1)
IOMMU Group 30 09:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 HDMI Audio [1002:ab38]
IOMMU Group 31 0a:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X] [1002:6810]
IOMMU Group 32 0a:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Oland/Hainan/Cape Verde/Pitcairn HDMI Audio [Radeon HD 7000 Series] [1002:aab0]
IOMMU Group 33 0b:00.0 Non-Volatile memory controller [0108]: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201] (rev 03)
IOMMU Group 39 0d:00.3 Audio device [0403]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) HD Audio Controller [1022:1457]
We're looking at the number after the IOMMU group, the pci ID and the vendor / product ID at the end.
this is my
/etc/modprobe.d/amdgpu.conf
Code: Select all
softdep amdgpu pre: vfio-pci
softdep amd_iommu_v2 pre: vfio-pci
telling those drivers not to load until after vfio-pci (because both cards use amdgpu so we want to bind the passthrough card before loading the graphics of the host)
my
/etc/modprobe.d/vfio-pci.conf (you could probably combine these two .conf files but I keep it separate for each module)
Code: Select all
options vfio-pci ids=1002:731f,1002:ab38,1cc1:8201,1022:43c8
#,1cc1:8201 nvme
#,1022:43c8 sata
1002:731f,1002:ab38,
now those are the vendor/product ids of my 5700xt video and audio, (you have to pass through video and audio together.. but you don't have to passthrough the downstream/upstream pcie ports that come with the card) then one of my nvme drives and my sata ahci controller.
and my
/etc/conf.d/modules tells the system which modules to load on boot. it's important to have your kernel configured for these options to loadable modules.. I actually accidentally put the vfio and the amd_iommu *in* the kernel rather than as a module so it gripes at me that they are already present when I try to load them but I leave it there cause it works lol
Code: Select all
modules="vfio vfio-pci vfio_iommu_type1 vfio_virqfd amd_iommu_v2 amdgpu snd_hda_intel"
I didn't run into error 43 but I did run into the navi reset bug, so I have downloaded my own card's Navi 10.rom on a windows install with gpu-z and the one from
https://www.techpowerup.com/vgabios/212 ... 192-190616 as I have a sapphire pulse, but you can find your own. that I pass through to my windows 10 VM (but I don't think it works for me as I still sometimes run into the reset bug after shutting down my VM, and have to either suspend system to RAM to fix it but usually I have to fully reboot) but my VM works great and has the latest AMD drivers and everything.
So with this setup, after I boot up the host and login I run this script in order to unbind and rebind one nvme drive, my sata controller, and HD audio controller: It's simply a wrapper around a second script that provides all my IDs to passthrough to vfio-pci, you can compare the IDs with the above and see where to get the groups and vendor and product.
you don't need to do this if you don't want to pass through anything other than your video card. you should probably first just set it up with the virtio drivers and then worry about passthrough of other stuff after you've got it working, unless you want to, then go ahead
Code: Select all
#!/bin/sh
#first nvme drive (both nvme drives are the same pci ids so i'm running into your problem with these instead but I got it working like this
/usr/sbin/vfio-pci-bind 0000:01:00.0 1cc1:8201
/usr/sbin/vfio-pci-bind 0000:02:00.1 1022:43c8 #sata controller
/usr/sbin/vfio-pci-bind 0000:0d:00.3 1022:1457 #hd audio controller for the mobo
and this script I found I have saved in
/usr/sbin/vfio-pci-bind and I just use that wrapper script to call this will the correct IDs:
you could silence the output of this script and make it run automatically if you wanted to, but I left it like this because I wanted to be able to access these devices in the host &/or the guest
Code: Select all
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
#
# =============================================================================
#
# The MIT License (MIT)
#
# Copyright (c) 2015 Andre Richter
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# =============================================================================
#
# Author(s):
# Andre Richter, <andre.o.richter @t gmail_com>
#
# =============================================================================
#
# This script takes one or two parameters in any order:
# <Vendor:Device> i.e. vvvv:dddd
# <Domain:Bus:Device.Function> i.e. dddd:bb:dd.f
# and then:
#
# (1) If both <Vendor:Device> and <Domain:Bus:Device.Function> were provided,
# validate that the requested <Vendor:Device> exists at <Domain:Bus:Device.Function>
#
# If only <Vendor:Device> was provided, determine the current
# <Domain:Bus:Device.Function> for that device.
#
# If only <Domain:Bus:Device.Function> was provided, use it.
#
# (2) Unbinds all devices that are in the same iommu group as the supplied
# device from their current driver (except PCIe bridges).
#
# (3) Binds to vfio-pci:
# (3.1) The supplied device.
# (3.2) All devices that are in the same iommu group.
#
# (4) Transfers ownership of the respective iommu group inside /dev/vfio
# to $SUDO_USER
#
# Script must be executed via sudo
BDF_REGEX="^[[:xdigit:]]{2}:[[:xdigit:]]{2}.[[:xdigit:]]$"
DBDF_REGEX="^[[:xdigit:]]{4}:[[:xdigit:]]{2}:[[:xdigit:]]{2}.[[:xdigit:]]$"
VD_REGEX="^[[:xdigit:]]{4}:[[:xdigit:]]{4}$"
if [[ $EUID -ne 0 ]]; then
echo "Error: This script must be run as root" 1>&2
exit 1
fi
if [[ -z "$@" ]]; then
echo "Error: Please provide Domain:Bus:Device.Function (dddd:bb:dd.f) and/or Version:Device (vvvv:dddd)" 1>&2
exit 1
fi
unset VD BDF
for arg in "$@"
do
if [[ $arg =~ $VD_REGEX ]]; then
VD=$arg
elif [[ $arg =~ $DBDF_REGEX ]]; then
BDF=$arg
elif [[ $arg =~ $BDF_REGEX ]]; then
BDF="0000:${arg}"
echo "Warning: You did not supply a PCI domain, assuming ${BDF}" 1>&2
else
echo "Error: Please provide Version:Device (vvvv:dddd) and/or Domain:Bus:Device.Function (dddd:bb:dd.f)" 1>&2
exit 1
fi
done
# BDF not provided, find BDF for Vendor:Device
if [[ -z $BDF ]]; then
COUNT=$(lspci -n -d ${VD} 2>/dev/null | wc -l)
if [[ $COUNT -eq 0 ]]; then
echo "Error: Vendor:Device ${VD} not found" 1>&2
exit 1
elif [[ $COUNT -gt 1 ]]; then
echo "Error: Multiple results for Vendor:Device ${VD}, please provide Domain:Bus:Device.Function (dddd:bb:dd.f) as well" 1>&2
exit 1
fi
BDF=$(lspci -n -d ${VD} 2>/dev/null | cut -d " " -f1)
if [[ $BDF =~ $BDF_REGEX ]]; then
BDF="0000:${BDF}"
elif [[ ! $BDF =~ $DBDF_REGEX ]]; then
echo "Error: Unable to find Domain:Bus:Device.Function for Vendor:Device ${VD}" 1>&2
exit 1
fi
fi
TARGET_DEV_SYSFS_PATH="/sys/bus/pci/devices/$BDF"
if [[ ! -d $TARGET_DEV_SYSFS_PATH ]]; then
echo "Error: Device ${BDF} does not exist, unable to bind device" 1>&2
exit 1
fi
if [[ ! -d "$TARGET_DEV_SYSFS_PATH/iommu/" ]]; then
echo "Error: No signs of an IOMMU. Check your hardware and/or linux cmdline parameters. Use intel_iommu=on or iommu=pt iommu=1" 1>&2
exit 1
fi
# validate that the correct Vendor:Device was found for this BDF
if [[ ! -z $VD ]]; then
if [[ $(lspci -n -s ${BDF} -d ${VD} 2>/dev/null | wc -l) -eq 0 ]]; then
echo "Error: Vendor:Device ${VD} not found at ${BDF}, unable to bind device" 1>&2
exit 1
else
echo "Vendor:Device ${VD} found at ${BDF}"
fi
else
echo "Warning: You did not specify a Vendor:Device (vvvv:dddd), unable to validate ${BDF}" 1>&2
fi
unset dev_sysfs_paths
for dsp in $TARGET_DEV_SYSFS_PATH/iommu_group/devices/*
do
dbdf=${dsp##*/}
if [[ $(( 0x$(setpci -s $dbdf 0e.b) & 0x7f )) -eq 0 ]]; then
dev_sysfs_paths+=( $dsp )
fi
done
printf "\nIOMMU group members (sans bridges):\n"
for dsp in ${dev_sysfs_paths[@]}; do echo $dsp; done
modprobe -i vfio-pci
if [[ $? -ne 0 ]]; then
echo "Error: Error probing vfio-pci" 1>&2
exit 1
fi
printf "\nBinding...\n"
for dsp in ${dev_sysfs_paths[@]}
do
dpath="$dsp/driver"
dbdf=${dsp##*/}
echo "vfio-pci" > "$dsp/driver_override"
if [[ -d $dpath ]]; then
curr_driver=$(readlink $dpath)
curr_driver=${curr_driver##*/}
if [[ "$curr_driver" == "vfio-pci" ]]; then
echo "$dbdf already bound to vfio-pci"
continue
else
echo $dbdf > "$dpath/unbind"
echo "Unbound $dbdf from $curr_driver"
fi
fi
echo $dbdf > /sys/bus/pci/drivers_probe
done
printf "\n"
# Adjust group ownership
iommu_group=$(readlink $TARGET_DEV_SYSFS_PATH/iommu_group)
iommu_group=${iommu_group##*/}
chown $SUDO_UID:$SUDO_GID "/dev/vfio/$iommu_group"
if [[ $? -ne 0 ]]; then
echo "Error: unable to adjust group ownership of /dev/vfio/${iommu_group}" 1>&2
exit 1
fi
printf "success...\n\n"
echo "Device ${VD} at ${BDF} bound to vfio-pci"
echo 'Devices listed in /sys/bus/pci/drivers/vfio-pci:'
ls -l /sys/bus/pci/drivers/vfio-pci | egrep [[:xdigit:]]{4}:
printf "\nls -l /dev/vfio/\n"
ls -l /dev/vfio/
just for reference here is my lspci -nnk *before* i run that script:
Code: Select all
**condensed to the important parts**
01:00.0 Non-Volatile memory controller [0108]: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201] (rev 03)
Subsystem: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201]
Kernel driver in use: nvme
02:00.1 SATA controller [0106]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset SATA Controller [1022:43c8] (rev 01)
Subsystem: ASMedia Technology Inc. 400 Series Chipset SATA Controller [1b21:1062]
Kernel driver in use: ahci
09:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] [1002:731f] (rev c1)
Subsystem: Sapphire Technology Limited Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] [1da2:e411]
Kernel driver in use: vfio-pci
09:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 HDMI Audio [1002:ab38]
Subsystem: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 HDMI Audio [1002:ab38]
Kernel driver in use: vfio-pci
0a:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X] [1002:6810]
Subsystem: Gigabyte Technology Co., Ltd Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X] [1458:227d]
Kernel driver in use: amdgpu
0a:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Oland/Hainan/Cape Verde/Pitcairn HDMI Audio [Radeon HD 7000 Series] [1002:aab0]
Subsystem: Gigabyte Technology Co., Ltd Oland/Hainan/Cape Verde/Pitcairn HDMI Audio [Radeon HD 7000 Series] [1458:aab0]
Kernel driver in use: snd_hda_intel
0b:00.0 Non-Volatile memory controller [0108]: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201] (rev 03)
Subsystem: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201]
Kernel driver in use: nvme
0d:00.3 Audio device [0403]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) HD Audio Controller [1022:1457]
Subsystem: ASUSTeK Computer Inc. Family 17h (Models 00h-0fh) HD Audio Controller [1043:8723]
Kernel driver in use: snd_hda_intel
You can see that so far just the 5700xt video and audio are attached to vfio-pci but after I run the script:
Code: Select all
** condensed to the important parts **
01:00.0 Non-Volatile memory controller [0108]: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201] (rev 03)
Subsystem: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201]
Kernel driver in use: vfio-pci
02:00.1 SATA controller [0106]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset SATA Controller [1022:43c8] (rev 01)
Subsystem: ASMedia Technology Inc. 400 Series Chipset SATA Controller [1b21:1062]
Kernel driver in use: vfio-pci
09:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] [1002:731f] (rev c1)
Subsystem: Sapphire Technology Limited Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] [1da2:e411]
Kernel driver in use: vfio-pci
09:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 HDMI Audio [1002:ab38]
Subsystem: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 HDMI Audio [1002:ab38]
Kernel driver in use: vfio-pci
0a:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X] [1002:6810]
Subsystem: Gigabyte Technology Co., Ltd Curacao XT / Trinidad XT [Radeon R7 370 / R9 270X/370X] [1458:227d]
Kernel driver in use: amdgpu
0a:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Oland/Hainan/Cape Verde/Pitcairn HDMI Audio [Radeon HD 7000 Series] [1002:aab0]
Subsystem: Gigabyte Technology Co., Ltd Oland/Hainan/Cape Verde/Pitcairn HDMI Audio [Radeon HD 7000 Series] [1458:aab0]
Kernel driver in use: snd_hda_intel
0b:00.0 Non-Volatile memory controller [0108]: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201] (rev 03)
Subsystem: ADATA Technology Co., Ltd. XPG SX8200 Pro PCIe Gen3x4 M.2 2280 Solid State Drive [1cc1:8201]
Kernel driver in use: nvme
0d:00.3 Audio device [0403]: Advanced Micro Devices, Inc. [AMD] Family 17h (Models 00h-0fh) HD Audio Controller [1022:1457]
Subsystem: ASUSTeK Computer Inc. Family 17h (Models 00h-0fh) HD Audio Controller [1043:8723]
Kernel driver in use: vfio-pci
Now you can see that one of the nvmes, the HD audio, and the sata controller are attached to vfio-pci. The only thing left to do is configure qemu/kvm/virt-manager by adding these devices as PCI devices. You should follow one of the guides that tells you to install windows (assuming thats what youre doing) with the windows CD .iso and the red hat virtio drivers .iso. I had to first set up my drives one as SATA and one as SCSI, install windows, tell it about the drivers, or reboot into safe mode after install so that it will accept the SCSI drivers & reboot back to normal before you can use them. Then you can set them to virtio and/or do pci passthrough nvme / sata controllers /drives like i'm doing.
I've noticed that I can just pass through an nvme drive that already had windows installed on it and it will work but it will be a little buggy, it's better when you install a fresh copy of windows onto a drive and use the virtio drivers, hugepages, cpu pinning ,whatever you want to do.
I also have two monitors, both have multiple inputs so I have both of them hooked up to both GPUs and I can select between inputs to see the VM or the host at the same time. I also pass through a USB mouse and keyboard.
Tried to be as clear as I could, if you have any questions I can try to answer them
-----
override patch: place this in
/etc/portage/patches/sys-kernel/gentoo-sources-5.4.60/override_acs_caps.patch adjust for your kernel source / version.. i would definitely only use this if necessary. you might not need it on your board.
Code: Select all
--- a/drivers/pci/quirks.c 2020-05-12 20:48:40.153152132 +0300
+++ b/drivers/pci/quirks.c 2020-05-13 15:59:18.477619314 +0300
@@ -4695,6 +4695,111 @@
PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
}
+/*
+* PCIe ACS Override
+*/
+static bool acs_on_downstream;
+static bool acs_on_multifunction;
+
+#define NUM_ACS_IDS 16
+struct acs_on_id {
+ unsigned short vendor;
+ unsigned short device;
+};
+static struct acs_on_id acs_on_ids[NUM_ACS_IDS];
+static u8 max_acs_id;
+
+static __init int pcie_acs_override_setup(char *p)
+{
+ if (!p)
+ return -EINVAL;
+
+ while (*p) {
+ if (!strncmp(p, "downstream", 10))
+ acs_on_downstream = true;
+ if (!strncmp(p, "multifunction", 13))
+ acs_on_multifunction = true;
+ if (!strncmp(p, "id:", 3)) {
+ char opt[5];
+ int ret;
+ long val;
+
+ if (max_acs_id >= NUM_ACS_IDS - 1) {
+ pr_warn("Out of PCIe ACS override slots (%d)\n",
+ NUM_ACS_IDS);
+ goto next;
+ }
+
+ p += 3;
+ snprintf(opt, 5, "%s", p);
+ ret = kstrtol(opt, 16, &val);
+ if (ret) {
+ pr_warn("PCIe ACS ID parse error %d\n", ret);
+ goto next;
+ }
+ acs_on_ids[max_acs_id].vendor = val;
+
+ p += strcspn(p, ":");
+ if (*p != ':') {
+ pr_warn("PCIe ACS invalid ID\n");
+ goto next;
+ }
+
+ p++;
+ snprintf(opt, 5, "%s", p);
+ ret = kstrtol(opt, 16, &val);
+ if (ret) {
+ pr_warn("PCIe ACS ID parse error %d\n", ret);
+ goto next;
+ }
+ acs_on_ids[max_acs_id].device = val;
+ max_acs_id++;
+ }
+next:
+ p += strcspn(p, ",");
+ if (*p == ',')
+ p++;
+ }
+
+ if (acs_on_downstream || acs_on_multifunction || max_acs_id)
+ pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n");
+
+ return 0;
+}
+
+early_param("pcie_acs_override", pcie_acs_override_setup);
+
+static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags)
+{
+ int i;
+
+ /* Never override ACS for legacy devices or devices with ACS caps */
+ if (!pci_is_pcie(dev) ||
+ pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS))
+ return -ENOTTY;
+
+ for (i = 0; i < max_acs_id; i++)
+ if (acs_on_ids[i].vendor == dev->vendor &&
+ acs_on_ids[i].device == dev->device)
+ return 1;
+
+ switch (pci_pcie_type(dev)) {
+ case PCI_EXP_TYPE_DOWNSTREAM:
+ case PCI_EXP_TYPE_ROOT_PORT:
+ if (acs_on_downstream)
+ return 1;
+ break;
+ case PCI_EXP_TYPE_ENDPOINT:
+ case PCI_EXP_TYPE_UPSTREAM:
+ case PCI_EXP_TYPE_LEG_END:
+ case PCI_EXP_TYPE_RC_END:
+ if (acs_on_multifunction && dev->multifunction)
+ return 1;
+ }
+
+ return -ENOTTY;
+}
+
static const struct pci_dev_acs_enabled {
u16 vendor;
u16 device;
@@ -4797,6 +4902,8 @@
{ PCI_VENDOR_ID_ZHAOXIN, 0x9083, pci_quirk_mf_endpoint_acs },
/* Zhaoxin Root/Downstream Ports */
{ PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs },
+ /* IOMMU ACS override patch */
+ { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides },
{ 0 }
};
then you can just compile the kernel sources and itll patch.