Control Flow Integrity(CFI) is a security mechanism that disallows changes to the original control flow graph of a compiled binary, making it significantly harder to perform such attacks. init_state_node() assign same function callback to different function pointer declarations. static int init_state_node(struct cpuidle_state *idle_state, const struct of_device_id *matches, struct device_node *state_node) { ... idle_state->enter = match_id->data; ... idle_state->enter_s2idle = match_id->data; } Function declarations: struct cpuidle_state { ... int (*enter) (struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); void (*enter_s2idle) (struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); }; In this case, either enter() or enter_s2idle() would cause CFI check failed since they use same callee. Align function prototype of enter() since it needs return value for some use cases. The return value of enter_s2idle() is no need currently.
Unified · Split
| @@ -655,8 +655,8 @@ static int acpi_idle_enter(struct cpuidle_device *dev, · 654 unmodified lines | |||
| 655 | return index; | 655 | return index; |
| 656 | } | 656 | } |
| 657 | 657 | ||
| 658 | static void acpi_idle_enter_s2idle(struct cpuidle_device *dev, | 658 | static int acpi_idle_enter_s2idle(struct cpuidle_device *dev, |
| 659 | struct cpuidle_driver *drv, int index) | 659 | struct cpuidle_driver *drv, int index) |
| 660 | { | 660 | { |
| 661 | struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); | 661 | struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); |
| 662 | 662 | ||
| @@ -674,6 +674,8 @@ static void acpi_idle_enter_s2idle(struct cpuidle_device *dev, · 11 unmodified lines | |||
| 674 | } | 674 | } |
| 675 | } | 675 | } |
| 676 | acpi_idle_do_entry(cx); | 676 | acpi_idle_do_entry(cx); |
| 677 | |||
| 678 | return 0; | ||
| 677 | } | 679 | } |
| 678 | 680 | ||
| 679 | static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, | 681 | static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, |
| @@ -253,11 +253,13 @@ static int tegra_cpuidle_enter(struct cpuidle_device *dev, · 252 unmodified lines | |||
| 253 | return err ? -1 : index; | 253 | return err ? -1 : index; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | static void tegra114_enter_s2idle(struct cpuidle_device *dev, | 256 | static int tegra114_enter_s2idle(struct cpuidle_device *dev, |
| 257 | struct cpuidle_driver *drv, | 257 | struct cpuidle_driver *drv, |
| 258 | int index) | 258 | int index) |
| 259 | { | 259 | { |
| 260 | tegra_cpuidle_enter(dev, drv, index); | 260 | tegra_cpuidle_enter(dev, drv, index); |
| 261 | |||
| 262 | return 0; | ||
| 261 | } | 263 | } |
| 262 | 264 | ||
| 263 | /* | 265 | /* |
| @@ -173,13 +173,15 @@ static __cpuidle int intel_idle(struct cpuidle_device *dev, · 172 unmodified lines | |||
| 173 | * Invoked as a suspend-to-idle callback routine with frozen user space, frozen | 173 | * Invoked as a suspend-to-idle callback routine with frozen user space, frozen |
| 174 | * scheduler tick and suspended scheduler clock on the target CPU. | 174 | * scheduler tick and suspended scheduler clock on the target CPU. |
| 175 | */ | 175 | */ |
| 176 | static __cpuidle void intel_idle_s2idle(struct cpuidle_device *dev, | 176 | static __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev, |
| 177 | struct cpuidle_driver *drv, int index) | 177 | struct cpuidle_driver *drv, int index) |
| 178 | { | 178 | { |
| 179 | unsigned long eax = flg2MWAIT(drv->states[index].flags); | 179 | unsigned long eax = flg2MWAIT(drv->states[index].flags); |
| 180 | unsigned long ecx = 1; /* break on interrupt flag */ | 180 | unsigned long ecx = 1; /* break on interrupt flag */ |
| 181 | 181 | ||
| 182 | mwait_idle_with_hints(eax, ecx); | 182 | mwait_idle_with_hints(eax, ecx); |
| 183 | |||
| 184 | return 0; | ||
| 183 | } | 185 | } |
| 184 | 186 | ||
| 185 | /* | 187 | /* |
| @@ -65,10 +65,13 @@ struct cpuidle_state { · 64 unmodified lines | |||
| 65 | * CPUs execute ->enter_s2idle with the local tick or entire timekeeping | 65 | * CPUs execute ->enter_s2idle with the local tick or entire timekeeping |
| 66 | * suspended, so it must not re-enable interrupts at any point (even | 66 | * suspended, so it must not re-enable interrupts at any point (even |
| 67 | * temporarily) or attempt to change states of clock event devices. | 67 | * temporarily) or attempt to change states of clock event devices. |
| 68 | * | ||
| 69 | * This callback may point to the same function as ->enter if all of | ||
| 70 | * the above requirements are met by it. | ||
| 68 | */ | 71 | */ |
| 69 | void (*enter_s2idle) (struct cpuidle_device *dev, | 72 | int (*enter_s2idle)(struct cpuidle_device *dev, |
| 70 | struct cpuidle_driver *drv, | 73 | struct cpuidle_driver *drv, |
| 71 | int index); | 74 | int index); |
| 72 | }; | 75 | }; |
| 73 | 76 | ||
| 74 | /* Idle State Flags */ | 77 | /* Idle State Flags */ |