The patch below does not apply to the 5.15-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y git checkout FETCH_HEAD git cherry-pick -x f489c948028b69cea235d9c0de1cc10eeb26a172 # <resolve conflicts, build, test, etc.> git commit -s git send-email --to 'stable@vger.kernel.org' --in-reply-to '2024042905-puppy-heritage-e422@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
f489c948028b ("ACPI: CPPC: Fix access width used for PCC registers") 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space") c42fa24b4475 ("ACPI: bus: Avoid using CPPC if not supported by firmware") 2ca8e6285250 ("Revert "ACPI: Pass the same capabilities to the _OSC regardless of the query flag"") f684b1075128 ("ACPI: CPPC: Drop redundant local variable from cpc_read()") 5f51c7ce1dc3 ("ACPI: CPPC: Fix up I/O port access in cpc_read()") a2c8f92bea5f ("ACPI: CPPC: Implement support for SystemIO registers")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f489c948028b69cea235d9c0de1cc10eeb26a172 Mon Sep 17 00:00:00 2001 From: Vanshidhar Konda vanshikonda@os.amperecomputing.com Date: Thu, 11 Apr 2024 16:18:44 -0700 Subject: [PATCH] ACPI: CPPC: Fix access width used for PCC registers
commit 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") modified cpc_read()/cpc_write() to use access_width to read CPC registers.
However, for PCC registers the access width field in the ACPI register macro specifies the PCC subspace ID. For non-zero PCC subspace ID it is incorrectly treated as access width. This causes errors when reading from PCC registers in the CPPC driver.
For PCC registers, base the size of read/write on the bit width field. The debug message in cpc_read()/cpc_write() is updated to print relevant information for the address space type used to read the register.
Fixes: 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") Signed-off-by: Vanshidhar Konda vanshikonda@os.amperecomputing.com Tested-by: Jarred White jarredwhite@linux.microsoft.com Reviewed-by: Jarred White jarredwhite@linux.microsoft.com Reviewed-by: Easwar Hariharan eahariha@linux.microsoft.com Cc: 5.15+ stable@vger.kernel.org # 5.15+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 00a30ca35e78..a40b6f3946ef 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1002,14 +1002,14 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) }
*val = 0; + size = GET_BIT_WIDTH(reg);
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { - u32 width = GET_BIT_WIDTH(reg); u32 val_u32; acpi_status status;
status = acpi_os_read_port((acpi_io_address)reg->address, - &val_u32, width); + &val_u32, size); if (ACPI_FAILURE(status)) { pr_debug("Error: Failed to read SystemIO port %llx\n", reg->address); @@ -1018,17 +1018,22 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
*val = val_u32; return 0; - } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { + /* + * For registers in PCC space, the register size is determined + * by the bit width field; the access size is used to indicate + * the PCC subspace id. + */ + size = reg->bit_width; vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); + } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_read_ffh(cpu, reg, val); else return acpi_os_read_memory((acpi_physical_address)reg->address, - val, reg->bit_width); - - size = GET_BIT_WIDTH(reg); + val, size);
switch (size) { case 8: @@ -1044,8 +1049,13 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) *val = readq_relaxed(vaddr); break; default: - pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", - reg->bit_width, pcc_ss_id); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + pr_debug("Error: Cannot read %u bit width from system memory: 0x%llx\n", + size, reg->address); + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { + pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", + size, pcc_ss_id); + } return -EFAULT; }
@@ -1063,12 +1073,13 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg;
+ size = GET_BIT_WIDTH(reg); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { - u32 width = GET_BIT_WIDTH(reg); acpi_status status;
status = acpi_os_write_port((acpi_io_address)reg->address, - (u32)val, width); + (u32)val, size); if (ACPI_FAILURE(status)) { pr_debug("Error: Failed to write SystemIO port %llx\n", reg->address); @@ -1076,17 +1087,22 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) }
return 0; - } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { + /* + * For registers in PCC space, the register size is determined + * by the bit width field; the access size is used to indicate + * the PCC subspace id. + */ + size = reg->bit_width; vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); + } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_write_ffh(cpu, reg, val); else return acpi_os_write_memory((acpi_physical_address)reg->address, - val, reg->bit_width); - - size = GET_BIT_WIDTH(reg); + val, size);
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) val = MASK_VAL(reg, val); @@ -1105,8 +1121,13 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) writeq_relaxed(val, vaddr); break; default: - pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n", - reg->bit_width, pcc_ss_id); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + pr_debug("Error: Cannot write %u bit width to system memory: 0x%llx\n", + size, reg->address); + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { + pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n", + size, pcc_ss_id); + } ret_val = -EFAULT; break; }
On 4/29/2024 4:53 AM, gregkh@linuxfoundation.org wrote:
The patch below does not apply to the 5.15-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y git checkout FETCH_HEAD git cherry-pick -x f489c948028b69cea235d9c0de1cc10eeb26a172 # <resolve conflicts, build, test, etc.> git commit -s git send-email --to 'stable@vger.kernel.org' --in-reply-to '2024042905-puppy-heritage-e422@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
f489c948028b ("ACPI: CPPC: Fix access width used for PCC registers") 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space") c42fa24b4475 ("ACPI: bus: Avoid using CPPC if not supported by firmware") 2ca8e6285250 ("Revert "ACPI: Pass the same capabilities to the _OSC regardless of the query flag"") f684b1075128 ("ACPI: CPPC: Drop redundant local variable from cpc_read()") 5f51c7ce1dc3 ("ACPI: CPPC: Fix up I/O port access in cpc_read()") a2c8f92bea5f ("ACPI: CPPC: Implement support for SystemIO registers")
thanks,
greg k-h
Hi Greg,
Please fix this with the following set of changes in linux-5.15.y.
Revert b54c4632946ae42f2b39ed38abd909bbf78cbcc2 from linux-5.15.y Cherry-pick 05d92ee782eeb7b939bdd0189e6efcab9195bf95 from upstream Pick the following backport of f489c948028b69cea235d9c0de1cc10eeb26a172 from upstream
----------------------x8------------------------------------------------- From d3260c1d3c9021d3f1b9aa4cf5c85e7501dacbdf Mon Sep 17 00:00:00 2001 From: Vanshidhar Konda vanshikonda@os.amperecomputing.com Date: Thu, 11 Apr 2024 16:18:44 -0700 Subject: [PATCH] ACPI: CPPC: Fix access width used for PCC registers
commit f489c948028b69cea235d9c0de1cc10eeb26a172 upstream
commit 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") modified cpc_read()/cpc_write() to use access_width to read CPC registers.
However, for PCC registers the access width field in the ACPI register macro specifies the PCC subspace ID. For non-zero PCC subspace ID it is incorrectly treated as access width. This causes errors when reading from PCC registers in the CPPC driver.
For PCC registers, base the size of read/write on the bit width field. The debug message in cpc_read()/cpc_write() is updated to print relevant information for the address space type used to read the register.
Fixes: 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") Signed-off-by: Vanshidhar Konda vanshikonda@os.amperecomputing.com Tested-by: Jarred White jarredwhite@linux.microsoft.com Reviewed-by: Jarred White jarredwhite@linux.microsoft.com Reviewed-by: Easwar Hariharan eahariha@linux.microsoft.com Cc: 5.15+ stable@vger.kernel.org # 5.15+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Easwar Hariharan eahariha@linux.microsoft.com --- drivers/acpi/cppc_acpi.c | 48 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 6aa456cda0ed..6dcce036adb9 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -955,17 +955,24 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) }
*val = 0; - if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + size = GET_BIT_WIDTH(reg); + + if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { + /* + * For registers in PCC space, the register size is determined + * by the bit width field; the access size is used to indicate + * the PCC subspace id. + */ + size = reg->bit_width; vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); + } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_read_ffh(cpu, reg, val); else return acpi_os_read_memory((acpi_physical_address)reg->address, - val, reg->bit_width); - - size = GET_BIT_WIDTH(reg); + val, size);
switch (size) { case 8: @@ -981,8 +988,13 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) *val = readq_relaxed(vaddr); break; default: - pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", - reg->bit_width, pcc_ss_id); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + pr_debug("Error: Cannot read %u bit width from system memory: 0x%llx\n", + size, reg->address); + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { + pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", + size, pcc_ss_id); + } ret_val = -EFAULT; }
@@ -1000,17 +1012,24 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg;
- if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + size = GET_BIT_WIDTH(reg); + + if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { + /* + * For registers in PCC space, the register size is determined + * by the bit width field; the access size is used to indicate + * the PCC subspace id. + */ + size = reg->bit_width; vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); + } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_write_ffh(cpu, reg, val); else return acpi_os_write_memory((acpi_physical_address)reg->address, - val, reg->bit_width); - - size = GET_BIT_WIDTH(reg); + val, size);
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) val = MASK_VAL(reg, val); @@ -1029,8 +1048,13 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) writeq_relaxed(val, vaddr); break; default: - pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n", - reg->bit_width, pcc_ss_id); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + pr_debug("Error: Cannot write %u bit width to system memory: 0x%llx\n", + size, reg->address); + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { + pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n", + size, pcc_ss_id); + } ret_val = -EFAULT; break; }
On Tue, Apr 30, 2024 at 09:05:28AM -0700, Easwar Hariharan wrote:
On 4/29/2024 4:53 AM, gregkh@linuxfoundation.org wrote:
The patch below does not apply to the 5.15-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y git checkout FETCH_HEAD git cherry-pick -x f489c948028b69cea235d9c0de1cc10eeb26a172 # <resolve conflicts, build, test, etc.> git commit -s git send-email --to 'stable@vger.kernel.org' --in-reply-to '2024042905-puppy-heritage-e422@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
f489c948028b ("ACPI: CPPC: Fix access width used for PCC registers") 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space") c42fa24b4475 ("ACPI: bus: Avoid using CPPC if not supported by firmware") 2ca8e6285250 ("Revert "ACPI: Pass the same capabilities to the _OSC regardless of the query flag"") f684b1075128 ("ACPI: CPPC: Drop redundant local variable from cpc_read()") 5f51c7ce1dc3 ("ACPI: CPPC: Fix up I/O port access in cpc_read()") a2c8f92bea5f ("ACPI: CPPC: Implement support for SystemIO registers")
thanks,
greg k-h
Hi Greg,
Please fix this with the following set of changes in linux-5.15.y.
Revert b54c4632946ae42f2b39ed38abd909bbf78cbcc2 from linux-5.15.y Cherry-pick 05d92ee782eeb7b939bdd0189e6efcab9195bf95 from upstream Pick the following backport of f489c948028b69cea235d9c0de1cc10eeb26a172 from upstream
Please provide a series of patches that I can apply that does this, attempting to revert and cherry-pick and then manually hand-edit this email and apply it does not scale at all, sorry.
thanks,
greg k-h
On 4/30/2024 10:41 AM, Greg KH wrote:
On Tue, Apr 30, 2024 at 09:05:28AM -0700, Easwar Hariharan wrote:
On 4/29/2024 4:53 AM, gregkh@linuxfoundation.org wrote:
The patch below does not apply to the 5.15-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y git checkout FETCH_HEAD git cherry-pick -x f489c948028b69cea235d9c0de1cc10eeb26a172 # <resolve conflicts, build, test, etc.> git commit -s git send-email --to 'stable@vger.kernel.org' --in-reply-to '2024042905-puppy-heritage-e422@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
f489c948028b ("ACPI: CPPC: Fix access width used for PCC registers") 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space") c42fa24b4475 ("ACPI: bus: Avoid using CPPC if not supported by firmware") 2ca8e6285250 ("Revert "ACPI: Pass the same capabilities to the _OSC regardless of the query flag"") f684b1075128 ("ACPI: CPPC: Drop redundant local variable from cpc_read()") 5f51c7ce1dc3 ("ACPI: CPPC: Fix up I/O port access in cpc_read()") a2c8f92bea5f ("ACPI: CPPC: Implement support for SystemIO registers")
thanks,
greg k-h
Hi Greg,
Please fix this with the following set of changes in linux-5.15.y.
Revert b54c4632946ae42f2b39ed38abd909bbf78cbcc2 from linux-5.15.y Cherry-pick 05d92ee782eeb7b939bdd0189e6efcab9195bf95 from upstream Pick the following backport of f489c948028b69cea235d9c0de1cc10eeb26a172 from upstream
Please provide a series of patches that I can apply that does this, attempting to revert and cherry-pick and then manually hand-edit this email and apply it does not scale at all, sorry.
thanks,
greg k-h
Sorry about that, I'll send the series right away. I'm not quite sure what Closes: lore link to provide, could you please fix it up?
Thanks, Easwar
On Tue, Apr 30, 2024 at 11:05:06AM -0700, Easwar Hariharan wrote:
On 4/30/2024 10:41 AM, Greg KH wrote:
On Tue, Apr 30, 2024 at 09:05:28AM -0700, Easwar Hariharan wrote:
On 4/29/2024 4:53 AM, gregkh@linuxfoundation.org wrote:
The patch below does not apply to the 5.15-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y git checkout FETCH_HEAD git cherry-pick -x f489c948028b69cea235d9c0de1cc10eeb26a172 # <resolve conflicts, build, test, etc.> git commit -s git send-email --to 'stable@vger.kernel.org' --in-reply-to '2024042905-puppy-heritage-e422@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
f489c948028b ("ACPI: CPPC: Fix access width used for PCC registers") 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space") c42fa24b4475 ("ACPI: bus: Avoid using CPPC if not supported by firmware") 2ca8e6285250 ("Revert "ACPI: Pass the same capabilities to the _OSC regardless of the query flag"") f684b1075128 ("ACPI: CPPC: Drop redundant local variable from cpc_read()") 5f51c7ce1dc3 ("ACPI: CPPC: Fix up I/O port access in cpc_read()") a2c8f92bea5f ("ACPI: CPPC: Implement support for SystemIO registers")
thanks,
greg k-h
Hi Greg,
Please fix this with the following set of changes in linux-5.15.y.
Revert b54c4632946ae42f2b39ed38abd909bbf78cbcc2 from linux-5.15.y Cherry-pick 05d92ee782eeb7b939bdd0189e6efcab9195bf95 from upstream Pick the following backport of f489c948028b69cea235d9c0de1cc10eeb26a172 from upstream
Please provide a series of patches that I can apply that does this, attempting to revert and cherry-pick and then manually hand-edit this email and apply it does not scale at all, sorry.
thanks,
greg k-h
Sorry about that, I'll send the series right away. I'm not quite sure what Closes: lore link to provide, could you please fix it up?
There's no need for any "Closes:" link for stable backports.
thanks,
greg k-h
This reverts commit b54c4632946ae42f2b39ed38abd909bbf78cbcc2 which was a revert of a backport of commit 2f4a4d63a193be6fd530d180bb13c3592052904c upstream to 5.15.y.
The original commit[1] fixed a kernel panic on boot on the Microsoft Azure Cobalt 100 platform, but as reported by Vanshidhar Konda [2], caused a regression in AmpereOne systems. While testing [2], there was an additional bug found in [1] which resulted in [3]
[1] commit 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") [2] commit f489c948028b ("ACPI: CPPC: Fix access width used for PCC registers") [3] commit 05d92ee782ee ("ACPI: CPPC: Fix bit_offset shift in MASK_VAL() macro").
Cc: Jarred White jarredwhite@linux.microsoft.com Cc: Rafael J. Wysocki rafael.j.wysocki@intel.com Cc: Vanshidhar Konda vanshikonda@os.amperecomputing.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Easwar Hariharan eahariha@linux.microsoft.com --- drivers/acpi/cppc_acpi.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 7cc9183c8dc8..408b1fda5702 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -161,6 +161,13 @@ show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_freq); show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf); show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
+/* Check for valid access_width, otherwise, fallback to using bit_width */ +#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width) + +/* Shift and apply the mask for CPC reads/writes */ +#define MASK_VAL(reg, val) ((val) >> ((reg)->bit_offset & \ + GENMASK(((reg)->bit_width), 0))) + static ssize_t show_feedback_ctrs(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -762,8 +769,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { if (gas_t->address) { void __iomem *addr; + size_t access_width;
- addr = ioremap(gas_t->address, gas_t->bit_width/8); + access_width = GET_BIT_WIDTH(gas_t) / 8; + addr = ioremap(gas_t->address, access_width); if (!addr) goto out_free; cpc_ptr->cpc_regs[i-2].sys_mem_vaddr = addr; @@ -936,6 +945,7 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) { int ret_val = 0; void __iomem *vaddr = NULL; + int size; int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg;
@@ -955,7 +965,9 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) return acpi_os_read_memory((acpi_physical_address)reg->address, val, reg->bit_width);
- switch (reg->bit_width) { + size = GET_BIT_WIDTH(reg); + + switch (size) { case 8: *val = readb_relaxed(vaddr); break; @@ -974,12 +986,16 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) ret_val = -EFAULT; }
+ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + *val = MASK_VAL(reg, *val); + return ret_val; }
static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) { int ret_val = 0; + int size; void __iomem *vaddr = NULL; int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg; @@ -994,7 +1010,12 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) return acpi_os_write_memory((acpi_physical_address)reg->address, val, reg->bit_width);
- switch (reg->bit_width) { + size = GET_BIT_WIDTH(reg); + + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + val = MASK_VAL(reg, val); + + switch (size) { case 8: writeb_relaxed(val, vaddr); break;
base-commit: b925f60c6ee7ec871d2d48575d0fde3872129c20
From: Jarred White jarredwhite@linux.microsoft.com
commit 05d92ee782eeb7b939bdd0189e6efcab9195bf95 upstream
Commit 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") neglected to properly wrap the bit_offset shift when it comes to applying the mask. This may cause incorrect values to be read and may cause the cpufreq module not be loaded.
[ 11.059751] cpu_capacity: CPU0 missing/invalid highest performance. [ 11.066005] cpu_capacity: partial information: fallback to 1024 for all CPUs
Also, corrected the bitmask generation in GENMASK (extra bit being added).
Fixes: 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") Signed-off-by: Jarred White jarredwhite@linux.microsoft.com Cc: 5.15+ stable@vger.kernel.org # 5.15+ Reviewed-by: Vanshidhar Konda vanshikonda@os.amperecomputing.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Easwar Hariharan eahariha@linux.microsoft.com --- drivers/acpi/cppc_acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 408b1fda5702..6aa456cda0ed 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -165,8 +165,8 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); #define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
/* Shift and apply the mask for CPC reads/writes */ -#define MASK_VAL(reg, val) ((val) >> ((reg)->bit_offset & \ - GENMASK(((reg)->bit_width), 0))) +#define MASK_VAL(reg, val) (((val) >> (reg)->bit_offset) & \ + GENMASK(((reg)->bit_width) - 1, 0))
static ssize_t show_feedback_ctrs(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
From: Vanshidhar Konda vanshikonda@os.amperecomputing.com
commit f489c948028b69cea235d9c0de1cc10eeb26a172 upstream
commit 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") modified cpc_read()/cpc_write() to use access_width to read CPC registers.
However, for PCC registers the access width field in the ACPI register macro specifies the PCC subspace ID. For non-zero PCC subspace ID it is incorrectly treated as access width. This causes errors when reading from PCC registers in the CPPC driver.
For PCC registers, base the size of read/write on the bit width field. The debug message in cpc_read()/cpc_write() is updated to print relevant information for the address space type used to read the register.
Fixes: 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses") Signed-off-by: Vanshidhar Konda vanshikonda@os.amperecomputing.com Tested-by: Jarred White jarredwhite@linux.microsoft.com Reviewed-by: Jarred White jarredwhite@linux.microsoft.com Reviewed-by: Easwar Hariharan eahariha@linux.microsoft.com Cc: 5.15+ stable@vger.kernel.org # 5.15+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com [ eahariha: Backport to v5.15 by dropping SystemIO bits as commit a2c8f92bea5f is not present ] Signed-off-by: Easwar Hariharan eahariha@linux.microsoft.com --- drivers/acpi/cppc_acpi.c | 48 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 6aa456cda0ed..6dcce036adb9 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -955,17 +955,24 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) }
*val = 0; - if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + size = GET_BIT_WIDTH(reg); + + if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { + /* + * For registers in PCC space, the register size is determined + * by the bit width field; the access size is used to indicate + * the PCC subspace id. + */ + size = reg->bit_width; vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); + } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_read_ffh(cpu, reg, val); else return acpi_os_read_memory((acpi_physical_address)reg->address, - val, reg->bit_width); - - size = GET_BIT_WIDTH(reg); + val, size);
switch (size) { case 8: @@ -981,8 +988,13 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) *val = readq_relaxed(vaddr); break; default: - pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", - reg->bit_width, pcc_ss_id); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + pr_debug("Error: Cannot read %u bit width from system memory: 0x%llx\n", + size, reg->address); + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { + pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", + size, pcc_ss_id); + } ret_val = -EFAULT; }
@@ -1000,17 +1012,24 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg;
- if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + size = GET_BIT_WIDTH(reg); + + if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { + /* + * For registers in PCC space, the register size is determined + * by the bit width field; the access size is used to indicate + * the PCC subspace id. + */ + size = reg->bit_width; vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); + } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_write_ffh(cpu, reg, val); else return acpi_os_write_memory((acpi_physical_address)reg->address, - val, reg->bit_width); - - size = GET_BIT_WIDTH(reg); + val, size);
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) val = MASK_VAL(reg, val); @@ -1029,8 +1048,13 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) writeq_relaxed(val, vaddr); break; default: - pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n", - reg->bit_width, pcc_ss_id); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + pr_debug("Error: Cannot write %u bit width to system memory: 0x%llx\n", + size, reg->address); + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { + pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n", + size, pcc_ss_id); + } ret_val = -EFAULT; break; }
linux-stable-mirror@lists.linaro.org