Skip to content

Commit 1198d23

Browse files
kimphillamdjoergroedel
authored andcommitted
iommu/amd: Fix ill-formed ivrs_ioapic, ivrs_hpet and ivrs_acpihid options
Currently, these options cause the following libkmod error: libkmod: ERROR ../libkmod/libkmod-config.c:489 kcmdline_parse_result: \ Ignoring bad option on kernel command line while parsing module \ name: 'ivrs_xxxx[XX:XX' Fix by introducing a new parameter format for these options and throw a warning for the deprecated format. Users are still allowed to omit the PCI Segment if zero. Adding a Link: to the reason why we're modding the syntax parsing in the driver and not in libkmod. Fixes: ca3bf5d ("iommu/amd: Introduces ivrs_acpihid kernel parameter") Cc: [email protected] Link: https://lore.kernel.org/linux-modules/[email protected]/ Reported-by: Kim Phillips <[email protected]> Co-developed-by: Suravee Suthikulpanit <[email protected]> Signed-off-by: Suravee Suthikulpanit <[email protected]> Signed-off-by: Kim Phillips <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 5f18e9f commit 1198d23

File tree

2 files changed

+76
-30
lines changed

2 files changed

+76
-30
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2300,7 +2300,13 @@
23002300
Provide an override to the IOAPIC-ID<->DEVICE-ID
23012301
mapping provided in the IVRS ACPI table.
23022302
By default, PCI segment is 0, and can be omitted.
2303-
For example:
2303+
2304+
For example, to map IOAPIC-ID decimal 10 to
2305+
PCI segment 0x1 and PCI device 00:14.0,
2306+
write the parameter as:
2307+
ivrs_ioapic=10@0001:00:14.0
2308+
2309+
Deprecated formats:
23042310
* To map IOAPIC-ID decimal 10 to PCI device 00:14.0
23052311
write the parameter as:
23062312
ivrs_ioapic[10]=00:14.0
@@ -2312,7 +2318,13 @@
23122318
Provide an override to the HPET-ID<->DEVICE-ID
23132319
mapping provided in the IVRS ACPI table.
23142320
By default, PCI segment is 0, and can be omitted.
2315-
For example:
2321+
2322+
For example, to map HPET-ID decimal 10 to
2323+
PCI segment 0x1 and PCI device 00:14.0,
2324+
write the parameter as:
2325+
ivrs_hpet=10@0001:00:14.0
2326+
2327+
Deprecated formats:
23162328
* To map HPET-ID decimal 0 to PCI device 00:14.0
23172329
write the parameter as:
23182330
ivrs_hpet[0]=00:14.0
@@ -2323,15 +2335,20 @@
23232335
ivrs_acpihid [HW,X86-64]
23242336
Provide an override to the ACPI-HID:UID<->DEVICE-ID
23252337
mapping provided in the IVRS ACPI table.
2338+
By default, PCI segment is 0, and can be omitted.
23262339

23272340
For example, to map UART-HID:UID AMD0020:0 to
23282341
PCI segment 0x1 and PCI device ID 00:14.5,
23292342
write the parameter as:
2330-
ivrs_acpihid[0001:00:14.5]=AMD0020:0
2343+
ivrs_acpihid=AMD0020:0@0001:00:14.5
23312344

2332-
By default, PCI segment is 0, and can be omitted.
2333-
For example, PCI device 00:14.5 write the parameter as:
2345+
Deprecated formats:
2346+
* To map UART-HID:UID AMD0020:0 to PCI segment is 0,
2347+
PCI device ID 00:14.5, write the parameter as:
23342348
ivrs_acpihid[00:14.5]=AMD0020:0
2349+
* To map UART-HID:UID AMD0020:0 to PCI segment 0x1 and
2350+
PCI device ID 00:14.5, write the parameter as:
2351+
ivrs_acpihid[0001:00:14.5]=AMD0020:0
23352352

23362353
js= [HW,JOY] Analog joystick
23372354
See Documentation/input/joydev/joystick.rst.

