Skip to content

Commit 2b0181a

Browse files
committed
Merge branch 'acpi-processor'
Merge ACPI processor driver changes for 6.20-rc1/7.0-rc1: - Rework the ACPI idle driver initialization to register it directly from the common initialization code instead of doing that from a CPU hotplug "online" callback and clean it up (Huisong Li, Rafael Wysocki) - Fix a possible NULL pointer dereference in acpi_processor_errata_piix4() (Tuo Li) * acpi-processor: ACPI: processor: idle: Rework the handling of acpi_processor_ffh_lpi_probe() ACPI: processor: idle: Convert acpi_processor_setup_cpuidle_dev() to void ACPI: processor: idle: Convert acpi_processor_setup_cpuidle_states() to void ACPI: processor: idle: Add debug log for states with invalid entry methods ACPI: processor: Fix NULL-pointer dereference in acpi_processor_errata_piix4() ACPI: processor: Do not expose global variable acpi_idle_driver ACPI: processor: idle: Rearrange declarations in header file ACPI: processor: idle: Redefine two functions as void ACPI: processor: Update cpuidle driver check in __acpi_processor_start() ACPI: processor: Remove unused empty stubs of some functions ACPI: processor: idle: Optimize ACPI idle driver registration
2 parents 1a91d4e + cac173b commit 2b0181a

4 files changed

Lines changed: 124 additions & 109 deletions

File tree

drivers/acpi/acpi_processor.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev)
5050
{
5151
u8 value1 = 0;
5252
u8 value2 = 0;
53+
struct pci_dev *ide_dev = NULL, *isa_dev = NULL;
5354

5455

5556
if (!dev)
@@ -107,12 +108,12 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev)
107108
* each IDE controller's DMA status to make sure we catch all
108109
* DMA activity.
109110
*/
110-
dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
111+
ide_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
111112
PCI_DEVICE_ID_INTEL_82371AB,
112113
PCI_ANY_ID, PCI_ANY_ID, NULL);
113-
if (dev) {
114-
errata.piix4.bmisx = pci_resource_start(dev, 4);
115-
pci_dev_put(dev);
114+
if (ide_dev) {
115+
errata.piix4.bmisx = pci_resource_start(ide_dev, 4);
116+
pci_dev_put(ide_dev);
116117
}
117118

118119
/*
@@ -124,24 +125,25 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev)
124125
* disable C3 support if this is enabled, as some legacy
125126
* devices won't operate well if fast DMA is disabled.
126127
*/
127-
dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
128+
isa_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
128129
PCI_DEVICE_ID_INTEL_82371AB_0,
129130
PCI_ANY_ID, PCI_ANY_ID, NULL);
130-
if (dev) {
131-
pci_read_config_byte(dev, 0x76, &value1);
132-
pci_read_config_byte(dev, 0x77, &value2);
131+
if (isa_dev) {
132+
pci_read_config_byte(isa_dev, 0x76, &value1);
133+
pci_read_config_byte(isa_dev, 0x77, &value2);
133134
if ((value1 & 0x80) || (value2 & 0x80))
134135
errata.piix4.fdma = 1;
135-
pci_dev_put(dev);
136+
pci_dev_put(isa_dev);
136137
}
137138

138139
break;
139140
}
140141

141-
if (errata.piix4.bmisx)
142-
dev_dbg(&dev->dev, "Bus master activity detection (BM-IDE) erratum enabled\n");
143-
if (errata.piix4.fdma)
144-
dev_dbg(&dev->dev, "Type-F DMA livelock erratum (C3 disabled)\n");
142+
if (ide_dev)
143+
dev_dbg(&ide_dev->dev, "Bus master activity detection (BM-IDE) erratum enabled\n");
144+
145+
if (isa_dev)
146+
dev_dbg(&isa_dev->dev, "Type-F DMA livelock erratum (C3 disabled)\n");
145147

146148
return 0;
147149
}

