From: Sasha Levin Date: Sun, 29 Oct 2023 22:49:28 +0000 (-0400) Subject: Fixes for 5.10 X-Git-Tag: v6.1.61~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ab42831d21ee496f9739eea40d9d917ec0400c66;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/acpica-add-support-for-madt-online-enabled-bit.patch b/queue-5.10/acpica-add-support-for-madt-online-enabled-bit.patch new file mode 100644 index 00000000000..5ecb3f0bc06 --- /dev/null +++ b/queue-5.10/acpica-add-support-for-madt-online-enabled-bit.patch @@ -0,0 +1,36 @@ +From 1cf7e5d39939757c72a8f77b09273310433c300b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Sep 2021 16:41:45 -0500 +Subject: ACPICA: Add support for MADT online enabled bit + +From: Mario Limonciello + +[ Upstream commit 435a8dc8d9b9d91e625901fea5b5695b9b976d84 ] + +The online enabled bit on newer ACPI implmentations will indicate +whether the CPU is hotpluggable. + +Link: http://github.com/acpica/acpica/pull/708/ +Signed-off-by: Mario Limonciello +Signed-off-by: Rafael J. Wysocki +Stable-dep-of: 128b0c9781c9 ("x86/i8259: Skip probing when ACPI/MADT advertises PCAT compatibility") +Signed-off-by: Sasha Levin +--- + include/acpi/actbl2.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h +index ec66779cb1934..71f4ce6e78aae 100644 +--- a/include/acpi/actbl2.h ++++ b/include/acpi/actbl2.h +@@ -731,6 +731,7 @@ struct acpi_madt_generic_translator { + /* MADT Local APIC flags */ + + #define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */ ++#define ACPI_MADT_ONLINE_CAPABLE (2) /* 01: System HW supports enabling processor at runtime */ + + /* MADT MPS INTI flags (inti_flags) */ + +-- +2.42.0 + diff --git a/queue-5.10/iio-adc-xilinx-use-devm_krealloc-instead-of-kfree-kc.patch b/queue-5.10/iio-adc-xilinx-use-devm_krealloc-instead-of-kfree-kc.patch new file mode 100644 index 00000000000..7d5eea2bedd --- /dev/null +++ b/queue-5.10/iio-adc-xilinx-use-devm_krealloc-instead-of-kfree-kc.patch @@ -0,0 +1,73 @@ +From 49dbe0191303691b44cd796ff0855a4833f6c79d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Nov 2020 15:27:58 +0100 +Subject: iio: adc: xilinx: use devm_krealloc() instead of kfree() + kcalloc() + +From: Bartosz Golaszewski + +[ Upstream commit eab64715709ed440d54cac42f239e2d49df26c1f ] + +We now have devm_krealloc() in the kernel Use it indstead of calling +kfree() and kcalloc() separately. + +Signed-off-by: Bartosz Golaszewski +Tested-by: Anand Ashok Dumbre +Reviewed-by: Anand Ashok Dumbre +Link: https://lore.kernel.org/r/20201130142759.28216-3-brgl@bgdev.pl +Signed-off-by: Jonathan Cameron +Stable-dep-of: 8d6b3ea4d9ea ("iio: adc: xilinx-xadc: Don't clobber preset voltage/temperature thresholds") +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/xilinx-xadc-core.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c +index 8494eb424b331..6f89a97bb127b 100644 +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -585,15 +586,22 @@ static int xadc_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *mask) + { + struct xadc *xadc = iio_priv(indio_dev); +- unsigned int n; ++ size_t new_size, n; ++ void *data; + + n = bitmap_weight(mask, indio_dev->masklength); + +- kfree(xadc->data); +- xadc->data = kcalloc(n, sizeof(*xadc->data), GFP_KERNEL); +- if (!xadc->data) ++ if (check_mul_overflow(n, sizeof(*xadc->data), &new_size)) ++ return -ENOMEM; ++ ++ data = devm_krealloc(indio_dev->dev.parent, xadc->data, ++ new_size, GFP_KERNEL); ++ if (!data) + return -ENOMEM; + ++ memset(data, 0, new_size); ++ xadc->data = data; ++ + return 0; + } + +@@ -1372,7 +1380,6 @@ static int xadc_remove(struct platform_device *pdev) + free_irq(xadc->irq, indio_dev); + cancel_delayed_work_sync(&xadc->zynq_unmask_work); + clk_disable_unprepare(xadc->clk); +- kfree(xadc->data); + + return 0; + } +-- +2.42.0 + diff --git a/queue-5.10/iio-adc-xilinx-use-helper-variable-for-pdev-dev.patch b/queue-5.10/iio-adc-xilinx-use-helper-variable-for-pdev-dev.patch new file mode 100644 index 00000000000..23f41506de4 --- /dev/null +++ b/queue-5.10/iio-adc-xilinx-use-helper-variable-for-pdev-dev.patch @@ -0,0 +1,87 @@ +From 70551fc85e35be9a3aeb59ff9044f78adbf70ad9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Nov 2020 15:27:57 +0100 +Subject: iio: adc: xilinx: use helper variable for &pdev->dev + +From: Bartosz Golaszewski + +[ Upstream commit 9d8fd2a06a2bcce8eada1bad26cbe0fbfc27cdf4 ] + +It's more elegant to use a helper local variable to store the address +of the underlying struct device than to dereference pdev everywhere. + +Signed-off-by: Bartosz Golaszewski +Tested-by: Anand Ashok Dumbre +Reviewed-by: Anand Ashok Dumbre +Link: https://lore.kernel.org/r/20201130142759.28216-2-brgl@bgdev.pl +Signed-off-by: Jonathan Cameron +Stable-dep-of: 8d6b3ea4d9ea ("iio: adc: xilinx-xadc: Don't clobber preset voltage/temperature thresholds") +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/xilinx-xadc-core.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c +index f93c34fe58731..8494eb424b331 100644 +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -1186,6 +1186,7 @@ static int xadc_parse_dt(struct iio_dev *indio_dev, struct device_node *np, + + static int xadc_probe(struct platform_device *pdev) + { ++ struct device *dev = &pdev->dev; + const struct of_device_id *id; + struct iio_dev *indio_dev; + unsigned int bipolar_mask; +@@ -1195,10 +1196,10 @@ static int xadc_probe(struct platform_device *pdev) + int irq; + int i; + +- if (!pdev->dev.of_node) ++ if (!dev->of_node) + return -ENODEV; + +- id = of_match_node(xadc_of_match_table, pdev->dev.of_node); ++ id = of_match_node(xadc_of_match_table, dev->of_node); + if (!id) + return -EINVAL; + +@@ -1206,7 +1207,7 @@ static int xadc_probe(struct platform_device *pdev) + if (irq <= 0) + return -ENXIO; + +- indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*xadc)); ++ indio_dev = devm_iio_device_alloc(dev, sizeof(*xadc)); + if (!indio_dev) + return -ENOMEM; + +@@ -1226,7 +1227,7 @@ static int xadc_probe(struct platform_device *pdev) + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &xadc_info; + +- ret = xadc_parse_dt(indio_dev, pdev->dev.of_node, &conf0); ++ ret = xadc_parse_dt(indio_dev, dev->of_node, &conf0); + if (ret) + return ret; + +@@ -1250,7 +1251,7 @@ static int xadc_probe(struct platform_device *pdev) + } + } + +- xadc->clk = devm_clk_get(&pdev->dev, NULL); ++ xadc->clk = devm_clk_get(dev, NULL); + if (IS_ERR(xadc->clk)) { + ret = PTR_ERR(xadc->clk); + goto err_free_samplerate_trigger; +@@ -1276,7 +1277,7 @@ static int xadc_probe(struct platform_device *pdev) + } + + ret = request_irq(xadc->irq, xadc->ops->interrupt_handler, 0, +- dev_name(&pdev->dev), indio_dev); ++ dev_name(dev), indio_dev); + if (ret) + goto err_clk_disable_unprepare; + +-- +2.42.0 + diff --git a/queue-5.10/iio-adc-xilinx-use-more-devres-helpers-and-remove-re.patch b/queue-5.10/iio-adc-xilinx-use-more-devres-helpers-and-remove-re.patch new file mode 100644 index 00000000000..0475cbf35c5 --- /dev/null +++ b/queue-5.10/iio-adc-xilinx-use-more-devres-helpers-and-remove-re.patch @@ -0,0 +1,266 @@ +From 24785958e5d2c40b503b17a6e79305584ce75677 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Nov 2020 15:27:59 +0100 +Subject: iio: adc: xilinx: use more devres helpers and remove remove() + +From: Bartosz Golaszewski + +[ Upstream commit 2a9685d1a3b7644ca08d8355fc238b43faef7c3e ] + +In order to simplify resource management and error paths in probe() and +entirely drop the remove() callback - use devres helpers wherever +possible. Define devm actions for cancelling the delayed work and +disabling the clock. + +Signed-off-by: Bartosz Golaszewski +Tested-by: Anand Ashok Dumbre +Reviewed-by: Anand Ashok Dumbre +Link: https://lore.kernel.org/r/20201130142759.28216-4-brgl@bgdev.pl +Signed-off-by: Jonathan Cameron +Stable-dep-of: 8d6b3ea4d9ea ("iio: adc: xilinx-xadc: Don't clobber preset voltage/temperature thresholds") +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/xilinx-xadc-core.c | 133 ++++++++++++----------------- + 1 file changed, 55 insertions(+), 78 deletions(-) + +diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c +index 6f89a97bb127b..fec266682e91d 100644 +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -713,11 +713,12 @@ static const struct iio_trigger_ops xadc_trigger_ops = { + static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev, + const char *name) + { ++ struct device *dev = indio_dev->dev.parent; + struct iio_trigger *trig; + int ret; + +- trig = iio_trigger_alloc("%s%d-%s", indio_dev->name, +- indio_dev->id, name); ++ trig = devm_iio_trigger_alloc(dev, "%s%d-%s", indio_dev->name, ++ indio_dev->id, name); + if (trig == NULL) + return ERR_PTR(-ENOMEM); + +@@ -725,15 +726,11 @@ static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev, + trig->ops = &xadc_trigger_ops; + iio_trigger_set_drvdata(trig, iio_priv(indio_dev)); + +- ret = iio_trigger_register(trig); ++ ret = devm_iio_trigger_register(dev, trig); + if (ret) +- goto error_free_trig; ++ return ERR_PTR(ret); + + return trig; +- +-error_free_trig: +- iio_trigger_free(trig); +- return ERR_PTR(ret); + } + + static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode) +@@ -1192,6 +1189,20 @@ static int xadc_parse_dt(struct iio_dev *indio_dev, struct device_node *np, + return 0; + } + ++static void xadc_clk_disable_unprepare(void *data) ++{ ++ struct clk *clk = data; ++ ++ clk_disable_unprepare(clk); ++} ++ ++static void xadc_cancel_delayed_work(void *data) ++{ ++ struct delayed_work *work = data; ++ ++ cancel_delayed_work_sync(work); ++} ++ + static int xadc_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -1240,34 +1251,35 @@ static int xadc_probe(struct platform_device *pdev) + return ret; + + if (xadc->ops->flags & XADC_FLAGS_BUFFERED) { +- ret = iio_triggered_buffer_setup(indio_dev, +- &iio_pollfunc_store_time, &xadc_trigger_handler, +- &xadc_buffer_ops); ++ ret = devm_iio_triggered_buffer_setup(dev, indio_dev, ++ &iio_pollfunc_store_time, ++ &xadc_trigger_handler, ++ &xadc_buffer_ops); + if (ret) + return ret; + + xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst"); +- if (IS_ERR(xadc->convst_trigger)) { +- ret = PTR_ERR(xadc->convst_trigger); +- goto err_triggered_buffer_cleanup; +- } ++ if (IS_ERR(xadc->convst_trigger)) ++ return PTR_ERR(xadc->convst_trigger); ++ + xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev, + "samplerate"); +- if (IS_ERR(xadc->samplerate_trigger)) { +- ret = PTR_ERR(xadc->samplerate_trigger); +- goto err_free_convst_trigger; +- } ++ if (IS_ERR(xadc->samplerate_trigger)) ++ return PTR_ERR(xadc->samplerate_trigger); + } + + xadc->clk = devm_clk_get(dev, NULL); +- if (IS_ERR(xadc->clk)) { +- ret = PTR_ERR(xadc->clk); +- goto err_free_samplerate_trigger; +- } ++ if (IS_ERR(xadc->clk)) ++ return PTR_ERR(xadc->clk); + + ret = clk_prepare_enable(xadc->clk); + if (ret) +- goto err_free_samplerate_trigger; ++ return ret; ++ ++ ret = devm_add_action_or_reset(dev, ++ xadc_clk_disable_unprepare, xadc->clk); ++ if (ret) ++ return ret; + + /* + * Make sure not to exceed the maximum samplerate since otherwise the +@@ -1276,22 +1288,28 @@ static int xadc_probe(struct platform_device *pdev) + if (xadc->ops->flags & XADC_FLAGS_BUFFERED) { + ret = xadc_read_samplerate(xadc); + if (ret < 0) +- goto err_free_samplerate_trigger; ++ return ret; ++ + if (ret > XADC_MAX_SAMPLERATE) { + ret = xadc_write_samplerate(xadc, XADC_MAX_SAMPLERATE); + if (ret < 0) +- goto err_free_samplerate_trigger; ++ return ret; + } + } + +- ret = request_irq(xadc->irq, xadc->ops->interrupt_handler, 0, +- dev_name(dev), indio_dev); ++ ret = devm_request_irq(dev, xadc->irq, xadc->ops->interrupt_handler, 0, ++ dev_name(dev), indio_dev); ++ if (ret) ++ return ret; ++ ++ ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work, ++ &xadc->zynq_unmask_work); + if (ret) +- goto err_clk_disable_unprepare; ++ return ret; + + ret = xadc->ops->setup(pdev, indio_dev, xadc->irq); + if (ret) +- goto err_free_irq; ++ return ret; + + for (i = 0; i < 16; i++) + xadc_read_adc_reg(xadc, XADC_REG_THRESHOLD(i), +@@ -1299,7 +1317,7 @@ static int xadc_probe(struct platform_device *pdev) + + ret = xadc_write_adc_reg(xadc, XADC_REG_CONF0, conf0); + if (ret) +- goto err_free_irq; ++ return ret; + + bipolar_mask = 0; + for (i = 0; i < indio_dev->num_channels; i++) { +@@ -1309,17 +1327,18 @@ static int xadc_probe(struct platform_device *pdev) + + ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(0), bipolar_mask); + if (ret) +- goto err_free_irq; ++ return ret; ++ + ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(1), + bipolar_mask >> 16); + if (ret) +- goto err_free_irq; ++ return ret; + + /* Disable all alarms */ + ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_ALARM_MASK, + XADC_CONF1_ALARM_MASK); + if (ret) +- goto err_free_irq; ++ return ret; + + /* Set thresholds to min/max */ + for (i = 0; i < 16; i++) { +@@ -1334,59 +1353,17 @@ static int xadc_probe(struct platform_device *pdev) + ret = xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i), + xadc->threshold[i]); + if (ret) +- goto err_free_irq; ++ return ret; + } + + /* Go to non-buffered mode */ + xadc_postdisable(indio_dev); + +- ret = iio_device_register(indio_dev); +- if (ret) +- goto err_free_irq; +- +- platform_set_drvdata(pdev, indio_dev); +- +- return 0; +- +-err_free_irq: +- free_irq(xadc->irq, indio_dev); +- cancel_delayed_work_sync(&xadc->zynq_unmask_work); +-err_clk_disable_unprepare: +- clk_disable_unprepare(xadc->clk); +-err_free_samplerate_trigger: +- if (xadc->ops->flags & XADC_FLAGS_BUFFERED) +- iio_trigger_free(xadc->samplerate_trigger); +-err_free_convst_trigger: +- if (xadc->ops->flags & XADC_FLAGS_BUFFERED) +- iio_trigger_free(xadc->convst_trigger); +-err_triggered_buffer_cleanup: +- if (xadc->ops->flags & XADC_FLAGS_BUFFERED) +- iio_triggered_buffer_cleanup(indio_dev); +- +- return ret; +-} +- +-static int xadc_remove(struct platform_device *pdev) +-{ +- struct iio_dev *indio_dev = platform_get_drvdata(pdev); +- struct xadc *xadc = iio_priv(indio_dev); +- +- iio_device_unregister(indio_dev); +- if (xadc->ops->flags & XADC_FLAGS_BUFFERED) { +- iio_trigger_free(xadc->samplerate_trigger); +- iio_trigger_free(xadc->convst_trigger); +- iio_triggered_buffer_cleanup(indio_dev); +- } +- free_irq(xadc->irq, indio_dev); +- cancel_delayed_work_sync(&xadc->zynq_unmask_work); +- clk_disable_unprepare(xadc->clk); +- +- return 0; ++ return devm_iio_device_register(dev, indio_dev); + } + + static struct platform_driver xadc_driver = { + .probe = xadc_probe, +- .remove = xadc_remove, + .driver = { + .name = "xadc", + .of_match_table = xadc_of_match_table, +-- +2.42.0 + diff --git a/queue-5.10/iio-adc-xilinx-xadc-don-t-clobber-preset-voltage-tem.patch b/queue-5.10/iio-adc-xilinx-xadc-don-t-clobber-preset-voltage-tem.patch new file mode 100644 index 00000000000..2efbda931a3 --- /dev/null +++ b/queue-5.10/iio-adc-xilinx-xadc-don-t-clobber-preset-voltage-tem.patch @@ -0,0 +1,74 @@ +From 9c2528f8b330dda82ad8f1d021edc591e6fa95c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 18:10:18 -0600 +Subject: iio: adc: xilinx-xadc: Don't clobber preset voltage/temperature + thresholds + +From: Robert Hancock + +[ Upstream commit 8d6b3ea4d9eaca80982442b68a292ce50ce0a135 ] + +In the probe function, the driver was reading out the thresholds already +set in the core, which can be configured by the user in the Vivado tools +when the FPGA image is built. However, it later clobbered those values +with zero or maximum values. In particular, the overtemperature shutdown +threshold register was overwritten with the max value, which effectively +prevents the FPGA from shutting down when the desired threshold was +eached, potentially risking hardware damage in that case. + +Remove this code to leave the preconfigured default threshold values +intact. + +The code was also disabling all alarms regardless of what enable state +they were left in by the FPGA image, including the overtemperature +shutdown feature. Leave these bits in their original state so they are +not unconditionally disabled. + +Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver") +Signed-off-by: Robert Hancock +Acked-by: O'Griofa, Conall +Tested-by: O'Griofa, Conall +Link: https://lore.kernel.org/r/20230915001019.2862964-2-robert.hancock@calian.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/xilinx-xadc-core.c | 22 ---------------------- + 1 file changed, 22 deletions(-) + +diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c +index fec266682e91d..30b5a17ce41a7 100644 +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -1334,28 +1334,6 @@ static int xadc_probe(struct platform_device *pdev) + if (ret) + return ret; + +- /* Disable all alarms */ +- ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_ALARM_MASK, +- XADC_CONF1_ALARM_MASK); +- if (ret) +- return ret; +- +- /* Set thresholds to min/max */ +- for (i = 0; i < 16; i++) { +- /* +- * Set max voltage threshold and both temperature thresholds to +- * 0xffff, min voltage threshold to 0. +- */ +- if (i % 8 < 4 || i == 7) +- xadc->threshold[i] = 0xffff; +- else +- xadc->threshold[i] = 0; +- ret = xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i), +- xadc->threshold[i]); +- if (ret) +- return ret; +- } +- + /* Go to non-buffered mode */ + xadc_postdisable(indio_dev); + +-- +2.42.0 + diff --git a/queue-5.10/series b/queue-5.10/series index d3bd087cbfc..c2b6022cffe 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -39,3 +39,11 @@ nvmem-imx-correct-nregs-for-i.mx6ul.patch perf-core-fix-potential-null-deref.patch sparc32-fix-a-braino-in-fault-handling-in-csum_and_copy_..._user.patch clk-sanitize-possible_parent_show-to-handle-return-value-of-of_clk_get_parent_name.patch +iio-adc-xilinx-use-helper-variable-for-pdev-dev.patch +iio-adc-xilinx-use-devm_krealloc-instead-of-kfree-kc.patch +iio-adc-xilinx-use-more-devres-helpers-and-remove-re.patch +iio-adc-xilinx-xadc-don-t-clobber-preset-voltage-tem.patch +acpica-add-support-for-madt-online-enabled-bit.patch +x86-acpi-don-t-add-cpus-that-are-not-online-capable.patch +x86-acpi-boot-use-fadt-version-to-check-support-for-.patch +x86-i8259-skip-probing-when-acpi-madt-advertises-pca.patch diff --git a/queue-5.10/x86-acpi-boot-use-fadt-version-to-check-support-for-.patch b/queue-5.10/x86-acpi-boot-use-fadt-version-to-check-support-for-.patch new file mode 100644 index 00000000000..0498637a993 --- /dev/null +++ b/queue-5.10/x86-acpi-boot-use-fadt-version-to-check-support-for-.patch @@ -0,0 +1,55 @@ +From cf8da7f357c25cfa1fb0b78c3ad744e071e8d798 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Mar 2023 12:45:35 -0500 +Subject: x86/ACPI/boot: Use FADT version to check support for online capable + +From: Mario Limonciello + +[ Upstream commit a74fabfbd1b7013045afc8cc541e6cab3360ccb5 ] + +ACPI 6.3 introduced the online capable bit, and also introduced MADT +version 5. + +Latter was used to distinguish whether the offset storing online capable +could be used. However ACPI 6.2b has MADT version "45" which is for +an errata version of the ACPI 6.2 spec. This means that the Linux code +for detecting availability of MADT will mistakenly flag ACPI 6.2b as +supporting online capable which is inaccurate as it's an ACPI 6.3 feature. + +Instead use the FADT major and minor revision fields to distinguish this. + + [ bp: Massage. ] + +Fixes: aa06e20f1be6 ("x86/ACPI: Don't add CPUs that are not online capable") +Reported-by: Eric DeVolder +Reported-by: Borislav Petkov +Signed-off-by: Mario Limonciello +Signed-off-by: Borislav Petkov (AMD) +Cc: +Link: https://lore.kernel.org/r/943d2445-84df-d939-f578-5d8240d342cc@unsolicited.net +Stable-dep-of: 128b0c9781c9 ("x86/i8259: Skip probing when ACPI/MADT advertises PCAT compatibility") +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/acpi/boot.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index 7840e650f452a..2f7f72b6f1235 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -141,7 +141,11 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) + printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", + madt->address); + } +- if (madt->header.revision >= 5) ++ ++ /* ACPI 6.3 and newer support the online capable bit. */ ++ if (acpi_gbl_FADT.header.revision > 6 || ++ (acpi_gbl_FADT.header.revision == 6 && ++ acpi_gbl_FADT.minor_revision >= 3)) + acpi_support_online_capable = true; + + default_acpi_madt_oem_check(madt->header.oem_id, +-- +2.42.0 + diff --git a/queue-5.10/x86-acpi-don-t-add-cpus-that-are-not-online-capable.patch b/queue-5.10/x86-acpi-don-t-add-cpus-that-are-not-online-capable.patch new file mode 100644 index 00000000000..cb1853ff1d4 --- /dev/null +++ b/queue-5.10/x86-acpi-don-t-add-cpus-that-are-not-online-capable.patch @@ -0,0 +1,64 @@ +From a7d395fab9e1231f558746ce56d13f4406fa7fa9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Sep 2021 16:41:46 -0500 +Subject: x86/ACPI: Don't add CPUs that are not online capable + +From: Mario Limonciello + +[ Upstream commit aa06e20f1be628186f0c2dcec09ea0009eb69778 ] + +A number of systems are showing "hotplug capable" CPUs when they +are not really hotpluggable. This is because the MADT has extra +CPU entries to support different CPUs that may be inserted into +the socket with different numbers of cores. + +Starting with ACPI 6.3 the spec has an Online Capable bit in the +MADT used to determine whether or not a CPU is hotplug capable +when the enabled bit is not set. + +Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html?#local-apic-flags +Signed-off-by: Mario Limonciello +Signed-off-by: Rafael J. Wysocki +Stable-dep-of: 128b0c9781c9 ("x86/i8259: Skip probing when ACPI/MADT advertises PCAT compatibility") +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/acpi/boot.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index 55562a9b7f92e..7840e650f452a 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -63,6 +63,7 @@ int acpi_fix_pin2_polarity __initdata; + + #ifdef CONFIG_X86_LOCAL_APIC + static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; ++static bool acpi_support_online_capable; + #endif + + #ifdef CONFIG_X86_IO_APIC +@@ -140,6 +141,8 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) + printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", + madt->address); + } ++ if (madt->header.revision >= 5) ++ acpi_support_online_capable = true; + + default_acpi_madt_oem_check(madt->header.oem_id, + madt->header.oem_table_id); +@@ -241,6 +244,12 @@ acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end) + if (processor->id == 0xff) + return 0; + ++ /* don't register processors that can not be onlined */ ++ if (acpi_support_online_capable && ++ !(processor->lapic_flags & ACPI_MADT_ENABLED) && ++ !(processor->lapic_flags & ACPI_MADT_ONLINE_CAPABLE)) ++ return 0; ++ + /* + * We need to register disabled CPU as well to permit + * counting disabled CPUs. This allows us to size +-- +2.42.0 + diff --git a/queue-5.10/x86-i8259-skip-probing-when-acpi-madt-advertises-pca.patch b/queue-5.10/x86-i8259-skip-probing-when-acpi-madt-advertises-pca.patch new file mode 100644 index 00000000000..a999e76690f --- /dev/null +++ b/queue-5.10/x86-i8259-skip-probing-when-acpi-madt-advertises-pca.patch @@ -0,0 +1,151 @@ +From 8a6394357ea2e57d2f829b13d2c4abf3dccd5cfa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 23:04:15 +0200 +Subject: x86/i8259: Skip probing when ACPI/MADT advertises PCAT compatibility + +From: Thomas Gleixner + +[ Upstream commit 128b0c9781c9f2651bea163cb85e52a6c7be0f9e ] + +David and a few others reported that on certain newer systems some legacy +interrupts fail to work correctly. + +Debugging revealed that the BIOS of these systems leaves the legacy PIC in +uninitialized state which makes the PIC detection fail and the kernel +switches to a dummy implementation. + +Unfortunately this fallback causes quite some code to fail as it depends on +checks for the number of legacy PIC interrupts or the availability of the +real PIC. + +In theory there is no reason to use the PIC on any modern system when +IO/APIC is available, but the dependencies on the related checks cannot be +resolved trivially and on short notice. This needs lots of analysis and +rework. + +The PIC detection has been added to avoid quirky checks and force selection +of the dummy implementation all over the place, especially in VM guest +scenarios. So it's not an option to revert the relevant commit as that +would break a lot of other scenarios. + +One solution would be to try to initialize the PIC on detection fail and +retry the detection, but that puts the burden on everything which does not +have a PIC. + +Fortunately the ACPI/MADT table header has a flag field, which advertises +in bit 0 that the system is PCAT compatible, which means it has a legacy +8259 PIC. + +Evaluate that bit and if set avoid the detection routine and keep the real +PIC installed, which then gets initialized (for nothing) and makes the rest +of the code with all the dependencies work again. + +Fixes: e179f6914152 ("x86, irq, pic: Probe for legacy PIC and set legacy_pic appropriately") +Reported-by: David Lazar +Signed-off-by: Thomas Gleixner +Tested-by: David Lazar +Reviewed-by: Hans de Goede +Reviewed-by: Mario Limonciello +Cc: stable@vger.kernel.org +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218003 +Link: https://lore.kernel.org/r/875y2u5s8g.ffs@tglx +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/i8259.h | 2 ++ + arch/x86/kernel/acpi/boot.c | 3 +++ + arch/x86/kernel/i8259.c | 38 ++++++++++++++++++++++++++++-------- + 3 files changed, 35 insertions(+), 8 deletions(-) + +diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h +index 89789e8c80f66..e16574c16e933 100644 +--- a/arch/x86/include/asm/i8259.h ++++ b/arch/x86/include/asm/i8259.h +@@ -67,6 +67,8 @@ struct legacy_pic { + void (*make_irq)(unsigned int irq); + }; + ++void legacy_pic_pcat_compat(void); ++ + extern struct legacy_pic *legacy_pic; + extern struct legacy_pic null_legacy_pic; + +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index 2f7f72b6f1235..5f325d9204455 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -142,6 +142,9 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) + madt->address); + } + ++ if (madt->flags & ACPI_MADT_PCAT_COMPAT) ++ legacy_pic_pcat_compat(); ++ + /* ACPI 6.3 and newer support the online capable bit. */ + if (acpi_gbl_FADT.header.revision > 6 || + (acpi_gbl_FADT.header.revision == 6 && +diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c +index f325389d03516..4c9f559e1388b 100644 +--- a/arch/x86/kernel/i8259.c ++++ b/arch/x86/kernel/i8259.c +@@ -32,6 +32,7 @@ + */ + static void init_8259A(int auto_eoi); + ++static bool pcat_compat __ro_after_init; + static int i8259A_auto_eoi; + DEFINE_RAW_SPINLOCK(i8259A_lock); + +@@ -301,15 +302,32 @@ static void unmask_8259A(void) + + static int probe_8259A(void) + { ++ unsigned char new_val, probe_val = ~(1 << PIC_CASCADE_IR); + unsigned long flags; +- unsigned char probe_val = ~(1 << PIC_CASCADE_IR); +- unsigned char new_val; ++ ++ /* ++ * If MADT has the PCAT_COMPAT flag set, then do not bother probing ++ * for the PIC. Some BIOSes leave the PIC uninitialized and probing ++ * fails. ++ * ++ * Right now this causes problems as quite some code depends on ++ * nr_legacy_irqs() > 0 or has_legacy_pic() == true. This is silly ++ * when the system has an IO/APIC because then PIC is not required ++ * at all, except for really old machines where the timer interrupt ++ * must be routed through the PIC. So just pretend that the PIC is ++ * there and let legacy_pic->init() initialize it for nothing. ++ * ++ * Alternatively this could just try to initialize the PIC and ++ * repeat the probe, but for cases where there is no PIC that's ++ * just pointless. ++ */ ++ if (pcat_compat) ++ return nr_legacy_irqs(); ++ + /* +- * Check to see if we have a PIC. +- * Mask all except the cascade and read +- * back the value we just wrote. If we don't +- * have a PIC, we will read 0xff as opposed to the +- * value we wrote. ++ * Check to see if we have a PIC. Mask all except the cascade and ++ * read back the value we just wrote. If we don't have a PIC, we ++ * will read 0xff as opposed to the value we wrote. + */ + raw_spin_lock_irqsave(&i8259A_lock, flags); + +@@ -431,5 +449,9 @@ static int __init i8259A_init_ops(void) + + return 0; + } +- + device_initcall(i8259A_init_ops); ++ ++void __init legacy_pic_pcat_compat(void) ++{ ++ pcat_compat = true; ++} +-- +2.42.0 +