--- /dev/null
+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: ACPI: CPPC: Fix access width used for PCC registers
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/acpi/cppc_acpi.c | 53 ++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 37 insertions(+), 16 deletions(-)
+
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -1002,14 +1002,14 @@ static int cpc_read(int cpu, struct cpc_
+ }
+
+ *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_
+
+ *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_
+ *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
+ 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
+ }
+
+ 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
+ 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;
+ }
--- /dev/null
+From 05d92ee782eeb7b939bdd0189e6efcab9195bf95 Mon Sep 17 00:00:00 2001
+From: Jarred White <jarredwhite@linux.microsoft.com>
+Date: Mon, 8 Apr 2024 22:23:09 -0700
+Subject: ACPI: CPPC: Fix bit_offset shift in MASK_VAL() macro
+
+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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/acpi/cppc_acpi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -170,8 +170,8 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_
+ #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)
--- /dev/null
+From 2f4a4d63a193be6fd530d180bb13c3592052904c Mon Sep 17 00:00:00 2001
+From: Jarred White <jarredwhite@linux.microsoft.com>
+Date: Fri, 1 Mar 2024 11:25:59 -0800
+Subject: ACPI: CPPC: Use access_width over bit_width for system memory accesses
+
+From: Jarred White <jarredwhite@linux.microsoft.com>
+
+commit 2f4a4d63a193be6fd530d180bb13c3592052904c upstream.
+
+To align with ACPI 6.3+, since bit_width can be any 8-bit value, it
+cannot be depended on to be always on a clean 8b boundary. This was
+uncovered on the Cobalt 100 platform.
+
+SError Interrupt on CPU26, code 0xbe000011 -- SError
+ CPU: 26 PID: 1510 Comm: systemd-udevd Not tainted 5.15.2.1-13 #1
+ Hardware name: MICROSOFT CORPORATION, BIOS MICROSOFT CORPORATION
+ pstate: 62400009 (nZCv daif +PAN -UAO +TCO -DIT -SSBS BTYPE=--)
+ pc : cppc_get_perf_caps+0xec/0x410
+ lr : cppc_get_perf_caps+0xe8/0x410
+ sp : ffff8000155ab730
+ x29: ffff8000155ab730 x28: ffff0080139d0038 x27: ffff0080139d0078
+ x26: 0000000000000000 x25: ffff0080139d0058 x24: 00000000ffffffff
+ x23: ffff0080139d0298 x22: ffff0080139d0278 x21: 0000000000000000
+ x20: ffff00802b251910 x19: ffff0080139d0000 x18: ffffffffffffffff
+ x17: 0000000000000000 x16: ffffdc7e111bad04 x15: ffff00802b251008
+ x14: ffffffffffffffff x13: ffff013f1fd63300 x12: 0000000000000006
+ x11: ffffdc7e128f4420 x10: 0000000000000000 x9 : ffffdc7e111badec
+ x8 : ffff00802b251980 x7 : 0000000000000000 x6 : ffff0080139d0028
+ x5 : 0000000000000000 x4 : ffff0080139d0018 x3 : 00000000ffffffff
+ x2 : 0000000000000008 x1 : ffff8000155ab7a0 x0 : 0000000000000000
+ Kernel panic - not syncing: Asynchronous SError Interrupt
+ CPU: 26 PID: 1510 Comm: systemd-udevd Not tainted
+5.15.2.1-13 #1
+ Hardware name: MICROSOFT CORPORATION, BIOS MICROSOFT CORPORATION
+ Call trace:
+ dump_backtrace+0x0/0x1e0
+ show_stack+0x24/0x30
+ dump_stack_lvl+0x8c/0xb8
+ dump_stack+0x18/0x34
+ panic+0x16c/0x384
+ add_taint+0x0/0xc0
+ arm64_serror_panic+0x7c/0x90
+ arm64_is_fatal_ras_serror+0x34/0xa4
+ do_serror+0x50/0x6c
+ el1h_64_error_handler+0x40/0x74
+ el1h_64_error+0x7c/0x80
+ cppc_get_perf_caps+0xec/0x410
+ cppc_cpufreq_cpu_init+0x74/0x400 [cppc_cpufreq]
+ cpufreq_online+0x2dc/0xa30
+ cpufreq_add_dev+0xc0/0xd4
+ subsys_interface_register+0x134/0x14c
+ cpufreq_register_driver+0x1b0/0x354
+ cppc_cpufreq_init+0x1a8/0x1000 [cppc_cpufreq]
+ do_one_initcall+0x50/0x250
+ do_init_module+0x60/0x27c
+ load_module+0x2300/0x2570
+ __do_sys_finit_module+0xa8/0x114
+ __arm64_sys_finit_module+0x2c/0x3c
+ invoke_syscall+0x78/0x100
+ el0_svc_common.constprop.0+0x180/0x1a0
+ do_el0_svc+0x84/0xa0
+ el0_svc+0x2c/0xc0
+ el0t_64_sync_handler+0xa4/0x12c
+ el0t_64_sync+0x1a4/0x1a8
+
+Instead, use access_width to determine the size and use the offset and
+width to shift and mask the bits to read/write out. Make sure to add a
+check for system memory since pcc redefines the access_width to
+subspace id.
+
+If access_width is not set, then fall back to using bit_width.
+
+Signed-off-by: Jarred White <jarredwhite@linux.microsoft.com>
+Reviewed-by: Easwar Hariharan <eahariha@linux.microsoft.com>
+Cc: 5.15+ <stable@vger.kernel.org> # 5.15+
+[ rjw: Subject and changelog edits, comment adjustments ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/acpi/cppc_acpi.c | 31 ++++++++++++++++++++++++++-----
+ 1 file changed, 26 insertions(+), 5 deletions(-)
+
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -166,6 +166,13 @@ show_cppc_data(cppc_get_perf_caps, cppc_
+ 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)
+ {
+@@ -780,6 +787,7 @@ int acpi_cppc_processor_probe(struct acp
+ } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+ if (gas_t->address) {
+ void __iomem *addr;
++ size_t access_width;
+
+ if (!osc_cpc_flexible_adr_space_confirmed) {
+ pr_debug("Flexible address space capability not supported\n");
+@@ -787,7 +795,8 @@ int acpi_cppc_processor_probe(struct acp
+ goto out_free;
+ }
+
+- 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;
+@@ -983,6 +992,7 @@ int __weak cpc_write_ffh(int cpunum, str
+ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
+ {
+ 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;
+
+@@ -994,7 +1004,7 @@ static int cpc_read(int cpu, struct cpc_
+ *val = 0;
+
+ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
+- u32 width = 8 << (reg->access_width - 1);
++ u32 width = GET_BIT_WIDTH(reg);
+ u32 val_u32;
+ acpi_status status;
+
+@@ -1018,7 +1028,9 @@ static int cpc_read(int cpu, struct cpc_
+ 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;
+@@ -1037,18 +1049,22 @@ static int cpc_read(int cpu, struct cpc_
+ return -EFAULT;
+ }
+
++ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
++ *val = MASK_VAL(reg, *val);
++
+ return 0;
+ }
+
+ 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;
+
+ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
+- u32 width = 8 << (reg->access_width - 1);
++ u32 width = GET_BIT_WIDTH(reg);
+ acpi_status status;
+
+ status = acpi_os_write_port((acpi_io_address)reg->address,
+@@ -1070,7 +1086,12 @@ static int cpc_write(int cpu, struct cpc
+ 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;
--- /dev/null
+From c26591afd33adce296c022e3480dea4282b7ef91 Mon Sep 17 00:00:00 2001
+From: Guanrui Huang <guanrui.huang@linux.alibaba.com>
+Date: Thu, 18 Apr 2024 14:10:52 +0800
+Subject: irqchip/gic-v3-its: Prevent double free on error
+
+From: Guanrui Huang <guanrui.huang@linux.alibaba.com>
+
+commit c26591afd33adce296c022e3480dea4282b7ef91 upstream.
+
+The error handling path in its_vpe_irq_domain_alloc() causes a double free
+when its_vpe_init() fails after successfully allocating at least one
+interrupt. This happens because its_vpe_irq_domain_free() frees the
+interrupts along with the area bitmap and the vprop_page and
+its_vpe_irq_domain_alloc() subsequently frees the area bitmap and the
+vprop_page again.
+
+Fix this by unconditionally invoking its_vpe_irq_domain_free() which
+handles all cases correctly and by removing the bitmap/vprop_page freeing
+from its_vpe_irq_domain_alloc().
+
+[ tglx: Massaged change log ]
+
+Fixes: 7d75bbb4bc1a ("irqchip/gic-v3-its: Add VPE irq domain allocation/teardown")
+Signed-off-by: Guanrui Huang <guanrui.huang@linux.alibaba.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240418061053.96803-2-guanrui.huang@linux.alibaba.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/irqchip/irq-gic-v3-its.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/drivers/irqchip/irq-gic-v3-its.c
++++ b/drivers/irqchip/irq-gic-v3-its.c
+@@ -4561,13 +4561,8 @@ static int its_vpe_irq_domain_alloc(stru
+ irqd_set_resend_when_in_progress(irq_get_irq_data(virq + i));
+ }
+
+- if (err) {
+- if (i > 0)
+- its_vpe_irq_domain_free(domain, virq, i);
+-
+- its_lpi_free(bitmap, base, nr_ids);
+- its_free_prop_table(vprop_page);
+- }
++ if (err)
++ its_vpe_irq_domain_free(domain, virq, i);
+
+ return err;
+ }
drm-amdgpu-fix-leak-when-gpu-memory-allocation-fails.patch
drm-amdkfd-fix-rescheduling-of-restore-worker.patch
drm-amdkfd-fix-eviction-fence-handling.patch
+irqchip-gic-v3-its-prevent-double-free-on-error.patch
+acpi-cppc-use-access_width-over-bit_width-for-system-memory-accesses.patch
+acpi-cppc-fix-bit_offset-shift-in-mask_val-macro.patch
+acpi-cppc-fix-access-width-used-for-pcc-registers.patch