drivers/acpi/processor_driver.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,7 @@ static int __acpi_processor_start(struct acpi_device *device)
166166
if (result && !IS_ENABLED(CONFIG_ACPI_CPU_FREQ_PSS))
167167
dev_dbg(&device->dev, "CPPC data invalid or not present\n");
168168

169-
if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
170-
acpi_processor_power_init(pr);
169+
acpi_processor_power_init(pr);
171170

172171
acpi_pss_perf_init(pr);
173172

@@ -259,9 +258,11 @@ static int __init acpi_processor_driver_init(void)
259258
acpi_processor_ignore_ppc_init();
260259
}
261260

261+
acpi_processor_register_idle_driver();
262+
262263
result = driver_register(&acpi_processor_driver);
263264
if (result < 0)
264-
return result;
265+
goto unregister_idle_drv;
265266

266267
result = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
267268
"acpi/cpu-drv:online",
@@ -283,8 +284,13 @@ static int __init acpi_processor_driver_init(void)
283284
acpi_idle_rescan_dead_smt_siblings();
284285

285286
return 0;
287+
286288
err:
287289
driver_unregister(&acpi_processor_driver);
290+
291+
unregister_idle_drv:
292+
acpi_processor_unregister_idle_driver();
293+
288294
return result;
289295
}
290296

@@ -302,6 +308,7 @@ static void __exit acpi_processor_driver_exit(void)
302308
cpuhp_remove_state_nocalls(hp_online);
303309
cpuhp_remove_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD);
304310
driver_unregister(&acpi_processor_driver);
311+
acpi_processor_unregister_idle_driver();
305312
}
306313

307314
module_init(acpi_processor_driver_init);

drivers/acpi/processor_idle.c

Lines changed: 93 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ module_param(latency_factor, uint, 0644);
5151

5252
static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device);
5353

