2021-11-09 11:16:23

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 4.4 15/30] ACPICA: Avoid evaluating methods too early during system resume

From: "Rafael J. Wysocki" <[email protected]>

[ Upstream commit d3c4b6f64ad356c0d9ddbcf73fa471e6a841cc5c ]

ACPICA commit 0762982923f95eb652cf7ded27356b247c9774de

During wakeup from system-wide sleep states, acpi_get_sleep_type_data()
is called and it tries to get memory from the slab allocator in order
to evaluate a control method, but if KFENCE is enabled in the kernel,
the memory allocation attempt causes an IRQ work to be queued and a
self-IPI to be sent to the CPU running the code which requires the
memory controller to be ready, so if that happens too early in the
wakeup path, it doesn't work.

Prevent that from taking place by calling acpi_get_sleep_type_data()
for S0 upfront, when preparing to enter a given sleep state, and
saving the data obtained by it for later use during system wakeup.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214271
Reported-by: Reik Keutterling <[email protected]>
Tested-by: Reik Keutterling <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/acpi/acpica/acglobal.h | 2 ++
drivers/acpi/acpica/hwesleep.c | 8 ++------
drivers/acpi/acpica/hwsleep.c | 11 ++++-------
drivers/acpi/acpica/hwxfsleep.c | 7 +++++++
4 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index faa97604d878e..f178d11597c09 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -256,6 +256,8 @@ extern struct acpi_bit_register_info

ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a);
ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b);
+ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a_s0);
+ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b_s0);

/*****************************************************************************
*
diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c
index e5599f6108083..e4998cc0ce283 100644
--- a/drivers/acpi/acpica/hwesleep.c
+++ b/drivers/acpi/acpica/hwesleep.c
@@ -184,17 +184,13 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)

acpi_status acpi_hw_extended_wake_prep(u8 sleep_state)
{
- acpi_status status;
u8 sleep_type_value;

ACPI_FUNCTION_TRACE(hw_extended_wake_prep);

- status = acpi_get_sleep_type_data(ACPI_STATE_S0,
- &acpi_gbl_sleep_type_a,
- &acpi_gbl_sleep_type_b);
- if (ACPI_SUCCESS(status)) {
+ if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
sleep_type_value =
- ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
+ ((acpi_gbl_sleep_type_a_s0 << ACPI_X_SLEEP_TYPE_POSITION) &
ACPI_X_SLEEP_TYPE_MASK);

(void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE),
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index 7d21cae6d6028..7e44ba8c6a1ab 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -217,7 +217,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)

acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
{
- acpi_status status;
+ acpi_status status = AE_OK;
struct acpi_bit_register_info *sleep_type_reg_info;
struct acpi_bit_register_info *sleep_enable_reg_info;
u32 pm1a_control;
@@ -230,10 +230,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
* This is unclear from the ACPI Spec, but it is required
* by some machines.
*/
- status = acpi_get_sleep_type_data(ACPI_STATE_S0,
- &acpi_gbl_sleep_type_a,
- &acpi_gbl_sleep_type_b);
- if (ACPI_SUCCESS(status)) {
+ if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
sleep_type_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
@@ -254,9 +251,9 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)

/* Insert the SLP_TYP bits */

