thunderbolt: Changes for v4.21 merge window
-----BEGIN PGP SIGNATURE----- iQJUBAABCgA+FiEEVTdhRGBbNzLrSUBaAP2fSd+ZWKAFAlwOLrYgHG1pa2Eud2Vz dGVyYmVyZ0BsaW51eC5pbnRlbC5jb20ACgkQAP2fSd+ZWKCQyA//Zs4mAtgwa6ON 9gaYjVDkrAIs8jD1JHHBKpqCVvRdCZfnAtYT2Rk33SgRYFV0UmXoOL3HzMOHMTjO 2/S0SmO260UAQL7b4yPSb6tzCLSrW55rDS52EpQmJ8ncGD8l65tduwdA9gZEt+Kr AhM5TK6nEQagRIcAQSmBlJMkDWNy2wvxTOebQv3C9woGSK7TFMvhCfZaLV9hpi89 ThdQtGLsGnYyzSw9tvEAwrsX96mWr2sdMV392SIgXEs+P3NtphTPvNM33Jo48l36 aFbhQwHEy6vtV6sC1va8NC/XQgLCK3DSx9R2/s+dZnZTXF4w14X+7KvNhQM8YpPB OXPQXIsjpz/APBWULoPy6BX2TtzJUy0upGm/4B0kYBCFF1qmbFIeOi6beaXTFGzz 80qBpv6XUk/P/kGs3FTt3FfARjmHYnYuQhP90wFgoelMOHmBatz0YQYUYVeNe5ew 5itFeXgm3PkSnibxu0KBJCQe32SmNgMiGctgEKirAbK6Ibdp0bvj8NlZuCdoF5S/ 1z6L4GL9zoPrxTRKMZlxlvexe9Lr+qRqiG8fG+Xt/WRZFauD0k7l7RvTqzxDC+Di PnlrryDDNDEnSSlNjHdEqNMg8B1QrQ/5e0GAUoKNFVVTBLfc1oChaxAfzDjhRRgU 4l2irxVwQSP76ZCvPuF5NOfEfI58Buo= =tqRs -----END PGP SIGNATURE----- Merge tag 'thunderbolt-for-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into char-misc-next Mika writes: thunderbolt: Changes for v4.21 merge window * tag 'thunderbolt-for-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: thunderbolt: Export IOMMU based DMA protection support to userspace iommu/vt-d: Do not enable ATS for untrusted devices iommu/vt-d: Force IOMMU on for platform opt in hint PCI / ACPI: Identify untrusted PCI devices
This commit is contained in:
commit
c20c809f92
@ -21,6 +21,15 @@ Description: Holds a comma separated list of device unique_ids that
|
|||||||
If a device is authorized automatically during boot its
|
If a device is authorized automatically during boot its
|
||||||
boot attribute is set to 1.
|
boot attribute is set to 1.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../domainX/iommu_dma_protection
|
||||||
|
Date: Mar 2019
|
||||||
|
KernelVersion: 4.21
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: This attribute tells whether the system uses IOMMU
|
||||||
|
for DMA protection. Value of 1 means IOMMU is used 0 means
|
||||||
|
it is not (DMA protection is solely based on Thunderbolt
|
||||||
|
security levels).
|
||||||
|
|
||||||
What: /sys/bus/thunderbolt/devices/.../domainX/security
|
What: /sys/bus/thunderbolt/devices/.../domainX/security
|
||||||
Date: Sep 2017
|
Date: Sep 2017
|
||||||
KernelVersion: 4.13
|
KernelVersion: 4.13
|
||||||
|
@ -133,6 +133,26 @@ If the user still wants to connect the device they can either approve
|
|||||||
the device without a key or write a new key and write 1 to the
|
the device without a key or write a new key and write 1 to the
|
||||||
``authorized`` file to get the new key stored on the device NVM.
|
``authorized`` file to get the new key stored on the device NVM.
|
||||||
|
|
||||||
|
DMA protection utilizing IOMMU
|
||||||
|
------------------------------
|
||||||
|
Recent systems from 2018 and forward with Thunderbolt ports may natively
|
||||||
|
support IOMMU. This means that Thunderbolt security is handled by an IOMMU
|
||||||
|
so connected devices cannot access memory regions outside of what is
|
||||||
|
allocated for them by drivers. When Linux is running on such system it
|
||||||
|
automatically enables IOMMU if not enabled by the user already. These
|
||||||
|
systems can be identified by reading ``1`` from
|
||||||
|
``/sys/bus/thunderbolt/devices/domainX/iommu_dma_protection`` attribute.
|
||||||
|
|
||||||
|
The driver does not do anything special in this case but because DMA
|
||||||
|
protection is handled by the IOMMU, security levels (if set) are
|
||||||
|
redundant. For this reason some systems ship with security level set to
|
||||||
|
``none``. Other systems have security level set to ``user`` in order to
|
||||||
|
support downgrade to older OS, so users who want to automatically
|
||||||
|
authorize devices when IOMMU DMA protection is enabled can use the
|
||||||
|
following ``udev`` rule::
|
||||||
|
|
||||||
|
ACTION=="add", SUBSYSTEM=="thunderbolt", ATTRS{iommu_dma_protection}=="1", ATTR{authorized}=="0", ATTR{authorized}="1"
|
||||||
|
|
||||||
Upgrading NVM on Thunderbolt device or host
|
Upgrading NVM on Thunderbolt device or host
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
Since most of the functionality is handled in firmware running on a
|
Since most of the functionality is handled in firmware running on a
|
||||||
|
@ -24,6 +24,14 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data,
|
|||||||
acpi_object_type type,
|
acpi_object_type type,
|
||||||
const union acpi_object **obj);
|
const union acpi_object **obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The GUIDs here are made equivalent to each other in order to avoid extra
|
||||||
|
* complexity in the properties handling code, with the caveat that the
|
||||||
|
* kernel will accept certain combinations of GUID and properties that are
|
||||||
|
* not defined without a warning. For instance if any of the properties
|
||||||
|
* from different GUID appear in a property list of another, it will be
|
||||||
|
* accepted by the kernel. Firmware validation tools should catch these.
|
||||||
|
*/
|
||||||
static const guid_t prp_guids[] = {
|
static const guid_t prp_guids[] = {
|
||||||
/* ACPI _DSD device properties GUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
|
/* ACPI _DSD device properties GUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
|
||||||
GUID_INIT(0xdaffd814, 0x6eba, 0x4d8c,
|
GUID_INIT(0xdaffd814, 0x6eba, 0x4d8c,
|
||||||
@ -31,6 +39,9 @@ static const guid_t prp_guids[] = {
|
|||||||
/* Hotplug in D3 GUID: 6211e2c0-58a3-4af3-90e1-927a4e0c55a4 */
|
/* Hotplug in D3 GUID: 6211e2c0-58a3-4af3-90e1-927a4e0c55a4 */
|
||||||
GUID_INIT(0x6211e2c0, 0x58a3, 0x4af3,
|
GUID_INIT(0x6211e2c0, 0x58a3, 0x4af3,
|
||||||
0x90, 0xe1, 0x92, 0x7a, 0x4e, 0x0c, 0x55, 0xa4),
|
0x90, 0xe1, 0x92, 0x7a, 0x4e, 0x0c, 0x55, 0xa4),
|
||||||
|
/* External facing port GUID: efcc06cc-73ac-4bc3-bff0-76143807c389 */
|
||||||
|
GUID_INIT(0xefcc06cc, 0x73ac, 0x4bc3,
|
||||||
|
0xbf, 0xf0, 0x76, 0x14, 0x38, 0x07, 0xc3, 0x89),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const guid_t ads_guid =
|
static const guid_t ads_guid =
|
||||||
|
@ -2042,3 +2042,28 @@ int dmar_device_remove(acpi_handle handle)
|
|||||||
{
|
{
|
||||||
return dmar_device_hotplug(handle, false);
|
return dmar_device_hotplug(handle, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dmar_platform_optin - Is %DMA_CTRL_PLATFORM_OPT_IN_FLAG set in DMAR table
|
||||||
|
*
|
||||||
|
* Returns true if the platform has %DMA_CTRL_PLATFORM_OPT_IN_FLAG set in
|
||||||
|
* the ACPI DMAR table. This means that the platform boot firmware has made
|
||||||
|
* sure no device can issue DMA outside of RMRR regions.
|
||||||
|
*/
|
||||||
|
bool dmar_platform_optin(void)
|
||||||
|
{
|
||||||
|
struct acpi_table_dmar *dmar;
|
||||||
|
acpi_status status;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
status = acpi_get_table(ACPI_SIG_DMAR, 0,
|
||||||
|
(struct acpi_table_header **)&dmar);
|
||||||
|
if (ACPI_FAILURE(status))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ret = !!(dmar->flags & DMAR_PLATFORM_OPT_IN);
|
||||||
|
acpi_put_table((struct acpi_table_header *)dmar);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(dmar_platform_optin);
|
||||||
|
@ -184,6 +184,7 @@ static int rwbf_quirk;
|
|||||||
*/
|
*/
|
||||||
static int force_on = 0;
|
static int force_on = 0;
|
||||||
int intel_iommu_tboot_noforce;
|
int intel_iommu_tboot_noforce;
|
||||||
|
static int no_platform_optin;
|
||||||
|
|
||||||
#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
|
#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
|
||||||
|
|
||||||
@ -503,6 +504,7 @@ static int __init intel_iommu_setup(char *str)
|
|||||||
pr_info("IOMMU enabled\n");
|
pr_info("IOMMU enabled\n");
|
||||||
} else if (!strncmp(str, "off", 3)) {
|
} else if (!strncmp(str, "off", 3)) {
|
||||||
dmar_disabled = 1;
|
dmar_disabled = 1;
|
||||||
|
no_platform_optin = 1;
|
||||||
pr_info("IOMMU disabled\n");
|
pr_info("IOMMU disabled\n");
|
||||||
} else if (!strncmp(str, "igfx_off", 8)) {
|
} else if (!strncmp(str, "igfx_off", 8)) {
|
||||||
dmar_map_gfx = 0;
|
dmar_map_gfx = 0;
|
||||||
@ -1471,7 +1473,8 @@ static void iommu_enable_dev_iotlb(struct device_domain_info *info)
|
|||||||
if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
|
if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
|
||||||
info->pri_enabled = 1;
|
info->pri_enabled = 1;
|
||||||
#endif
|
#endif
|
||||||
if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
|
if (!pdev->untrusted && info->ats_supported &&
|
||||||
|
!pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
|
||||||
info->ats_enabled = 1;
|
info->ats_enabled = 1;
|
||||||
domain_update_iotlb(info->domain);
|
domain_update_iotlb(info->domain);
|
||||||
info->ats_qdep = pci_ats_queue_depth(pdev);
|
info->ats_qdep = pci_ats_queue_depth(pdev);
|
||||||
@ -2895,6 +2898,13 @@ static int iommu_should_identity_map(struct device *dev, int startup)
|
|||||||
if (device_is_rmrr_locked(dev))
|
if (device_is_rmrr_locked(dev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevent any device marked as untrusted from getting
|
||||||
|
* placed into the statically identity mapping domain.
|
||||||
|
*/
|
||||||
|
if (pdev->untrusted)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
|
if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -4728,14 +4738,54 @@ const struct attribute_group *intel_iommu_groups[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int __init platform_optin_force_iommu(void)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = NULL;
|
||||||
|
bool has_untrusted_dev = false;
|
||||||
|
|
||||||
|
if (!dmar_platform_optin() || no_platform_optin)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for_each_pci_dev(pdev) {
|
||||||
|
if (pdev->untrusted) {
|
||||||
|
has_untrusted_dev = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!has_untrusted_dev)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (no_iommu || dmar_disabled)
|
||||||
|
pr_info("Intel-IOMMU force enabled due to platform opt in\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If Intel-IOMMU is disabled by default, we will apply identity
|
||||||
|
* map for all devices except those marked as being untrusted.
|
||||||
|
*/
|
||||||
|
if (dmar_disabled)
|
||||||
|
iommu_identity_mapping |= IDENTMAP_ALL;
|
||||||
|
|
||||||
|
dmar_disabled = 0;
|
||||||
|
#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
|
||||||
|
swiotlb = 0;
|
||||||
|
#endif
|
||||||
|
no_iommu = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int __init intel_iommu_init(void)
|
int __init intel_iommu_init(void)
|
||||||
{
|
{
|
||||||
int ret = -ENODEV;
|
int ret = -ENODEV;
|
||||||
struct dmar_drhd_unit *drhd;
|
struct dmar_drhd_unit *drhd;
|
||||||
struct intel_iommu *iommu;
|
struct intel_iommu *iommu;
|
||||||
|
|
||||||
/* VT-d is required for a TXT/tboot launch, so enforce that */
|
/*
|
||||||
force_on = tboot_force_iommu();
|
* Intel IOMMU is required for a TXT/tboot launch or platform
|
||||||
|
* opt in, so enforce that.
|
||||||
|
*/
|
||||||
|
force_on = tboot_force_iommu() || platform_optin_force_iommu();
|
||||||
|
|
||||||
if (iommu_init_mempool()) {
|
if (iommu_init_mempool()) {
|
||||||
if (force_on)
|
if (force_on)
|
||||||
|
@ -789,6 +789,24 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev,
|
|||||||
ACPI_FREE(obj);
|
ACPI_FREE(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pci_acpi_set_untrusted(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
u8 val;
|
||||||
|
|
||||||
|
if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
|
||||||
|
return;
|
||||||
|
if (device_property_read_u8(&dev->dev, "ExternalFacingPort", &val))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These root ports expose PCIe (including DMA) outside of the
|
||||||
|
* system so make sure we treat them and everything behind as
|
||||||
|
* untrusted.
|
||||||
|
*/
|
||||||
|
if (val)
|
||||||
|
dev->untrusted = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void pci_acpi_setup(struct device *dev)
|
static void pci_acpi_setup(struct device *dev)
|
||||||
{
|
{
|
||||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||||
@ -798,6 +816,7 @@ static void pci_acpi_setup(struct device *dev)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
pci_acpi_optimize_delay(pci_dev, adev->handle);
|
pci_acpi_optimize_delay(pci_dev, adev->handle);
|
||||||
|
pci_acpi_set_untrusted(pci_dev);
|
||||||
|
|
||||||
pci_acpi_add_pm_notifier(adev, pci_dev);
|
pci_acpi_add_pm_notifier(adev, pci_dev);
|
||||||
if (!adev->wakeup.flags.valid)
|
if (!adev->wakeup.flags.valid)
|
||||||
|
@ -1378,6 +1378,19 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_pcie_untrusted(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
struct pci_dev *parent;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the upstream bridge is untrusted we treat this device
|
||||||
|
* untrusted as well.
|
||||||
|
*/
|
||||||
|
parent = pci_upstream_bridge(dev);
|
||||||
|
if (parent && parent->untrusted)
|
||||||
|
dev->untrusted = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_ext_cfg_is_aliased - Is ext config space just an alias of std config?
|
* pci_ext_cfg_is_aliased - Is ext config space just an alias of std config?
|
||||||
* @dev: PCI device
|
* @dev: PCI device
|
||||||
@ -1638,6 +1651,8 @@ int pci_setup_device(struct pci_dev *dev)
|
|||||||
/* Need to have dev->cfg_size ready */
|
/* Need to have dev->cfg_size ready */
|
||||||
set_pcie_thunderbolt(dev);
|
set_pcie_thunderbolt(dev);
|
||||||
|
|
||||||
|
set_pcie_untrusted(dev);
|
||||||
|
|
||||||
/* "Unknown power state" */
|
/* "Unknown power state" */
|
||||||
dev->current_state = PCI_UNKNOWN;
|
dev->current_state = PCI_UNKNOWN;
|
||||||
|
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/dmar.h>
|
||||||
#include <linux/idr.h>
|
#include <linux/idr.h>
|
||||||
|
#include <linux/iommu.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
@ -236,6 +238,20 @@ err_free_str:
|
|||||||
}
|
}
|
||||||
static DEVICE_ATTR_RW(boot_acl);
|
static DEVICE_ATTR_RW(boot_acl);
|
||||||
|
|
||||||
|
static ssize_t iommu_dma_protection_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Kernel DMA protection is a feature where Thunderbolt security is
|
||||||
|
* handled natively using IOMMU. It is enabled when IOMMU is
|
||||||
|
* enabled and ACPI DMAR table has DMAR_PLATFORM_OPT_IN set.
|
||||||
|
*/
|
||||||
|
return sprintf(buf, "%d\n",
|
||||||
|
iommu_present(&pci_bus_type) && dmar_platform_optin());
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(iommu_dma_protection);
|
||||||
|
|
||||||
static ssize_t security_show(struct device *dev, struct device_attribute *attr,
|
static ssize_t security_show(struct device *dev, struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
@ -251,6 +267,7 @@ static DEVICE_ATTR_RO(security);
|
|||||||
|
|
||||||
static struct attribute *domain_attrs[] = {
|
static struct attribute *domain_attrs[] = {
|
||||||
&dev_attr_boot_acl.attr,
|
&dev_attr_boot_acl.attr,
|
||||||
|
&dev_attr_iommu_dma_protection.attr,
|
||||||
&dev_attr_security.attr,
|
&dev_attr_security.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
@ -39,6 +39,7 @@ struct acpi_dmar_header;
|
|||||||
/* DMAR Flags */
|
/* DMAR Flags */
|
||||||
#define DMAR_INTR_REMAP 0x1
|
#define DMAR_INTR_REMAP 0x1
|
||||||
#define DMAR_X2APIC_OPT_OUT 0x2
|
#define DMAR_X2APIC_OPT_OUT 0x2
|
||||||
|
#define DMAR_PLATFORM_OPT_IN 0x4
|
||||||
|
|
||||||
struct intel_iommu;
|
struct intel_iommu;
|
||||||
|
|
||||||
@ -170,6 +171,8 @@ static inline int dmar_ir_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
|
|||||||
{ return 0; }
|
{ return 0; }
|
||||||
#endif /* CONFIG_IRQ_REMAP */
|
#endif /* CONFIG_IRQ_REMAP */
|
||||||
|
|
||||||
|
extern bool dmar_platform_optin(void);
|
||||||
|
|
||||||
#else /* CONFIG_DMAR_TABLE */
|
#else /* CONFIG_DMAR_TABLE */
|
||||||
|
|
||||||
static inline int dmar_device_add(void *handle)
|
static inline int dmar_device_add(void *handle)
|
||||||
@ -182,6 +185,11 @@ static inline int dmar_device_remove(void *handle)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool dmar_platform_optin(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_DMAR_TABLE */
|
#endif /* CONFIG_DMAR_TABLE */
|
||||||
|
|
||||||
struct irte {
|
struct irte {
|
||||||
|
@ -396,6 +396,14 @@ struct pci_dev {
|
|||||||
unsigned int is_hotplug_bridge:1;
|
unsigned int is_hotplug_bridge:1;
|
||||||
unsigned int shpc_managed:1; /* SHPC owned by shpchp */
|
unsigned int shpc_managed:1; /* SHPC owned by shpchp */
|
||||||
unsigned int is_thunderbolt:1; /* Thunderbolt controller */
|
unsigned int is_thunderbolt:1; /* Thunderbolt controller */
|
||||||
|
/*
|
||||||
|
* Devices marked being untrusted are the ones that can potentially
|
||||||
|
* execute DMA attacks and similar. They are typically connected
|
||||||
|
* through external ports such as Thunderbolt but not limited to
|
||||||
|
* that. When an IOMMU is enabled they should be getting full
|
||||||
|
* mappings to make sure they cannot access arbitrary memory.
|
||||||
|
*/
|
||||||
|
unsigned int untrusted:1;
|
||||||
unsigned int __aer_firmware_first_valid:1;
|
unsigned int __aer_firmware_first_valid:1;
|
||||||
unsigned int __aer_firmware_first:1;
|
unsigned int __aer_firmware_first:1;
|
||||||
unsigned int broken_intx_masking:1; /* INTx masking can't be used */
|
unsigned int broken_intx_masking:1; /* INTx masking can't be used */
|
||||||
|
Loading…
Reference in New Issue
Block a user