mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
iommu/amd: Add PCI segment support for ivrs_[ioapic/hpet/acpihid] commands
[ Upstream commitbbe3a10658] By default, PCI segment is zero and can be omitted. To support system with non-zero PCI segment ID, modify the parsing functions to allow PCI segment ID. Co-developed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Link: https://lore.kernel.org/r/20220706113825.25582-33-vasant.hegde@amd.com Signed-off-by: Joerg Roedel <jroedel@suse.de> Stable-dep-of:1198d2316d("iommu/amd: Fix ill-formed ivrs_ioapic, ivrs_hpet and ivrs_acpihid options") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
ab9bb65b85
commit
5badda810f
@@ -2103,23 +2103,39 @@
|
|||||||
|
|
||||||
ivrs_ioapic [HW,X86-64]
|
ivrs_ioapic [HW,X86-64]
|
||||||
Provide an override to the IOAPIC-ID<->DEVICE-ID
|
Provide an override to the IOAPIC-ID<->DEVICE-ID
|
||||||
mapping provided in the IVRS ACPI table. For
|
mapping provided in the IVRS ACPI table.
|
||||||
example, to map IOAPIC-ID decimal 10 to
|
By default, PCI segment is 0, and can be omitted.
|
||||||
PCI device 00:14.0 write the parameter as:
|
For example:
|
||||||
|
* To map IOAPIC-ID decimal 10 to PCI device 00:14.0
|
||||||
|
write the parameter as:
|
||||||
ivrs_ioapic[10]=00:14.0
|
ivrs_ioapic[10]=00:14.0
|
||||||
|
* To map IOAPIC-ID decimal 10 to PCI segment 0x1 and
|
||||||
|
PCI device 00:14.0 write the parameter as:
|
||||||
|
ivrs_ioapic[10]=0001:00:14.0
|
||||||
|
|
||||||
ivrs_hpet [HW,X86-64]
|
ivrs_hpet [HW,X86-64]
|
||||||
Provide an override to the HPET-ID<->DEVICE-ID
|
Provide an override to the HPET-ID<->DEVICE-ID
|
||||||
mapping provided in the IVRS ACPI table. For
|
mapping provided in the IVRS ACPI table.
|
||||||
example, to map HPET-ID decimal 0 to
|
By default, PCI segment is 0, and can be omitted.
|
||||||
PCI device 00:14.0 write the parameter as:
|
For example:
|
||||||
|
* To map HPET-ID decimal 0 to PCI device 00:14.0
|
||||||
|
write the parameter as:
|
||||||
ivrs_hpet[0]=00:14.0
|
ivrs_hpet[0]=00:14.0
|
||||||
|
* To map HPET-ID decimal 10 to PCI segment 0x1 and
|
||||||
|
PCI device 00:14.0 write the parameter as:
|
||||||
|
ivrs_ioapic[10]=0001:00:14.0
|
||||||
|
|
||||||
ivrs_acpihid [HW,X86-64]
|
ivrs_acpihid [HW,X86-64]
|
||||||
Provide an override to the ACPI-HID:UID<->DEVICE-ID
|
Provide an override to the ACPI-HID:UID<->DEVICE-ID
|
||||||
mapping provided in the IVRS ACPI table. For
|
mapping provided in the IVRS ACPI table.
|
||||||
example, to map UART-HID:UID AMD0020:0 to
|
|
||||||
PCI device 00:14.5 write the parameter as:
|
For example, to map UART-HID:UID AMD0020:0 to
|
||||||
|
PCI segment 0x1 and PCI device ID 00:14.5,
|
||||||
|
write the parameter as:
|
||||||
|
ivrs_acpihid[0001:00:14.5]=AMD0020:0
|
||||||
|
|
||||||
|
By default, PCI segment is 0, and can be omitted.
|
||||||
|
For example, PCI device 00:14.5 write the parameter as:
|
||||||
ivrs_acpihid[00:14.5]=AMD0020:0
|
ivrs_acpihid[00:14.5]=AMD0020:0
|
||||||
|
|
||||||
js= [HW,JOY] Analog joystick
|
js= [HW,JOY] Analog joystick
|
||||||
|
|||||||
@@ -85,6 +85,10 @@
|
|||||||
#define ACPI_DEVFLAG_ATSDIS 0x10000000
|
#define ACPI_DEVFLAG_ATSDIS 0x10000000
|
||||||
|
|
||||||
#define LOOP_TIMEOUT 2000000
|
#define LOOP_TIMEOUT 2000000
|
||||||
|
|
||||||
|
#define IVRS_GET_SBDF_ID(seg, bus, dev, fd) (((seg & 0xffff) << 16) | ((bus & 0xff) << 8) \
|
||||||
|
| ((dev & 0x1f) << 3) | (fn & 0x7))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ACPI table definitions
|
* ACPI table definitions
|
||||||
*
|
*
|
||||||
@@ -3046,15 +3050,17 @@ static int __init parse_amd_iommu_options(char *str)
|
|||||||
|
|
||||||
static int __init parse_ivrs_ioapic(char *str)
|
static int __init parse_ivrs_ioapic(char *str)
|
||||||
{
|
{
|
||||||
unsigned int bus, dev, fn;
|
u32 seg = 0, bus, dev, fn;
|
||||||
int ret, id, i;
|
int ret, id, i;
|
||||||
u16 devid;
|
u32 devid;
|
||||||
|
|
||||||
ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
|
ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
|
||||||
|
|
||||||
if (ret != 4) {
|
if (ret != 4) {
|
||||||
pr_err("Invalid command line: ivrs_ioapic%s\n", str);
|
ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
|
||||||
return 1;
|
if (ret != 5) {
|
||||||
|
pr_err("Invalid command line: ivrs_ioapic%s\n", str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (early_ioapic_map_size == EARLY_MAP_SIZE) {
|
if (early_ioapic_map_size == EARLY_MAP_SIZE) {
|
||||||
@@ -3063,7 +3069,7 @@ static int __init parse_ivrs_ioapic(char *str)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
|
devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
|
||||||
|
|
||||||
cmdline_maps = true;
|
cmdline_maps = true;
|
||||||
i = early_ioapic_map_size++;
|
i = early_ioapic_map_size++;
|
||||||
@@ -3076,15 +3082,17 @@ static int __init parse_ivrs_ioapic(char *str)
|
|||||||
|
|
||||||
static int __init parse_ivrs_hpet(char *str)
|
static int __init parse_ivrs_hpet(char *str)
|
||||||
{
|
{
|
||||||
unsigned int bus, dev, fn;
|
u32 seg = 0, bus, dev, fn;
|
||||||
int ret, id, i;
|
int ret, id, i;
|
||||||
u16 devid;
|
u32 devid;
|
||||||
|
|
||||||
ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
|
ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
|
||||||
|
|
||||||
if (ret != 4) {
|
if (ret != 4) {
|
||||||
pr_err("Invalid command line: ivrs_hpet%s\n", str);
|
ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
|
||||||
return 1;
|
if (ret != 5) {
|
||||||
|
pr_err("Invalid command line: ivrs_hpet%s\n", str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (early_hpet_map_size == EARLY_MAP_SIZE) {
|
if (early_hpet_map_size == EARLY_MAP_SIZE) {
|
||||||
@@ -3093,7 +3101,7 @@ static int __init parse_ivrs_hpet(char *str)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
|
devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
|
||||||
|
|
||||||
cmdline_maps = true;
|
cmdline_maps = true;
|
||||||
i = early_hpet_map_size++;
|
i = early_hpet_map_size++;
|
||||||
@@ -3106,15 +3114,18 @@ static int __init parse_ivrs_hpet(char *str)
|
|||||||
|
|
||||||
static int __init parse_ivrs_acpihid(char *str)
|
static int __init parse_ivrs_acpihid(char *str)
|
||||||
{
|
{
|
||||||
u32 bus, dev, fn;
|
u32 seg = 0, bus, dev, fn;
|
||||||
char *hid, *uid, *p;
|
char *hid, *uid, *p;
|
||||||
char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
|
char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
|
ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
|
||||||
if (ret != 4) {
|
if (ret != 4) {
|
||||||
pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
|
ret = sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid);
|
||||||
return 1;
|
if (ret != 5) {
|
||||||
|
pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p = acpiid;
|
p = acpiid;
|
||||||
@@ -3136,8 +3147,7 @@ static int __init parse_ivrs_acpihid(char *str)
|
|||||||
i = early_acpihid_map_size++;
|
i = early_acpihid_map_size++;
|
||||||
memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
|
memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
|
||||||
memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
|
memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
|
||||||
early_acpihid_map[i].devid =
|
early_acpihid_map[i].devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
|
||||||
((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
|
|
||||||
early_acpihid_map[i].cmd_line = true;
|
early_acpihid_map[i].cmd_line = true;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user