54-
struct cpuidle_driver acpi_idle_driver = {
54+
static struct cpuidle_driver acpi_idle_driver = {
5555
.name = "acpi_idle",
5656
.owner = THIS_MODULE,
5757
};
@@ -946,6 +946,8 @@ static int acpi_processor_evaluate_lpi(acpi_handle handle,
946946
lpi_state->entry_method = ACPI_CSTATE_INTEGER;
947947
lpi_state->address = obj->integer.value;
948948
} else {
949+
pr_debug("Entry method of state-%d is invalid, disable it.\n",
950+
state_idx);
949951
continue;
950952
}
951953

@@ -1178,15 +1180,15 @@ static int acpi_idle_lpi_enter(struct cpuidle_device *dev,
11781180
return -EINVAL;
11791181
}
11801182

1181-
static int acpi_processor_setup_lpi_states(struct acpi_processor *pr)
1183+
static void acpi_processor_setup_lpi_states(struct acpi_processor *pr)
11821184
{
11831185
int i;
11841186
struct acpi_lpi_state *lpi;
11851187
struct cpuidle_state *state;
11861188
struct cpuidle_driver *drv = &acpi_idle_driver;
11871189

11881190
if (!pr->flags.has_lpi)
1189-
return -EOPNOTSUPP;
1191+
return;
11901192

11911193
for (i = 0; i < pr->power.count && i < CPUIDLE_STATE_MAX; i++) {
11921194
lpi = &pr->power.lpi_states[i];
@@ -1204,8 +1206,6 @@ static int acpi_processor_setup_lpi_states(struct acpi_processor *pr)
12041206
}
12051207

12061208
drv->state_count = i;
1207-
1208-
return 0;
12091209
}
12101210

12111211
/**
@@ -1214,46 +1214,44 @@ static int acpi_processor_setup_lpi_states(struct acpi_processor *pr)
12141214
*
12151215
* @pr: the ACPI processor
12161216
*/
1217-
static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
1217+
static void acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
12181218
{
12191219
int i;
12201220
struct cpuidle_driver *drv = &acpi_idle_driver;
12211221

12221222
if (!pr->flags.power_setup_done || !pr->flags.power)
1223-
return -EINVAL;
1223+
return;
12241224

12251225
drv->safe_state_index = -1;
12261226
for (i = ACPI_IDLE_STATE_START; i < CPUIDLE_STATE_MAX; i++) {
12271227
drv->states[i].name[0] = '\0';
12281228
drv->states[i].desc[0] = '\0';
12291229
}
12301230

1231-
if (pr->flags.has_lpi)
1232-
return acpi_processor_setup_lpi_states(pr);
1231+
if (pr->flags.has_lpi) {
1232+
acpi_processor_setup_lpi_states(pr);
1233+
return;
1234+
}
12331235

12341236
acpi_processor_setup_cstates(pr);
1235-
return 0;
12361237
}
12371238

12381239
/**
1239-
* acpi_processor_setup_cpuidle_dev - prepares and configures CPUIDLE
1240+
* acpi_processor_setup_cpuidle_dev - configures CPUIDLE
12401241
* device i.e. per-cpu data
12411242
*
12421243
* @pr: the ACPI processor
12431244
* @dev : the cpuidle device
12441245
*/
1245-
static int acpi_processor_setup_cpuidle_dev(struct acpi_processor *pr,
1246-
struct cpuidle_device *dev)
1246+
static void acpi_processor_setup_cpuidle_dev(struct acpi_processor *pr,
1247+
struct cpuidle_device *dev)
12471248
{
12481249
if (!pr->flags.power_setup_done || !pr->flags.power || !dev)
1249-
return -EINVAL;
1250+
return;
12501251

12511252
dev->cpu = pr->id;
1252-
if (pr->flags.has_lpi)
1253-
return acpi_processor_ffh_lpi_probe(pr->id);
1254-
1255-
acpi_processor_setup_cpuidle_cx(pr, dev);
1256-
return 0;
1253+
if (!pr->flags.has_lpi)
1254+
acpi_processor_setup_cpuidle_cx(pr, dev);
12571255
}
12581256

12591257
static int acpi_processor_get_power_info(struct acpi_processor *pr)
@@ -1262,7 +1260,13 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
12621260

12631261
ret = acpi_processor_get_lpi_info(pr);
12641262
if (ret)
1265-
ret = acpi_processor_get_cstate_info(pr);
1263+
return acpi_processor_get_cstate_info(pr);
1264+
1265+
if (pr->flags.has_lpi) {
1266+
ret = acpi_processor_ffh_lpi_probe(pr->id);
1267+
if (ret)
1268+
pr_err("CPU%u: Invalid FFH LPI data\n", pr->id);
1269+
}
12661270

12671271
return ret;
12681272
}
@@ -1347,79 +1351,103 @@ int acpi_processor_power_state_has_changed(struct acpi_processor *pr)
13471351
return 0;
13481352
}
13491353

