mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
iommu/amd: Override wrong IVRS IOAPIC on Raven Ridge systems
[ Upstream commit 93d051550e ]
Raven Ridge systems may have malfunction touchpad or hang at boot if
incorrect IVRS IOAPIC is provided by BIOS.
Users already found correct "ivrs_ioapic=" values, let's put them inside
kernel to workaround buggy BIOS.
BugLink: https://bugs.launchpad.net/bugs/1795292
BugLink: https://bugs.launchpad.net/bugs/1837688
Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
291da33504
commit
2aeeb0a4b4
@@ -10,7 +10,7 @@ obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
|
||||
obj-$(CONFIG_IOMMU_IOVA) += iova.o
|
||||
obj-$(CONFIG_OF_IOMMU) += of_iommu.o
|
||||
obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
|
||||
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
|
||||
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_quirks.o
|
||||
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
|
||||
obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
|
||||
obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
|
||||
|
||||
14
drivers/iommu/amd_iommu.h
Normal file
14
drivers/iommu/amd_iommu.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef AMD_IOMMU_H
|
||||
#define AMD_IOMMU_H
|
||||
|
||||
int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line);
|
||||
|
||||
#ifdef CONFIG_DMI
|
||||
void amd_iommu_apply_ivrs_quirks(void);
|
||||
#else
|
||||
static void amd_iommu_apply_ivrs_quirks(void) { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <asm/irq_remapping.h>
|
||||
|
||||
#include <linux/crash_dump.h>
|
||||
#include "amd_iommu.h"
|
||||
#include "amd_iommu_proto.h"
|
||||
#include "amd_iommu_types.h"
|
||||
#include "irq_remapping.h"
|
||||
@@ -1002,7 +1003,7 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
|
||||
set_iommu_for_device(iommu, devid);
|
||||
}
|
||||
|
||||
static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
|
||||
int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
|
||||
{
|
||||
struct devid_map *entry;
|
||||
struct list_head *list;
|
||||
@@ -1153,6 +1154,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
amd_iommu_apply_ivrs_quirks();
|
||||
|
||||
/*
|
||||
* First save the recommended feature enable bits from ACPI
|
||||
*/
|
||||
|
||||
92
drivers/iommu/amd_iommu_quirks.c
Normal file
92
drivers/iommu/amd_iommu_quirks.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* Quirks for AMD IOMMU
|
||||
*
|
||||
* Copyright (C) 2019 Kai-Heng Feng <kai.heng.feng@canonical.com>
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DMI
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#include "amd_iommu.h"
|
||||
|
||||
#define IVHD_SPECIAL_IOAPIC 1
|
||||
|
||||
struct ivrs_quirk_entry {
|
||||
u8 id;
|
||||
u16 devid;
|
||||
};
|
||||
|
||||
enum {
|
||||
DELL_INSPIRON_7375 = 0,
|
||||
DELL_LATITUDE_5495,
|
||||
LENOVO_IDEAPAD_330S_15ARR,
|
||||
};
|
||||
|
||||
static const struct ivrs_quirk_entry ivrs_ioapic_quirks[][3] __initconst = {
|
||||
/* ivrs_ioapic[4]=00:14.0 ivrs_ioapic[5]=00:00.2 */
|
||||
[DELL_INSPIRON_7375] = {
|
||||
{ .id = 4, .devid = 0xa0 },
|
||||
{ .id = 5, .devid = 0x2 },
|
||||
{}
|
||||
},
|
||||
/* ivrs_ioapic[4]=00:14.0 */
|
||||
[DELL_LATITUDE_5495] = {
|
||||
{ .id = 4, .devid = 0xa0 },
|
||||
{}
|
||||
},
|
||||
/* ivrs_ioapic[32]=00:14.0 */
|
||||
[LENOVO_IDEAPAD_330S_15ARR] = {
|
||||
{ .id = 32, .devid = 0xa0 },
|
||||
{}
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static int __init ivrs_ioapic_quirk_cb(const struct dmi_system_id *d)
|
||||
{
|
||||
const struct ivrs_quirk_entry *i;
|
||||
|
||||
for (i = d->driver_data; i->id != 0 && i->devid != 0; i++)
|
||||
add_special_device(IVHD_SPECIAL_IOAPIC, i->id, (u16 *)&i->devid, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id ivrs_quirks[] __initconst = {
|
||||
{
|
||||
.callback = ivrs_ioapic_quirk_cb,
|
||||
.ident = "Dell Inspiron 7375",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7375"),
|
||||
},
|
||||
.driver_data = (void *)&ivrs_ioapic_quirks[DELL_INSPIRON_7375],
|
||||
},
|
||||
{
|
||||
.callback = ivrs_ioapic_quirk_cb,
|
||||
.ident = "Dell Latitude 5495",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 5495"),
|
||||
},
|
||||
.driver_data = (void *)&ivrs_ioapic_quirks[DELL_LATITUDE_5495],
|
||||
},
|
||||
{
|
||||
.callback = ivrs_ioapic_quirk_cb,
|
||||
.ident = "Lenovo ideapad 330S-15ARR",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "81FB"),
|
||||
},
|
||||
.driver_data = (void *)&ivrs_ioapic_quirks[LENOVO_IDEAPAD_330S_15ARR],
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
void __init amd_iommu_apply_ivrs_quirks(void)
|
||||
{
|
||||
dmi_check_system(ivrs_quirks);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user