drivers/iommu/amd/init.c

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3402,18 +3402,24 @@ static int __init parse_amd_iommu_options(char *str)
34023402
static int __init parse_ivrs_ioapic(char *str)
34033403
{
34043404
u32 seg = 0, bus, dev, fn;
3405-
int ret, id, i;
3405+
int id, i;
34063406
u32 devid;
34073407

3408-
ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
3409-
if (ret != 4) {
3410-
ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
3411-
if (ret != 5) {
3412-
pr_err("Invalid command line: ivrs_ioapic%s\n", str);
3413-
return 1;
3414-
}
3408+
if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
3409+
sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
3410+
goto found;
3411+
3412+
if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
3413+
sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
3414+
pr_warn("ivrs_ioapic%s option format deprecated; use ivrs_ioapic=%d@%04x:%02x:%02x.%d instead\n",
3415+
str, id, seg, bus, dev, fn);
3416+
goto found;
34153417
}
34163418

3419+
pr_err("Invalid command line: ivrs_ioapic%s\n", str);
3420+
return 1;
3421+
3422+
found:
34173423
if (early_ioapic_map_size == EARLY_MAP_SIZE) {
34183424
pr_err("Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n",
34193425
str);
@@ -3434,18 +3440,24 @@ static int __init parse_ivrs_ioapic(char *str)
34343440
static int __init parse_ivrs_hpet(char *str)
34353441
{
34363442
u32 seg = 0, bus, dev, fn;
3437-
int ret, id, i;
3443+
int id, i;
34383444
u32 devid;
34393445

3440-
ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
3441-
if (ret != 4) {
3442-
ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
3443-
if (ret != 5) {
3444-
pr_err("Invalid command line: ivrs_hpet%s\n", str);
3445-
return 1;
3446-
}
3446+
if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
3447+
sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
3448+
goto found;
3449+
3450+
if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
3451+
sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
3452+
pr_warn("ivrs_hpet%s option format deprecated; use ivrs_hpet=%d@%04x:%02x:%02x.%d instead\n",
3453+
str, id, seg, bus, dev, fn);
3454+
goto found;
34473455
}
34483456

3457+
pr_err("Invalid command line: ivrs_hpet%s\n", str);
3458+
return 1;
3459+
3460+
found:
34493461
if (early_hpet_map_size == EARLY_MAP_SIZE) {
34503462
pr_err("Early HPET map overflow - ignoring ivrs_hpet%s\n",
34513463
str);
@@ -3466,19 +3478,36 @@ static int __init parse_ivrs_hpet(char *str)
34663478
static int __init parse_ivrs_acpihid(char *str)
34673479
{
34683480
u32 seg = 0, bus, dev, fn;
3469-
char *hid, *uid, *p;
3481+
char *hid, *uid, *p, *addr;
34703482
char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
3471-
int ret, i;
3472-
3473-
ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
3474-
if (ret != 4) {
3475-
ret = sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid);
3476-
if (ret != 5) {
3477-
pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
3478-
return 1;
3483+
int i;
3484+
3485+
addr = strchr(str, '@');
3486+
if (!addr) {
3487+
if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 ||
3488+
sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) {
3489+
pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n",
3490+
str, acpiid, seg, bus, dev, fn);
3491+
goto found;
34793492
}
3493+
goto not_found;
34803494
}
34813495

3496+
/* We have the '@', make it the terminator to get just the acpiid */
3497+
*addr++ = 0;
3498+
3499+
if (sscanf(str, "=%s", acpiid) != 1)
3500+
goto not_found;
3501+
3502+
if (sscanf(addr, "%x:%x.%x", &bus, &dev, &fn) == 3 ||
3503+
sscanf(addr, "%x:%x:%x.%x", &seg, &bus, &dev, &fn) == 4)
3504+
goto found;
3505+
3506+
not_found:
3507+
pr_err("Invalid command line: ivrs_acpihid%s\n", str);
3508+
return 1;
3509+
3510+
found:
34823511
p = acpiid;
34833512
hid = strsep(&p, ":");
34843513
uid = p;

0 commit comments

Comments
 (0)