- pm1a_control |= (acpi_gbl_sleep_type_a <<
+ pm1a_control |= (acpi_gbl_sleep_type_a_s0 <<
sleep_type_reg_info->bit_position);
- pm1b_control |= (acpi_gbl_sleep_type_b <<
+ pm1b_control |= (acpi_gbl_sleep_type_b_s0 <<
sleep_type_reg_info->bit_position);

/* Write the control registers and ignore any errors */
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c
index d62a61612b3f1..b04e2b0f62246 100644
--- a/drivers/acpi/acpica/hwxfsleep.c
+++ b/drivers/acpi/acpica/hwxfsleep.c
@@ -372,6 +372,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
return_ACPI_STATUS(status);
}

+ status = acpi_get_sleep_type_data(ACPI_STATE_S0,
+ &acpi_gbl_sleep_type_a_s0,
+ &acpi_gbl_sleep_type_b_s0);
+ if (ACPI_FAILURE(status)) {
+ acpi_gbl_sleep_type_a_s0 = ACPI_SLEEP_TYPE_INVALID;
+ }
+
/* Execute the _PTS method (Prepare To Sleep) */

arg_list.count = 1;
--
2.33.0


2021-11-10 15:14:35

by Moore, Robert

[permalink] [raw]
Subject: RE: [PATCH AUTOSEL 4.4 15/30] ACPICA: Avoid evaluating methods too early during system resume

Sasha,
Can you re-do this patch in native ACPICA format, then add a pull request to our github?

Thanks,
Bob


-----Original Message-----
From: Sasha Levin <[email protected]>
Sent: Monday, November 08, 2021 5:09 PM
To: [email protected]; [email protected]
Cc: Wysocki, Rafael J <[email protected]>; Reik Keutterling <[email protected]>; Sasha Levin <[email protected]>; Moore, Robert <[email protected]>; [email protected]; [email protected]
Subject: [PATCH AUTOSEL 4.4 15/30] ACPICA: Avoid evaluating methods too early during system resume

From: "Rafael J. Wysocki" <[email protected]>

[ Upstream commit d3c4b6f64ad356c0d9ddbcf73fa471e6a841cc5c ]

ACPICA commit 0762982923f95eb652cf7ded27356b247c9774de

During wakeup from system-wide sleep states, acpi_get_sleep_type_data() is called and it tries to get memory from the slab allocator in order to evaluate a control method, but if KFENCE is enabled in the kernel, the memory allocation attempt causes an IRQ work to be queued and a self-IPI to be sent to the CPU running the code which requires the memory controller to be ready, so if that happens too early in the wakeup path, it doesn't work.

Prevent that from taking place by calling acpi_get_sleep_type_data() for S0 upfront, when preparing to enter a given sleep state, and saving the data obtained by it for later use during system wakeup.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214271
Reported-by: Reik Keutterling <[email protected]>
Tested-by: Reik Keutterling <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/acpi/acpica/acglobal.h | 2 ++ drivers/acpi/acpica/hwesleep.c | 8 ++------
drivers/acpi/acpica/hwsleep.c | 11 ++++-------
drivers/acpi/acpica/hwxfsleep.c | 7 +++++++
4 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index faa97604d878e..f178d11597c09 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -256,6 +256,8 @@ extern struct acpi_bit_register_info

ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a); ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b);
+ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a_s0); ACPI_GLOBAL(u8,
+acpi_gbl_sleep_type_b_s0);

/*****************************************************************************
*
diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index e5599f6108083..e4998cc0ce283 100644
--- a/drivers/acpi/acpica/hwesleep.c
+++ b/drivers/acpi/acpica/hwesleep.c
@@ -184,17 +184,13 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)

acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) {
- acpi_status status;
u8 sleep_type_value;

ACPI_FUNCTION_TRACE(hw_extended_wake_prep);

- status = acpi_get_sleep_type_data(ACPI_STATE_S0,
- &acpi_gbl_sleep_type_a,
- &acpi_gbl_sleep_type_b);
- if (ACPI_SUCCESS(status)) {
+ if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
sleep_type_value =
- ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
+ ((acpi_gbl_sleep_type_a_s0 << ACPI_X_SLEEP_TYPE_POSITION) &
ACPI_X_SLEEP_TYPE_MASK);

(void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE), diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 7d21cae6d6028..7e44ba8c6a1ab 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -217,7 +217,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)

acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) {
- acpi_status status;
+ acpi_status status = AE_OK;
struct acpi_bit_register_info *sleep_type_reg_info;
struct acpi_bit_register_info *sleep_enable_reg_info;
u32 pm1a_control;
@@ -230,10 +230,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
* This is unclear from the ACPI Spec, but it is required
* by some machines.
*/
- status = acpi_get_sleep_type_data(ACPI_STATE_S0,
- &acpi_gbl_sleep_type_a,
- &acpi_gbl_sleep_type_b);
- if (ACPI_SUCCESS(status)) {
+ if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
sleep_type_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
@@ -254,9 +251,9 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)

/* Insert the SLP_TYP bits */

- pm1a_control |= (acpi_gbl_sleep_type_a <<
+ pm1a_control |= (acpi_gbl_sleep_type_a_s0 <<
sleep_type_reg_info->bit_position);
- pm1b_control |= (acpi_gbl_sleep_type_b <<
+ pm1b_control |= (acpi_gbl_sleep_type_b_s0 <<
sleep_type_reg_info->bit_position);

/* Write the control registers and ignore any errors */ diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index d62a61612b3f1..b04e2b0f62246 100644
--- a/drivers/acpi/acpica/hwxfsleep.c
+++ b/drivers/acpi/acpica/hwxfsleep.c
@@ -372,6 +372,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
return_ACPI_STATUS(status);
}

+ status = acpi_get_sleep_type_data(ACPI_STATE_S0,
+ &acpi_gbl_sleep_type_a_s0,
+ &acpi_gbl_sleep_type_b_s0);
+ if (ACPI_FAILURE(status)) {
+ acpi_gbl_sleep_type_a_s0 = ACPI_SLEEP_TYPE_INVALID;
+ }
+
/* Execute the _PTS method (Prepare To Sleep) */

arg_list.count = 1;
--
2.33.0

2021-11-10 15:22:18

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 4.4 15/30] ACPICA: Avoid evaluating methods too early during system resume