1350-
static int acpi_processor_registered;
1354+
void acpi_processor_register_idle_driver(void)
1355+
{
1356+
struct acpi_processor *pr;
1357+
int ret = -ENODEV;
1358+
int cpu;
1359+
1360+
/*
1361+
* ACPI idle driver is used by all possible CPUs.
1362+
* Use the processor power info of one in them to set up idle states.
1363+
* Note that the existing idle handler will be used on platforms that
1364+
* only support C1.
1365+
*/
1366+
for_each_possible_cpu(cpu) {
1367+
pr = per_cpu(processors, cpu);
1368+
if (!pr)
1369+
continue;
1370+
1371+
acpi_processor_cstate_first_run_checks();
1372+
ret = acpi_processor_get_power_info(pr);
1373+
if (!ret) {
1374+
pr->flags.power_setup_done = 1;
1375+
acpi_processor_setup_cpuidle_states(pr);
1376+
break;
1377+
}
1378+
}
1379+
1380+
if (ret) {
1381+
pr_debug("No ACPI power information from any CPUs.\n");
1382+
return;
1383+
}
13511384

1352-
int acpi_processor_power_init(struct acpi_processor *pr)
1385+
ret = cpuidle_register_driver(&acpi_idle_driver);
1386+
if (ret) {
1387+
pr_debug("register %s failed.\n", acpi_idle_driver.name);
1388+
return;
1389+
}
1390+
pr_debug("%s registered with cpuidle.\n", acpi_idle_driver.name);
1391+
}
1392+
1393+
void acpi_processor_unregister_idle_driver(void)
1394+
{
1395+
cpuidle_unregister_driver(&acpi_idle_driver);
1396+
}
1397+
1398+
void acpi_processor_power_init(struct acpi_processor *pr)
13531399
{
1354-
int retval;
13551400
struct cpuidle_device *dev;
13561401

1402+
/*
1403+
* The code below only works if the current cpuidle driver is the ACPI
1404+
* idle driver.
1405+
*/
1406+
if (cpuidle_get_driver() != &acpi_idle_driver)
1407+
return;
1408+
13571409
if (disabled_by_idle_boot_param())
1358-
return 0;
1410+
return;
13591411

13601412
acpi_processor_cstate_first_run_checks();
13611413

13621414
if (!acpi_processor_get_power_info(pr))
13631415
pr->flags.power_setup_done = 1;
13641416

1365-
/*
1366-
* Install the idle handler if processor power management is supported.
1367-
* Note that we use previously set idle handler will be used on
1368-
* platforms that only support C1.
1369-
*/
1370-
if (pr->flags.power) {
1371-
/* Register acpi_idle_driver if not already registered */
1372-
if (!acpi_processor_registered) {
1373-
acpi_processor_setup_cpuidle_states(pr);
1374-
retval = cpuidle_register_driver(&acpi_idle_driver);
1375-
if (retval)
1376-
return retval;
1377-
pr_debug("%s registered with cpuidle\n",
1378-
acpi_idle_driver.name);
1379-
}
1417+
if (!pr->flags.power)
1418+
return;
1419+
1420+
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1421+
if (!dev)
1422+
return;
13801423

1381-
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1382-
if (!dev)
1383-
return -ENOMEM;
1384-
per_cpu(acpi_cpuidle_device, pr->id) = dev;
1424+
per_cpu(acpi_cpuidle_device, pr->id) = dev;
13851425

1386-
acpi_processor_setup_cpuidle_dev(pr, dev);
1426+
acpi_processor_setup_cpuidle_dev(pr, dev);
13871427

1388-
/* Register per-cpu cpuidle_device. Cpuidle driver
1389-
* must already be registered before registering device
1390-
*/
1391-
retval = cpuidle_register_device(dev);
1392-
if (retval) {
1393-
if (acpi_processor_registered == 0)
1394-
cpuidle_unregister_driver(&acpi_idle_driver);
1395-
1396-
per_cpu(acpi_cpuidle_device, pr->id) = NULL;
1397-
kfree(dev);
1398-
return retval;
1399-
}
1400-
acpi_processor_registered++;
1428+
/*
1429+
* Register a cpuidle device for this CPU. The cpuidle driver using
1430+
* this device is expected to be registered.
1431+
*/
1432+
if (cpuidle_register_device(dev)) {
1433+
per_cpu(acpi_cpuidle_device, pr->id) = NULL;
1434+
kfree(dev);
14011435
}
1402-
return 0;
14031436
}
14041437

1405-
int acpi_processor_power_exit(struct acpi_processor *pr)
1438+
void acpi_processor_power_exit(struct acpi_processor *pr)
14061439
{
14071440
struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id);
14081441

14091442
if (disabled_by_idle_boot_param())
1410-
return 0;
1443+
return;
14111444

14121445
if (pr->flags.power) {
14131446
cpuidle_unregister_device(dev);
1414-
acpi_processor_registered--;
1415-
if (acpi_processor_registered == 0)
1416-
cpuidle_unregister_driver(&acpi_idle_driver);
1417-
14181447
kfree(dev);
14191448
}
14201449

14211450
pr->flags.power_setup_done = 0;
1422-
return 0;
14231451
}
14241452

14251453
MODULE_IMPORT_NS("ACPI_PROCESSOR_IDLE");

0 commit comments

Comments
 (0)