When CONFIG_HOTPLUG_CPU=n and cpu_present is less than cpu_possible,
then cpuidle-powernv not passing an explicit drv->cpu_mask allows
generic cpuidle driver to try create sysfs objects for cpus that does
not have cpu_devices created by calling register_cpu().
This caused kernel to access incorrect address and crash. The
following patch series fixes the cpuidle-powernv driver and also adds
additional checks in cpuidle_add_sysfs()
This patch set is against v4.11-rc3.
Changed from v1: Updated commit message and comments.
Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
drv->cpumask defaults to cpu_possible_mask in __cpuidle_driver_init().
On PowerNV platform cpu_present could be less than cpu_possible in cases
where firmware detects the cpu, but it is not available to the OS. When
CONFIG_HOTPLUG_CPU=n, such cpus are not hotplugable at runtime and hence
we skip creating cpu_device.
This breaks cpuidle on powernv where register_cpu() is not called for
cpus in cpu_possible_mask that cannot be hot-added at runtime.
Trying cpuidle_register_device() on cpu without cpu_device will cause
crash like this:
cpu 0xf: Vector: 380 (Data SLB Access) at [c000000ff1503490]
pc: c00000000022c8bc: string+0x34/0x60
lr: c00000000022ed78: vsnprintf+0x284/0x42c
sp: c000000ff1503710
msr: 9000000000009033
dar: 6000000060000000
current = 0xc000000ff1480000
paca = 0xc00000000fe82d00 softe: 0 irq_happened: 0x01
pid = 1, comm = swapper/8
Linux version 4.11.0-rc2 (sv@sagarika) (gcc version 4.9.4
(Buildroot 2017.02-00004-gc28573e) ) #15 SMP Fri Mar 17 19:32:02 IST 2017
enter ? for help
[link register ] c00000000022ed78 vsnprintf+0x284/0x42c
[c000000ff1503710] c00000000022ebb8 vsnprintf+0xc4/0x42c (unreliable)
[c000000ff1503800] c00000000022ef40 vscnprintf+0x20/0x44
[c000000ff1503830] c0000000000ab61c vprintk_emit+0x94/0x2cc
[c000000ff15038a0] c0000000000acc9c vprintk_func+0x60/0x74
[c000000ff15038c0] c000000000619694 printk+0x38/0x4c
[c000000ff15038e0] c000000000224950 kobject_get+0x40/0x60
[c000000ff1503950] c00000000022507c kobject_add_internal+0x60/0x2c4
[c000000ff15039e0] c000000000225350 kobject_init_and_add+0x70/0x78
[c000000ff1503a60] c00000000053c288 cpuidle_add_sysfs+0x9c/0xe0
[c000000ff1503ae0] c00000000053aeac cpuidle_register_device+0xd4/0x12c
[c000000ff1503b30] c00000000053b108 cpuidle_register+0x98/0xcc
[c000000ff1503bc0] c00000000085eaf0 powernv_processor_idle_init+0x140/0x1e0
[c000000ff1503c60] c00000000000cd60 do_one_initcall+0xc0/0x15c
[c000000ff1503d20] c000000000833e84 kernel_init_freeable+0x1a0/0x25c
[c000000ff1503dc0] c00000000000d478 kernel_init+0x24/0x12c
[c000000ff1503e30] c00000000000b564 ret_from_kernel_thread+0x5c/0x78
This patch fixes the bug by passing correct cpumask from
powernv-cpuidle driver.
Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
---
drivers/cpuidle/cpuidle-powernv.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
index a06df51..82f7b33 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -175,6 +175,24 @@ static int powernv_cpuidle_driver_init(void)
drv->state_count += 1;
}
+ /*
+ * On PowerNV platform cpu_present may be less that cpu_possible in
+ * cases where firmware detects the cpu, but it is not available to the
+ * OS. If CONFIG_HOTPLUG_CPU=n then such CPUs are not hotplugable at
+ * runtime and hence cpu_devices are not created for those cpus by
+ * generic topology_init().
+ *
+ * drv->cpumask defaults to cpu_possible_mask in
+ * __cpuidle_driver_init(). This breaks cpuidle on powernv where
+ * cpu_devices are not created for cpus in cpu_possible_mask that
+ * cannot be hot-added later at runtime.
+ *
+ * Trying cpuidle_register_device() on a cpu without cpu_devices is
+ * incorrect. Hence pass correct cpu mask to generic cpuidle driver.
+ */
+
+ drv->cpumask = (struct cpumask *)cpu_present_mask;
+
return 0;
}
--
2.9.3
If a given cpu is not in cpu_present and cpu hotplug
is disabled, arch can skip setting up the cpu_dev.
Arch cpuidle driver should pass correct cpu mask
for registration, but failing to do so by the driver
causes error to propagate and crash like this:
[ 30.076045] Unable to handle kernel paging request for
data at address 0x00000048
[ 30.076100] Faulting instruction address: 0xc0000000007b2f30
cpu 0x4d: Vector: 300 (Data Access) at [c000003feb18b670]
pc: c0000000007b2f30: kobject_get+0x20/0x70
lr: c0000000007b3c94: kobject_add_internal+0x54/0x3f0
sp: c000003feb18b8f0
msr: 9000000000009033
dar: 48
dsisr: 40000000
current = 0xc000003fd2ed8300
paca = 0xc00000000fbab500 softe: 0 irq_happened: 0x01
pid = 1, comm = swapper/0
Linux version 4.11.0-rc2-svaidy+ (sv@sagarika) (gcc version 6.2.0
20161005 (Ubuntu 6.2.0-5ubuntu12) ) #10 SMP Sun Mar 19 00:08:09 IST 2017
enter ? for help
[c000003feb18b960] c0000000007b3c94 kobject_add_internal+0x54/0x3f0
[c000003feb18b9f0] c0000000007b43a4 kobject_init_and_add+0x64/0xa0
[c000003feb18ba70] c000000000e284f4 cpuidle_add_sysfs+0xb4/0x130
[c000003feb18baf0] c000000000e26038 cpuidle_register_device+0x118/0x1c0
[c000003feb18bb30] c000000000e26c48 cpuidle_register+0x78/0x120
[c000003feb18bbc0] c00000000168fd9c powernv_processor_idle_init+0x110/0x1c4
[c000003feb18bc40] c00000000000cff8 do_one_initcall+0x68/0x1d0
[c000003feb18bd00] c0000000016242f4 kernel_init_freeable+0x280/0x360
[c000003feb18bdc0] c00000000000d864 kernel_init+0x24/0x160
[c000003feb18be30] c00000000000b4e8 ret_from_kernel_thread+0x5c/0x74
Validating cpu_dev fixes the crash and reports correct error message like:
[ 30.163506] Failed to register cpuidle device for cpu136
[ 30.173329] Registration of powernv driver failed.
Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
---
drivers/cpuidle/sysfs.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
index c5adc8c..f2c3bce 100644
--- a/drivers/cpuidle/sysfs.c
+++ b/drivers/cpuidle/sysfs.c
@@ -615,6 +615,18 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev)
struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
int error;
+ /*
+ * Return error if cpu_device is not setup for this cpu. This
+ * could happen if arch did not setup cpu_device since this
+ * cpu is not in cpu_present mask and the driver did not send
+ * correct cpu mask at registration. Without this check we
+ * would end up passing bogus value for &cpu_dev->kobj in
+ * kobject_init_and_add().
+ */
+
+ if (!cpu_dev)
+ return -ENODEV;
+
kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
if (!kdev)
return -ENOMEM;
--
2.9.3
On Thu, Mar 23, 2017 at 4:22 PM, Vaidyanathan Srinivasan
<[email protected]> wrote:
> If a given cpu is not in cpu_present and cpu hotplug
> is disabled, arch can skip setting up the cpu_dev.
>
> Arch cpuidle driver should pass correct cpu mask
> for registration, but failing to do so by the driver
> causes error to propagate and crash like this:
>
> [ 30.076045] Unable to handle kernel paging request for
> data at address 0x00000048
> [ 30.076100] Faulting instruction address: 0xc0000000007b2f30
> cpu 0x4d: Vector: 300 (Data Access) at [c000003feb18b670]
> pc: c0000000007b2f30: kobject_get+0x20/0x70
> lr: c0000000007b3c94: kobject_add_internal+0x54/0x3f0
> sp: c000003feb18b8f0
> msr: 9000000000009033
> dar: 48
> dsisr: 40000000
> current = 0xc000003fd2ed8300
> paca = 0xc00000000fbab500 softe: 0 irq_happened: 0x01
> pid = 1, comm = swapper/0
> Linux version 4.11.0-rc2-svaidy+ (sv@sagarika) (gcc version 6.2.0
> 20161005 (Ubuntu 6.2.0-5ubuntu12) ) #10 SMP Sun Mar 19 00:08:09 IST 2017
> enter ? for help
> [c000003feb18b960] c0000000007b3c94 kobject_add_internal+0x54/0x3f0
> [c000003feb18b9f0] c0000000007b43a4 kobject_init_and_add+0x64/0xa0
> [c000003feb18ba70] c000000000e284f4 cpuidle_add_sysfs+0xb4/0x130
> [c000003feb18baf0] c000000000e26038 cpuidle_register_device+0x118/0x1c0
> [c000003feb18bb30] c000000000e26c48 cpuidle_register+0x78/0x120
> [c000003feb18bbc0] c00000000168fd9c powernv_processor_idle_init+0x110/0x1c4
> [c000003feb18bc40] c00000000000cff8 do_one_initcall+0x68/0x1d0
> [c000003feb18bd00] c0000000016242f4 kernel_init_freeable+0x280/0x360
> [c000003feb18bdc0] c00000000000d864 kernel_init+0x24/0x160
> [c000003feb18be30] c00000000000b4e8 ret_from_kernel_thread+0x5c/0x74
>
> Validating cpu_dev fixes the crash and reports correct error message like:
>
> [ 30.163506] Failed to register cpuidle device for cpu136
> [ 30.173329] Registration of powernv driver failed.
>
> Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
The previous version is in linux-next already and I'm going to push it
for merging shortly.
> ---
> drivers/cpuidle/sysfs.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
> index c5adc8c..f2c3bce 100644
> --- a/drivers/cpuidle/sysfs.c
> +++ b/drivers/cpuidle/sysfs.c
> @@ -615,6 +615,18 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev)
> struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
> int error;
>
> + /*
> + * Return error if cpu_device is not setup for this cpu. This
> + * could happen if arch did not setup cpu_device since this
> + * cpu is not in cpu_present mask and the driver did not send
> + * correct cpu mask at registration. Without this check we
> + * would end up passing bogus value for &cpu_dev->kobj in
> + * kobject_init_and_add().
> + */
> +
> + if (!cpu_dev)
> + return -ENODEV;
> +
> kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
> if (!kdev)
> return -ENOMEM;
> --
> 2.9.3
>
On Thu, Mar 23, 2017 at 4:22 PM, Vaidyanathan Srinivasan
<[email protected]> wrote:
> drv->cpumask defaults to cpu_possible_mask in __cpuidle_driver_init().
> On PowerNV platform cpu_present could be less than cpu_possible in cases
> where firmware detects the cpu, but it is not available to the OS. When
> CONFIG_HOTPLUG_CPU=n, such cpus are not hotplugable at runtime and hence
> we skip creating cpu_device.
>
> This breaks cpuidle on powernv where register_cpu() is not called for
> cpus in cpu_possible_mask that cannot be hot-added at runtime.
>
> Trying cpuidle_register_device() on cpu without cpu_device will cause
> crash like this:
>
> cpu 0xf: Vector: 380 (Data SLB Access) at [c000000ff1503490]
> pc: c00000000022c8bc: string+0x34/0x60
> lr: c00000000022ed78: vsnprintf+0x284/0x42c
> sp: c000000ff1503710
> msr: 9000000000009033
> dar: 6000000060000000
> current = 0xc000000ff1480000
> paca = 0xc00000000fe82d00 softe: 0 irq_happened: 0x01
> pid = 1, comm = swapper/8
> Linux version 4.11.0-rc2 (sv@sagarika) (gcc version 4.9.4
> (Buildroot 2017.02-00004-gc28573e) ) #15 SMP Fri Mar 17 19:32:02 IST 2017
> enter ? for help
> [link register ] c00000000022ed78 vsnprintf+0x284/0x42c
> [c000000ff1503710] c00000000022ebb8 vsnprintf+0xc4/0x42c (unreliable)
> [c000000ff1503800] c00000000022ef40 vscnprintf+0x20/0x44
> [c000000ff1503830] c0000000000ab61c vprintk_emit+0x94/0x2cc
> [c000000ff15038a0] c0000000000acc9c vprintk_func+0x60/0x74
> [c000000ff15038c0] c000000000619694 printk+0x38/0x4c
> [c000000ff15038e0] c000000000224950 kobject_get+0x40/0x60
> [c000000ff1503950] c00000000022507c kobject_add_internal+0x60/0x2c4
> [c000000ff15039e0] c000000000225350 kobject_init_and_add+0x70/0x78
> [c000000ff1503a60] c00000000053c288 cpuidle_add_sysfs+0x9c/0xe0
> [c000000ff1503ae0] c00000000053aeac cpuidle_register_device+0xd4/0x12c
> [c000000ff1503b30] c00000000053b108 cpuidle_register+0x98/0xcc
> [c000000ff1503bc0] c00000000085eaf0 powernv_processor_idle_init+0x140/0x1e0
> [c000000ff1503c60] c00000000000cd60 do_one_initcall+0xc0/0x15c
> [c000000ff1503d20] c000000000833e84 kernel_init_freeable+0x1a0/0x25c
> [c000000ff1503dc0] c00000000000d478 kernel_init+0x24/0x12c
> [c000000ff1503e30] c00000000000b564 ret_from_kernel_thread+0x5c/0x78
>
> This patch fixes the bug by passing correct cpumask from
> powernv-cpuidle driver.
>
> Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
That needs to be ACKed by someone familiar with powernv.
> ---
> drivers/cpuidle/cpuidle-powernv.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
> index a06df51..82f7b33 100644
> --- a/drivers/cpuidle/cpuidle-powernv.c
> +++ b/drivers/cpuidle/cpuidle-powernv.c
> @@ -175,6 +175,24 @@ static int powernv_cpuidle_driver_init(void)
> drv->state_count += 1;
> }
>
> + /*
> + * On PowerNV platform cpu_present may be less that cpu_possible in
> + * cases where firmware detects the cpu, but it is not available to the
> + * OS. If CONFIG_HOTPLUG_CPU=n then such CPUs are not hotplugable at
> + * runtime and hence cpu_devices are not created for those cpus by
> + * generic topology_init().
> + *
> + * drv->cpumask defaults to cpu_possible_mask in
> + * __cpuidle_driver_init(). This breaks cpuidle on powernv where
> + * cpu_devices are not created for cpus in cpu_possible_mask that
> + * cannot be hot-added later at runtime.
> + *
> + * Trying cpuidle_register_device() on a cpu without cpu_devices is
> + * incorrect. Hence pass correct cpu mask to generic cpuidle driver.
> + */
> +
> + drv->cpumask = (struct cpumask *)cpu_present_mask;
> +
> return 0;
> }
>
> --
> 2.9.3
>
* Rafael J. Wysocki <[email protected]> [2017-03-23 16:27:31]:
> On Thu, Mar 23, 2017 at 4:22 PM, Vaidyanathan Srinivasan
> <[email protected]> wrote:
> > If a given cpu is not in cpu_present and cpu hotplug
> > is disabled, arch can skip setting up the cpu_dev.
> >
> > Arch cpuidle driver should pass correct cpu mask
> > for registration, but failing to do so by the driver
> > causes error to propagate and crash like this:
> >
> > [ 30.076045] Unable to handle kernel paging request for
> > data at address 0x00000048
> > [ 30.076100] Faulting instruction address: 0xc0000000007b2f30
> > cpu 0x4d: Vector: 300 (Data Access) at [c000003feb18b670]
> > pc: c0000000007b2f30: kobject_get+0x20/0x70
> > lr: c0000000007b3c94: kobject_add_internal+0x54/0x3f0
> > sp: c000003feb18b8f0
> > msr: 9000000000009033
> > dar: 48
> > dsisr: 40000000
> > current = 0xc000003fd2ed8300
> > paca = 0xc00000000fbab500 softe: 0 irq_happened: 0x01
> > pid = 1, comm = swapper/0
> > Linux version 4.11.0-rc2-svaidy+ (sv@sagarika) (gcc version 6.2.0
> > 20161005 (Ubuntu 6.2.0-5ubuntu12) ) #10 SMP Sun Mar 19 00:08:09 IST 2017
> > enter ? for help
> > [c000003feb18b960] c0000000007b3c94 kobject_add_internal+0x54/0x3f0
> > [c000003feb18b9f0] c0000000007b43a4 kobject_init_and_add+0x64/0xa0
> > [c000003feb18ba70] c000000000e284f4 cpuidle_add_sysfs+0xb4/0x130
> > [c000003feb18baf0] c000000000e26038 cpuidle_register_device+0x118/0x1c0
> > [c000003feb18bb30] c000000000e26c48 cpuidle_register+0x78/0x120
> > [c000003feb18bbc0] c00000000168fd9c powernv_processor_idle_init+0x110/0x1c4
> > [c000003feb18bc40] c00000000000cff8 do_one_initcall+0x68/0x1d0
> > [c000003feb18bd00] c0000000016242f4 kernel_init_freeable+0x280/0x360
> > [c000003feb18bdc0] c00000000000d864 kernel_init+0x24/0x160
> > [c000003feb18be30] c00000000000b4e8 ret_from_kernel_thread+0x5c/0x74
> >
> > Validating cpu_dev fixes the crash and reports correct error message like:
> >
> > [ 30.163506] Failed to register cpuidle device for cpu136
> > [ 30.173329] Registration of powernv driver failed.
> >
> > Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
>
> The previous version is in linux-next already and I'm going to push it
> for merging shortly.
Thanks Rafael. The previous version is good for merge.
--Vaidy
* Rafael J. Wysocki <[email protected]> [2017-03-23 16:28:31]:
> On Thu, Mar 23, 2017 at 4:22 PM, Vaidyanathan Srinivasan
> <[email protected]> wrote:
> > drv->cpumask defaults to cpu_possible_mask in __cpuidle_driver_init().
> > On PowerNV platform cpu_present could be less than cpu_possible in cases
> > where firmware detects the cpu, but it is not available to the OS. When
> > CONFIG_HOTPLUG_CPU=n, such cpus are not hotplugable at runtime and hence
> > we skip creating cpu_device.
> >
> > This breaks cpuidle on powernv where register_cpu() is not called for
> > cpus in cpu_possible_mask that cannot be hot-added at runtime.
> >
> > Trying cpuidle_register_device() on cpu without cpu_device will cause
> > crash like this:
> >
> > cpu 0xf: Vector: 380 (Data SLB Access) at [c000000ff1503490]
> > pc: c00000000022c8bc: string+0x34/0x60
> > lr: c00000000022ed78: vsnprintf+0x284/0x42c
> > sp: c000000ff1503710
> > msr: 9000000000009033
> > dar: 6000000060000000
> > current = 0xc000000ff1480000
> > paca = 0xc00000000fe82d00 softe: 0 irq_happened: 0x01
> > pid = 1, comm = swapper/8
> > Linux version 4.11.0-rc2 (sv@sagarika) (gcc version 4.9.4
> > (Buildroot 2017.02-00004-gc28573e) ) #15 SMP Fri Mar 17 19:32:02 IST 2017
> > enter ? for help
> > [link register ] c00000000022ed78 vsnprintf+0x284/0x42c
> > [c000000ff1503710] c00000000022ebb8 vsnprintf+0xc4/0x42c (unreliable)
> > [c000000ff1503800] c00000000022ef40 vscnprintf+0x20/0x44
> > [c000000ff1503830] c0000000000ab61c vprintk_emit+0x94/0x2cc
> > [c000000ff15038a0] c0000000000acc9c vprintk_func+0x60/0x74
> > [c000000ff15038c0] c000000000619694 printk+0x38/0x4c
> > [c000000ff15038e0] c000000000224950 kobject_get+0x40/0x60
> > [c000000ff1503950] c00000000022507c kobject_add_internal+0x60/0x2c4
> > [c000000ff15039e0] c000000000225350 kobject_init_and_add+0x70/0x78
> > [c000000ff1503a60] c00000000053c288 cpuidle_add_sysfs+0x9c/0xe0
> > [c000000ff1503ae0] c00000000053aeac cpuidle_register_device+0xd4/0x12c
> > [c000000ff1503b30] c00000000053b108 cpuidle_register+0x98/0xcc
> > [c000000ff1503bc0] c00000000085eaf0 powernv_processor_idle_init+0x140/0x1e0
> > [c000000ff1503c60] c00000000000cd60 do_one_initcall+0xc0/0x15c
> > [c000000ff1503d20] c000000000833e84 kernel_init_freeable+0x1a0/0x25c
> > [c000000ff1503dc0] c00000000000d478 kernel_init+0x24/0x12c
> > [c000000ff1503e30] c00000000000b564 ret_from_kernel_thread+0x5c/0x78
> >
> > This patch fixes the bug by passing correct cpumask from
> > powernv-cpuidle driver.
> >
> > Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
>
> That needs to be ACKed by someone familiar with powernv.
Previous version at
https://lists.ozlabs.org/pipermail/linuxppc-dev/2017-March/155587.html
I had not CCed linux-pm in the first post.
Michael and Mikey have reviewed the previous version. Let me get an
ack for you to proceed with the merge.
Thanks,
Vaidy
On Thu, Mar 23, 2017 at 8:52 PM, Vaidyanathan Srinivasan
<[email protected]> wrote:
> drv->cpumask defaults to cpu_possible_mask in __cpuidle_driver_init().
> On PowerNV platform cpu_present could be less than cpu_possible in cases
> where firmware detects the cpu, but it is not available to the OS. When
> CONFIG_HOTPLUG_CPU=n, such cpus are not hotplugable at runtime and hence
> we skip creating cpu_device.
>
> This breaks cpuidle on powernv where register_cpu() is not called for
> cpus in cpu_possible_mask that cannot be hot-added at runtime.
>
> Trying cpuidle_register_device() on cpu without cpu_device will cause
> crash like this:
>
> cpu 0xf: Vector: 380 (Data SLB Access) at [c000000ff1503490]
> pc: c00000000022c8bc: string+0x34/0x60
> lr: c00000000022ed78: vsnprintf+0x284/0x42c
> sp: c000000ff1503710
> msr: 9000000000009033
> dar: 6000000060000000
> current = 0xc000000ff1480000
> paca = 0xc00000000fe82d00 softe: 0 irq_happened: 0x01
> pid = 1, comm = swapper/8
> Linux version 4.11.0-rc2 (sv@sagarika) (gcc version 4.9.4
> (Buildroot 2017.02-00004-gc28573e) ) #15 SMP Fri Mar 17 19:32:02 IST 2017
> enter ? for help
> [link register ] c00000000022ed78 vsnprintf+0x284/0x42c
> [c000000ff1503710] c00000000022ebb8 vsnprintf+0xc4/0x42c (unreliable)
> [c000000ff1503800] c00000000022ef40 vscnprintf+0x20/0x44
> [c000000ff1503830] c0000000000ab61c vprintk_emit+0x94/0x2cc
> [c000000ff15038a0] c0000000000acc9c vprintk_func+0x60/0x74
> [c000000ff15038c0] c000000000619694 printk+0x38/0x4c
> [c000000ff15038e0] c000000000224950 kobject_get+0x40/0x60
> [c000000ff1503950] c00000000022507c kobject_add_internal+0x60/0x2c4
> [c000000ff15039e0] c000000000225350 kobject_init_and_add+0x70/0x78
> [c000000ff1503a60] c00000000053c288 cpuidle_add_sysfs+0x9c/0xe0
> [c000000ff1503ae0] c00000000053aeac cpuidle_register_device+0xd4/0x12c
> [c000000ff1503b30] c00000000053b108 cpuidle_register+0x98/0xcc
> [c000000ff1503bc0] c00000000085eaf0 powernv_processor_idle_init+0x140/0x1e0
> [c000000ff1503c60] c00000000000cd60 do_one_initcall+0xc0/0x15c
> [c000000ff1503d20] c000000000833e84 kernel_init_freeable+0x1a0/0x25c
> [c000000ff1503dc0] c00000000000d478 kernel_init+0x24/0x12c
> [c000000ff1503e30] c00000000000b564 ret_from_kernel_thread+0x5c/0x78
>
> This patch fixes the bug by passing correct cpumask from
> powernv-cpuidle driver.
>
> Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
Reviewed-by: Gautham R. Shenoy <[email protected]>
> ---
> drivers/cpuidle/cpuidle-powernv.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
> index a06df51..82f7b33 100644
> --- a/drivers/cpuidle/cpuidle-powernv.c
> +++ b/drivers/cpuidle/cpuidle-powernv.c
> @@ -175,6 +175,24 @@ static int powernv_cpuidle_driver_init(void)
> drv->state_count += 1;
> }
>
> + /*
> + * On PowerNV platform cpu_present may be less that cpu_possible in
> + * cases where firmware detects the cpu, but it is not available to the
> + * OS. If CONFIG_HOTPLUG_CPU=n then such CPUs are not hotplugable at
> + * runtime and hence cpu_devices are not created for those cpus by
> + * generic topology_init().
> + *
> + * drv->cpumask defaults to cpu_possible_mask in
> + * __cpuidle_driver_init(). This breaks cpuidle on powernv where
> + * cpu_devices are not created for cpus in cpu_possible_mask that
> + * cannot be hot-added later at runtime.
> + *
> + * Trying cpuidle_register_device() on a cpu without cpu_devices is
> + * incorrect. Hence pass correct cpu mask to generic cpuidle driver.
> + */
> +
> + drv->cpumask = (struct cpumask *)cpu_present_mask;
> +
> return 0;
> }
>
> --
> 2.9.3
>
--
Thanks and Regards
gautham.
"Rafael J. Wysocki" <[email protected]> writes:
> On Thu, Mar 23, 2017 at 4:22 PM, Vaidyanathan Srinivasan
> <[email protected]> wrote:
>> drv->cpumask defaults to cpu_possible_mask in __cpuidle_driver_init().
>> On PowerNV platform cpu_present could be less than cpu_possible in cases
>> where firmware detects the cpu, but it is not available to the OS. When
>> CONFIG_HOTPLUG_CPU=n, such cpus are not hotplugable at runtime and hence
>> we skip creating cpu_device.
>>
>> This breaks cpuidle on powernv where register_cpu() is not called for
>> cpus in cpu_possible_mask that cannot be hot-added at runtime.
>>
>> Trying cpuidle_register_device() on cpu without cpu_device will cause
>> crash like this:
>>
>> cpu 0xf: Vector: 380 (Data SLB Access) at [c000000ff1503490]
>> pc: c00000000022c8bc: string+0x34/0x60
>> lr: c00000000022ed78: vsnprintf+0x284/0x42c
>> sp: c000000ff1503710
>> msr: 9000000000009033
>> dar: 6000000060000000
>> current = 0xc000000ff1480000
>> paca = 0xc00000000fe82d00 softe: 0 irq_happened: 0x01
>> pid = 1, comm = swapper/8
>> Linux version 4.11.0-rc2 (sv@sagarika) (gcc version 4.9.4
>> (Buildroot 2017.02-00004-gc28573e) ) #15 SMP Fri Mar 17 19:32:02 IST 2017
>> enter ? for help
>> [link register ] c00000000022ed78 vsnprintf+0x284/0x42c
>> [c000000ff1503710] c00000000022ebb8 vsnprintf+0xc4/0x42c (unreliable)
>> [c000000ff1503800] c00000000022ef40 vscnprintf+0x20/0x44
>> [c000000ff1503830] c0000000000ab61c vprintk_emit+0x94/0x2cc
>> [c000000ff15038a0] c0000000000acc9c vprintk_func+0x60/0x74
>> [c000000ff15038c0] c000000000619694 printk+0x38/0x4c
>> [c000000ff15038e0] c000000000224950 kobject_get+0x40/0x60
>> [c000000ff1503950] c00000000022507c kobject_add_internal+0x60/0x2c4
>> [c000000ff15039e0] c000000000225350 kobject_init_and_add+0x70/0x78
>> [c000000ff1503a60] c00000000053c288 cpuidle_add_sysfs+0x9c/0xe0
>> [c000000ff1503ae0] c00000000053aeac cpuidle_register_device+0xd4/0x12c
>> [c000000ff1503b30] c00000000053b108 cpuidle_register+0x98/0xcc
>> [c000000ff1503bc0] c00000000085eaf0 powernv_processor_idle_init+0x140/0x1e0
>> [c000000ff1503c60] c00000000000cd60 do_one_initcall+0xc0/0x15c
>> [c000000ff1503d20] c000000000833e84 kernel_init_freeable+0x1a0/0x25c
>> [c000000ff1503dc0] c00000000000d478 kernel_init+0x24/0x12c
>> [c000000ff1503e30] c00000000000b564 ret_from_kernel_thread+0x5c/0x78
>>
>> This patch fixes the bug by passing correct cpumask from
>> powernv-cpuidle driver.
>>
>> Signed-off-by: Vaidyanathan Srinivasan <[email protected]>
>
> That needs to be ACKed by someone familiar with powernv.
Acked-by: Michael Ellerman <[email protected]>
cheers