Hi Bob,

This is the Linux version of ACPICA commit
0762982923f95eb652cf7ded27356b247c9774de and now it has been
automatically selected for backporting into the "stable" kernel
versions.

On Wed, Nov 10, 2021 at 4:10 PM Moore, Robert <[email protected]> wrote:
>
> Sasha,
> Can you re-do this patch in native ACPICA format, then add a pull request to our github?
>
> Thanks,
> Bob
>
>
> -----Original Message-----
> From: Sasha Levin <[email protected]>
> Sent: Monday, November 08, 2021 5:09 PM
> To: [email protected]; [email protected]
> Cc: Wysocki, Rafael J <[email protected]>; Reik Keutterling <[email protected]>; Sasha Levin <[email protected]>; Moore, Robert <[email protected]>; [email protected]; [email protected]
> Subject: [PATCH AUTOSEL 4.4 15/30] ACPICA: Avoid evaluating methods too early during system resume
>
> From: "Rafael J. Wysocki" <[email protected]>
>
> [ Upstream commit d3c4b6f64ad356c0d9ddbcf73fa471e6a841cc5c ]
>
> ACPICA commit 0762982923f95eb652cf7ded27356b247c9774de
>
> During wakeup from system-wide sleep states, acpi_get_sleep_type_data() is called and it tries to get memory from the slab allocator in order to evaluate a control method, but if KFENCE is enabled in the kernel, the memory allocation attempt causes an IRQ work to be queued and a self-IPI to be sent to the CPU running the code which requires the memory controller to be ready, so if that happens too early in the wakeup path, it doesn't work.
>
> Prevent that from taking place by calling acpi_get_sleep_type_data() for S0 upfront, when preparing to enter a given sleep state, and saving the data obtained by it for later use during system wakeup.
>
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214271
> Reported-by: Reik Keutterling <[email protected]>
> Tested-by: Reik Keutterling <[email protected]>
> Signed-off-by: Rafael J. Wysocki <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---
> drivers/acpi/acpica/acglobal.h | 2 ++ drivers/acpi/acpica/hwesleep.c | 8 ++------
> drivers/acpi/acpica/hwsleep.c | 11 ++++-------
> drivers/acpi/acpica/hwxfsleep.c | 7 +++++++
> 4 files changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index faa97604d878e..f178d11597c09 100644
> --- a/drivers/acpi/acpica/acglobal.h
> +++ b/drivers/acpi/acpica/acglobal.h
> @@ -256,6 +256,8 @@ extern struct acpi_bit_register_info
>
> ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a); ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b);
> +ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a_s0); ACPI_GLOBAL(u8,
> +acpi_gbl_sleep_type_b_s0);
>
> /*****************************************************************************
> *
> diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index e5599f6108083..e4998cc0ce283 100644
> --- a/drivers/acpi/acpica/hwesleep.c
> +++ b/drivers/acpi/acpica/hwesleep.c
> @@ -184,17 +184,13 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)
>
> acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) {
> - acpi_status status;
> u8 sleep_type_value;
>
> ACPI_FUNCTION_TRACE(hw_extended_wake_prep);
>
> - status = acpi_get_sleep_type_data(ACPI_STATE_S0,
> - &acpi_gbl_sleep_type_a,
> - &acpi_gbl_sleep_type_b);
> - if (ACPI_SUCCESS(status)) {
> + if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
> sleep_type_value =
> - ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
> + ((acpi_gbl_sleep_type_a_s0 << ACPI_X_SLEEP_TYPE_POSITION) &
> ACPI_X_SLEEP_TYPE_MASK);
>
> (void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE), diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 7d21cae6d6028..7e44ba8c6a1ab 100644
> --- a/drivers/acpi/acpica/hwsleep.c
> +++ b/drivers/acpi/acpica/hwsleep.c
> @@ -217,7 +217,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
>
> acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) {
> - acpi_status status;
> + acpi_status status = AE_OK;
> struct acpi_bit_register_info *sleep_type_reg_info;
> struct acpi_bit_register_info *sleep_enable_reg_info;
> u32 pm1a_control;
> @@ -230,10 +230,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
> * This is unclear from the ACPI Spec, but it is required
> * by some machines.
> */
> - status = acpi_get_sleep_type_data(ACPI_STATE_S0,
> - &acpi_gbl_sleep_type_a,
> - &acpi_gbl_sleep_type_b);
> - if (ACPI_SUCCESS(status)) {
> + if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
> sleep_type_reg_info =
> acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
> sleep_enable_reg_info =
> @@ -254,9 +251,9 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
>
> /* Insert the SLP_TYP bits */
>
> - pm1a_control |= (acpi_gbl_sleep_type_a <<
> + pm1a_control |= (acpi_gbl_sleep_type_a_s0 <<
> sleep_type_reg_info->bit_position);
> - pm1b_control |= (acpi_gbl_sleep_type_b <<
> + pm1b_control |= (acpi_gbl_sleep_type_b_s0 <<
> sleep_type_reg_info->bit_position);
>
> /* Write the control registers and ignore any errors */ diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index d62a61612b3f1..b04e2b0f62246 100644
> --- a/drivers/acpi/acpica/hwxfsleep.c
> +++ b/drivers/acpi/acpica/hwxfsleep.c
> @@ -372,6 +372,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
> return_ACPI_STATUS(status);
> }
>
> + status = acpi_get_sleep_type_data(ACPI_STATE_S0,
> + &acpi_gbl_sleep_type_a_s0,
> + &acpi_gbl_sleep_type_b_s0);
> + if (ACPI_FAILURE(status)) {
> + acpi_gbl_sleep_type_a_s0 = ACPI_SLEEP_TYPE_INVALID;
> + }
> +
> /* Execute the _PTS method (Prepare To Sleep) */
>
> arg_list.count = 1;
> --
> 2.33.0
>

2021-11-10 15:52:21

by Moore, Robert

[permalink] [raw]
Subject: RE: [PATCH AUTOSEL 4.4 15/30] ACPICA: Avoid evaluating methods too early during system resume

OK, thanks.
Bob


-----Original Message-----
From: Rafael J. Wysocki <[email protected]>
Sent: Wednesday, November 10, 2021 7:19 AM
To: Moore, Robert <[email protected]>
Cc: Sasha Levin <[email protected]>; [email protected]; [email protected]; Wysocki, Rafael J <[email protected]>; Reik Keutterling <[email protected]>; [email protected]; [email protected]
Subject: Re: [PATCH AUTOSEL 4.4 15/30] ACPICA: Avoid evaluating methods too early during system resume

Hi Bob,

This is the Linux version of ACPICA commit 0762982923f95eb652cf7ded27356b247c9774de and now it has been automatically selected for backporting into the "stable" kernel versions.

On Wed, Nov 10, 2021 at 4:10 PM Moore, Robert <[email protected]> wrote:
>
> Sasha,
> Can you re-do this patch in native ACPICA format, then add a pull request to our github?
>
> Thanks,
> Bob
>
>
> -----Original Message-----
> From: Sasha Levin <[email protected]>
> Sent: Monday, November 08, 2021 5:09 PM
> To: [email protected]; [email protected]
> Cc: Wysocki, Rafael J <[email protected]>; Reik Keutterling
> <[email protected]>; Sasha Levin <[email protected]>; Moore, Robert
> <[email protected]>; [email protected]; [email protected]
> Subject: [PATCH AUTOSEL 4.4 15/30] ACPICA: Avoid evaluating methods
> too early during system resume
>
> From: "Rafael J. Wysocki" <[email protected]>
>
> [ Upstream commit d3c4b6f64ad356c0d9ddbcf73fa471e6a841cc5c ]
>
> ACPICA commit 0762982923f95eb652cf7ded27356b247c9774de
>
> During wakeup from system-wide sleep states, acpi_get_sleep_type_data() is called and it tries to get memory from the slab allocator in order to evaluate a control method, but if KFENCE is enabled in the kernel, the memory allocation attempt causes an IRQ work to be queued and a self-IPI to be sent to the CPU running the code which requires the memory controller to be ready, so if that happens too early in the wakeup path, it doesn't work.
>
> Prevent that from taking place by calling acpi_get_sleep_type_data() for S0 upfront, when preparing to enter a given sleep state, and saving the data obtained by it for later use during system wakeup.
>
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214271
> Reported-by: Reik Keutterling <[email protected]>
> Tested-by: Reik Keutterling <[email protected]>
> Signed-off-by: Rafael J. Wysocki <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---
> drivers/acpi/acpica/acglobal.h | 2 ++ drivers/acpi/acpica/hwesleep.c | 8 ++------
> drivers/acpi/acpica/hwsleep.c | 11 ++++-------
> drivers/acpi/acpica/hwxfsleep.c | 7 +++++++
> 4 files changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/acpi/acpica/acglobal.h
> b/drivers/acpi/acpica/acglobal.h index faa97604d878e..f178d11597c09
> 100644
> --- a/drivers/acpi/acpica/acglobal.h
> +++ b/drivers/acpi/acpica/acglobal.h
> @@ -256,6 +256,8 @@ extern struct acpi_bit_register_info
>
> ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a); ACPI_GLOBAL(u8,
> acpi_gbl_sleep_type_b);
> +ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a_s0); ACPI_GLOBAL(u8,
> +acpi_gbl_sleep_type_b_s0);
>
> /*****************************************************************************
> *
> diff --git a/drivers/acpi/acpica/hwesleep.c
> b/drivers/acpi/acpica/hwesleep.c index e5599f6108083..e4998cc0ce283
> 100644
> --- a/drivers/acpi/acpica/hwesleep.c
> +++ b/drivers/acpi/acpica/hwesleep.c
> @@ -184,17 +184,13 @@ acpi_status acpi_hw_extended_sleep(u8
> sleep_state)
>
> acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) {
> - acpi_status status;
> u8 sleep_type_value;
>
> ACPI_FUNCTION_TRACE(hw_extended_wake_prep);
>
> - status = acpi_get_sleep_type_data(ACPI_STATE_S0,
> - &acpi_gbl_sleep_type_a,
> - &acpi_gbl_sleep_type_b);
> - if (ACPI_SUCCESS(status)) {
> + if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
> sleep_type_value =
> - ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
> + ((acpi_gbl_sleep_type_a_s0 <<
> + ACPI_X_SLEEP_TYPE_POSITION) &
> ACPI_X_SLEEP_TYPE_MASK);
>
> (void)acpi_write((u64)(sleep_type_value |
> ACPI_X_SLEEP_ENABLE), diff --git a/drivers/acpi/acpica/hwsleep.c
> b/drivers/acpi/acpica/hwsleep.c index 7d21cae6d6028..7e44ba8c6a1ab
> 100644
> --- a/drivers/acpi/acpica/hwsleep.c
> +++ b/drivers/acpi/acpica/hwsleep.c
> @@ -217,7 +217,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
>
> acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) {
> - acpi_status status;
> + acpi_status status = AE_OK;
> struct acpi_bit_register_info *sleep_type_reg_info;
> struct acpi_bit_register_info *sleep_enable_reg_info;
> u32 pm1a_control;
> @@ -230,10 +230,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
> * This is unclear from the ACPI Spec, but it is required
> * by some machines.
> */
> - status = acpi_get_sleep_type_data(ACPI_STATE_S0,
> - &acpi_gbl_sleep_type_a,
> - &acpi_gbl_sleep_type_b);
> - if (ACPI_SUCCESS(status)) {
> + if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
> sleep_type_reg_info =
> acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
> sleep_enable_reg_info = @@ -254,9 +251,9 @@
> acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
>
> /* Insert the SLP_TYP bits */
>
> - pm1a_control |= (acpi_gbl_sleep_type_a <<
> + pm1a_control |= (acpi_gbl_sleep_type_a_s0 <<
> sleep_type_reg_info->bit_position);
> - pm1b_control |= (acpi_gbl_sleep_type_b <<
> + pm1b_control |= (acpi_gbl_sleep_type_b_s0 <<
>
> sleep_type_reg_info->bit_position);
>
> /* Write the control registers and ignore any
> errors */ diff --git a/drivers/acpi/acpica/hwxfsleep.c
> b/drivers/acpi/acpica/hwxfsleep.c index d62a61612b3f1..b04e2b0f62246
> 100644
> --- a/drivers/acpi/acpica/hwxfsleep.c
> +++ b/drivers/acpi/acpica/hwxfsleep.c
> @@ -372,6 +372,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
> return_ACPI_STATUS(status);
> }
>
> + status = acpi_get_sleep_type_data(ACPI_STATE_S0,
> + &acpi_gbl_sleep_type_a_s0,
> + &acpi_gbl_sleep_type_b_s0);
> + if (ACPI_FAILURE(status)) {
> + acpi_gbl_sleep_type_a_s0 = ACPI_SLEEP_TYPE_INVALID;
> + }
> +
> /* Execute the _PTS method (Prepare To Sleep) */
>
> arg_list.count = 1;
> --
> 2.33.0
>