From feabecaff5902f896531dde90646ca5dfa9d4f7d Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 17 Aug 2022 23:00:45 +0300 Subject: [PATCH 01/30] genirq/ipi: Fix NULL pointer deref in irq_data_get_affinity_mask() If ipi_send_{mask|single}() is called with an invalid interrupt number, all the local variables there will be NULL. ipi_send_verify() which is invoked from these functions does verify its 'data' parameter, resulting in a kernel oops in irq_data_get_affinity_mask() as the passed NULL pointer gets dereferenced. Add a missing NULL pointer check in ipi_send_verify()... Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Fixes: 3b8e29a82dd1 ("genirq: Implement ipi_send_mask/single()") Signed-off-by: Sergey Shtylyov Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/b541232d-c2b6-1fe9-79b4-a7129459e4d0@omp.ru --- kernel/irq/ipi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index bbd945bacef0..961d4af76af3 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -188,9 +188,9 @@ EXPORT_SYMBOL_GPL(ipi_get_hwirq); static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data, const struct cpumask *dest, unsigned int cpu) { - const struct cpumask *ipimask = irq_data_get_affinity_mask(data); + const struct cpumask *ipimask; - if (!chip || !ipimask) + if (!chip || !data) return -EINVAL; if (!chip->ipi_send_single && !chip->ipi_send_mask) @@ -199,6 +199,10 @@ static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data, if (cpu >= nr_cpu_ids) return -EINVAL; + ipimask = irq_data_get_affinity_mask(data); + if (!ipimask) + return -EINVAL; + if (dest) { if (!cpumask_subset(dest, ipimask)) return -EINVAL; From 0af2795f936f1ea1f9f1497447145dfcc7ed2823 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 20 Feb 2023 19:01:01 +0000 Subject: [PATCH 02/30] genirq/msi: Take the per-device MSI lock before validating the control structure Calling msi_ctrl_valid() ultimately results in calling msi_get_device_domain(), which requires holding the device MSI lock. However, in msi_domain_populate_irqs() the lock is taken right after having called msi_ctrl_valid(), which is just a tad too late. Take the lock before invoking msi_ctrl_valid(). Fixes: 40742716f294 ("genirq/msi: Make msi_add_simple_msi_descs() device domain aware") Reported-by: "Russell King (Oracle)" Signed-off-by: Marc Zyngier Signed-off-by: Thomas Gleixner Tested-by: Russell King (Oracle) Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/Y/Opu6ETe3ZzZ/8E@shell.armlinux.org.uk Link: https://lore.kernel.org/r/20230220190101.314446-1-maz@kernel.org --- kernel/irq/msi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 783a3e6a0b10..13d96495e6d0 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -1084,10 +1084,13 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, struct xarray *xa; int ret, virq; - if (!msi_ctrl_valid(dev, &ctrl)) - return -EINVAL; - msi_lock_descs(dev); + + if (!msi_ctrl_valid(dev, &ctrl)) { + ret = -EINVAL; + goto unlock; + } + ret = msi_domain_add_simple_msi_descs(dev, &ctrl); if (ret) goto unlock; From e6cc6f175566dd21a3f6e384c24593b1c751dd74 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Tue, 14 Feb 2023 13:13:20 -0800 Subject: [PATCH 03/30] PCI/MSI: Clarify usage of pci_msix_free_irq() pci_msix_free_irq() is used to free an interrupt on a PCI/MSI-X interrupt domain. The API description specifies that the interrupt to be freed was allocated via pci_msix_alloc_irq_at(). This description limits the usage of pci_msix_free_irq() since pci_msix_free_irq() can also be used to free MSI-X interrupts allocated with, for example, pci_alloc_irq_vectors(). Remove the text stating that the interrupt to be freed had to be allocated with pci_msix_alloc_irq_at(). The needed struct msi_map need not be from pci_msix_alloc_irq_at() but can be created from scratch using pci_irq_vector() to obtain the Linux IRQ number. Highlight that pci_msix_free_irq() cannot be used to disable MSI-X to guide users that, for example, pci_free_irq_vectors() remains to be needed. Signed-off-by: Reinette Chatre Signed-off-by: Thomas Gleixner Reviewed-by: Kevin Tian Link: https://lore.kernel.org/lkml/87r0xsd8j4.ffs@tglx Link: https://lore.kernel.org/r/4c3e7a50d6e70f408812cd7ab199c6b4b326f9de.1676408572.git.reinette.chatre@intel.com --- drivers/pci/msi/api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/msi/api.c b/drivers/pci/msi/api.c index b8009aa11f3c..be679aa5db64 100644 --- a/drivers/pci/msi/api.c +++ b/drivers/pci/msi/api.c @@ -163,11 +163,11 @@ EXPORT_SYMBOL_GPL(pci_msix_alloc_irq_at); /** * pci_msix_free_irq - Free an interrupt on a PCI/MSIX interrupt domain - * which was allocated via pci_msix_alloc_irq_at() * * @dev: The PCI device to operate on * @map: A struct msi_map describing the interrupt to free - * as returned from the allocation function. + * + * Undo an interrupt vector allocation. Does not disable MSI-X. */ void pci_msix_free_irq(struct pci_dev *dev, struct msi_map map) { From ce7980ae9080f72f08d50355c4d9084d57aece63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Fri, 17 Feb 2023 03:16:25 +0000 Subject: [PATCH 04/30] genirq/irqdesc: Make kobj_type structures constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit ee6d3dd4ed48 ("driver core: make kobj_type constant.") the driver core allows the usage of const struct kobj_type. Take advantage of this to constify the structure definitions which prevents modification at runtime. Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20230217-kobj_type-irq-v1-1-fedfacaf8cdb@weissschuh.net --- kernel/irq/irqdesc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index fd0996274401..240e145e969f 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -277,7 +277,7 @@ static struct attribute *irq_attrs[] = { }; ATTRIBUTE_GROUPS(irq); -static struct kobj_type irq_kobj_type = { +static const struct kobj_type irq_kobj_type = { .release = irq_kobj_release, .sysfs_ops = &kobj_sysfs_ops, .default_groups = irq_groups, @@ -335,7 +335,7 @@ postcore_initcall(irq_sysfs_init); #else /* !CONFIG_SYSFS */ -static struct kobj_type irq_kobj_type = { +static const struct kobj_type irq_kobj_type = { .release = irq_kobj_release, }; From ad32ab9604f29827494024828f527228e84fbd2c Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 23 Feb 2023 09:38:00 +0100 Subject: [PATCH 05/30] irqdomain: Add missing NULL pointer check in irq_domain_create_hierarchy() The recent switch to per-domain locking caused a NULL dereference in irq_domain_create_hierarchy(), as Xen code is calling msi_create_irq_domain() with a NULL parent pointer. Fix that by testing parent to be set before dereferencing it. For a non-existing parent the irqdomain's root will stay to point to itself. Fixes: 9dbb8e3452ab ("irqdomain: Switch to per-domain locking") Signed-off-by: Juergen Gross Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20230223083800.31347-1-jgross@suse.com --- kernel/irq/irqdomain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index aa5b7eeeceb8..6522dfb2e49c 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1172,7 +1172,8 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent, domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data); if (domain) { - domain->root = parent->root; + if (parent) + domain->root = parent->root; domain->parent = parent; domain->flags |= flags; From ea9a78c3a7a44e36fa690e1cc90dc2a758c8eb9a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 24 Feb 2023 14:05:09 +0100 Subject: [PATCH 06/30] genirq/msi: Drop dead domain name assignment Since commit d59f6617eef0 ("genirq: Allow fwnode to carry name information only") an IRQ domain is always given a name during allocation (e.g. used for the debugfs entry). Drop the unused fallback name assignment when creating MSI domains. Signed-off-by: Johan Hovold Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20230224130509.27814-1-johan+linaro@kernel.org --- kernel/irq/msi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 13d96495e6d0..efd21b79bf32 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -830,11 +830,8 @@ static struct irq_domain *__msi_create_irq_domain(struct fwnode_handle *fwnode, domain = irq_domain_create_hierarchy(parent, flags | IRQ_DOMAIN_FLAG_MSI, 0, fwnode, &msi_domain_ops, info); - if (domain) { - if (!domain->name && info->chip) - domain->name = info->chip->name; + if (domain) irq_domain_update_bus_token(domain, info->bus_token); - } return domain; } From 6921ed9049bc7457f66c1596c5b78aec0dae4a9d Mon Sep 17 00:00:00 2001 From: KP Singh Date: Mon, 27 Feb 2023 07:05:40 +0100 Subject: [PATCH 07/30] x86/speculation: Allow enabling STIBP with legacy IBRS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When plain IBRS is enabled (not enhanced IBRS), the logic in spectre_v2_user_select_mitigation() determines that STIBP is not needed. The IBRS bit implicitly protects against cross-thread branch target injection. However, with legacy IBRS, the IBRS bit is cleared on returning to userspace for performance reasons which leaves userspace threads vulnerable to cross-thread branch target injection against which STIBP protects. Exclude IBRS from the spectre_v2_in_ibrs_mode() check to allow for enabling STIBP (through seccomp/prctl() by default or always-on, if selected by spectre_v2_user kernel cmdline parameter). [ bp: Massage. ] Fixes: 7c693f54c873 ("x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS") Reported-by: José Oliveira Reported-by: Rodrigo Branco Signed-off-by: KP Singh Signed-off-by: Borislav Petkov (AMD) Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230220120127.1975241-1-kpsingh@kernel.org Link: https://lore.kernel.org/r/20230221184908.2349578-1-kpsingh@kernel.org --- arch/x86/kernel/cpu/bugs.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index cf81848b72f4..f9d060e71c3e 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1133,14 +1133,18 @@ spectre_v2_parse_user_cmdline(void) return SPECTRE_V2_USER_CMD_AUTO; } -static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode) +static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode) { - return mode == SPECTRE_V2_IBRS || - mode == SPECTRE_V2_EIBRS || + return mode == SPECTRE_V2_EIBRS || mode == SPECTRE_V2_EIBRS_RETPOLINE || mode == SPECTRE_V2_EIBRS_LFENCE; } +static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode) +{ + return spectre_v2_in_eibrs_mode(mode) || mode == SPECTRE_V2_IBRS; +} + static void __init spectre_v2_user_select_mitigation(void) { @@ -1203,12 +1207,19 @@ spectre_v2_user_select_mitigation(void) } /* - * If no STIBP, IBRS or enhanced IBRS is enabled, or SMT impossible, - * STIBP is not required. + * If no STIBP, enhanced IBRS is enabled, or SMT impossible, STIBP + * is not required. + * + * Enhanced IBRS also protects against cross-thread branch target + * injection in user-mode as the IBRS bit remains always set which + * implicitly enables cross-thread protections. However, in legacy IBRS + * mode, the IBRS bit is set only on kernel entry and cleared on return + * to userspace. This disables the implicit cross-thread protection, + * so allow for STIBP to be selected in that case. */ if (!boot_cpu_has(X86_FEATURE_STIBP) || !smt_possible || - spectre_v2_in_ibrs_mode(spectre_v2_enabled)) + spectre_v2_in_eibrs_mode(spectre_v2_enabled)) return; /* @@ -2340,7 +2351,7 @@ static ssize_t mmio_stale_data_show_state(char *buf) static char *stibp_state(void) { - if (spectre_v2_in_ibrs_mode(spectre_v2_enabled)) + if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) return ""; switch (spectre_v2_user_stibp) { From e02b50ca442e88122e1302d4dbc1b71a4808c13f Mon Sep 17 00:00:00 2001 From: KP Singh Date: Mon, 27 Feb 2023 07:05:41 +0100 Subject: [PATCH 08/30] Documentation/hw-vuln: Document the interaction between IBRS and STIBP Explain why STIBP is needed with legacy IBRS as currently implemented (KERNEL_IBRS) and why STIBP is not needed when enhanced IBRS is enabled. Fixes: 7c693f54c873 ("x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS") Signed-off-by: KP Singh Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20230227060541.1939092-2-kpsingh@kernel.org --- Documentation/admin-guide/hw-vuln/spectre.rst | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/hw-vuln/spectre.rst b/Documentation/admin-guide/hw-vuln/spectre.rst index 3fe6511c5405..4d186f599d90 100644 --- a/Documentation/admin-guide/hw-vuln/spectre.rst +++ b/Documentation/admin-guide/hw-vuln/spectre.rst @@ -479,8 +479,16 @@ Spectre variant 2 On Intel Skylake-era systems the mitigation covers most, but not all, cases. See :ref:`[3] ` for more details. - On CPUs with hardware mitigation for Spectre variant 2 (e.g. Enhanced - IBRS on x86), retpoline is automatically disabled at run time. + On CPUs with hardware mitigation for Spectre variant 2 (e.g. IBRS + or enhanced IBRS on x86), retpoline is automatically disabled at run time. + + Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at + boot, by setting the IBRS bit, and they're automatically protected against + Spectre v2 variant attacks, including cross-thread branch target injections + on SMT systems (STIBP). In other words, eIBRS enables STIBP too. + + Legacy IBRS systems clear the IBRS bit on exit to userspace and + therefore explicitly enable STIBP for that The retpoline mitigation is turned on by default on vulnerable CPUs. It can be forced on or off by the administrator @@ -504,9 +512,12 @@ Spectre variant 2 For Spectre variant 2 mitigation, individual user programs can be compiled with return trampolines for indirect branches. This protects them from consuming poisoned entries in the branch - target buffer left by malicious software. Alternatively, the - programs can disable their indirect branch speculation via prctl() - (See :ref:`Documentation/userspace-api/spec_ctrl.rst `). + target buffer left by malicious software. + + On legacy IBRS systems, at return to userspace, implicit STIBP is disabled + because the kernel clears the IBRS bit. In this case, the userspace programs + can disable indirect branch speculation via prctl() (See + :ref:`Documentation/userspace-api/spec_ctrl.rst `). On x86, this will turn on STIBP to guard against attacks from the sibling thread when the user program is running, and use IBPB to flush the branch target buffer when switching to/from the program. From 660ca9470f9c613fa2c71a123a9469c80a697ee4 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 27 Feb 2023 16:25:58 +0800 Subject: [PATCH 09/30] crypto: caam - Fix edesc/iv ordering mixup The attempt to add DMA alignment padding by moving IV to the front of edesc was completely broken as it didn't change the places where edesc was freed. It's also wrong as the IV may still share a cache-line with the edesc. Fix this by restoring the original layout and simply reserving enough memmory so that the IV is on a DMA cache-line by itself. Reported-by: Meenakshi Aggarwal Fixes: 199354d7fb6e ("crypto: caam - Remove GFP_DMA and add DMA alignment padding") Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 26 +++++++++++++++------ drivers/crypto/caam/caamalg_qi.c | 40 +++++++++++++++++++++----------- drivers/crypto/caam/qi.c | 10 ++++++-- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 4a9b998a8d26..12b1c8346243 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -60,7 +60,11 @@ #include #include #include +#include +#include #include +#include +#include /* * crypto alg @@ -1000,6 +1004,13 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err, crypto_finalize_aead_request(jrp->engine, req, ecode); } +static inline u8 *skcipher_edesc_iv(struct skcipher_edesc *edesc) +{ + + return PTR_ALIGN((u8 *)edesc->sec4_sg + edesc->sec4_sg_bytes, + dma_get_cache_alignment()); +} + static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err, void *context) { @@ -1027,8 +1038,7 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err, * This is used e.g. by the CTS mode. */ if (ivsize && !ecode) { - memcpy(req->iv, (u8 *)edesc->sec4_sg + edesc->sec4_sg_bytes, - ivsize); + memcpy(req->iv, skcipher_edesc_iv(edesc), ivsize); print_hex_dump_debug("dstiv @" __stringify(__LINE__)": ", DUMP_PREFIX_ADDRESS, 16, 4, req->iv, @@ -1683,18 +1693,19 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, /* * allocate space for base edesc and hw desc commands, link tables, IV */ - aligned_size = ALIGN(ivsize, __alignof__(*edesc)); - aligned_size += sizeof(*edesc) + desc_bytes + sec4_sg_bytes; + aligned_size = sizeof(*edesc) + desc_bytes + sec4_sg_bytes; aligned_size = ALIGN(aligned_size, dma_get_cache_alignment()); - iv = kzalloc(aligned_size, flags); - if (!iv) { + aligned_size += ~(ARCH_KMALLOC_MINALIGN - 1) & + (dma_get_cache_alignment() - 1); + aligned_size += ALIGN(ivsize, dma_get_cache_alignment()); + edesc = kzalloc(aligned_size, flags); + if (!edesc) { dev_err(jrdev, "could not allocate extended descriptor\n"); caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0, 0, 0, 0); return ERR_PTR(-ENOMEM); } - edesc = (void *)(iv + ALIGN(ivsize, __alignof__(*edesc))); edesc->src_nents = src_nents; edesc->dst_nents = dst_nents; edesc->mapped_src_nents = mapped_src_nents; @@ -1706,6 +1717,7 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, /* Make sure IV is located in a DMAable area */ if (ivsize) { + iv = skcipher_edesc_iv(edesc); memcpy(iv, req->iv, ivsize); iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_BIDIRECTIONAL); diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index 5e218bf20d5b..743ce50c14f2 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c @@ -20,8 +20,11 @@ #include "caamalg_desc.h" #include #include +#include +#include #include #include +#include /* * crypto alg @@ -1204,6 +1207,12 @@ static int ipsec_gcm_decrypt(struct aead_request *req) false); } +static inline u8 *skcipher_edesc_iv(struct skcipher_edesc *edesc) +{ + return PTR_ALIGN((u8 *)&edesc->sgt[0] + edesc->qm_sg_bytes, + dma_get_cache_alignment()); +} + static void skcipher_done(struct caam_drv_req *drv_req, u32 status) { struct skcipher_edesc *edesc; @@ -1236,8 +1245,7 @@ static void skcipher_done(struct caam_drv_req *drv_req, u32 status) * This is used e.g. by the CTS mode. */ if (!ecode) - memcpy(req->iv, (u8 *)&edesc->sgt[0] + edesc->qm_sg_bytes, - ivsize); + memcpy(req->iv, skcipher_edesc_iv(edesc), ivsize); qi_cache_free(edesc); skcipher_request_complete(req, ecode); @@ -1259,6 +1267,7 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, int dst_sg_idx, qm_sg_ents, qm_sg_bytes; struct qm_sg_entry *sg_table, *fd_sgt; struct caam_drv_ctx *drv_ctx; + unsigned int len; drv_ctx = get_drv_ctx(ctx, encrypt ? ENCRYPT : DECRYPT); if (IS_ERR(drv_ctx)) @@ -1319,9 +1328,12 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, qm_sg_ents = 1 + pad_sg_nents(qm_sg_ents); qm_sg_bytes = qm_sg_ents * sizeof(struct qm_sg_entry); - if (unlikely(ALIGN(ivsize, __alignof__(*edesc)) + - offsetof(struct skcipher_edesc, sgt) + qm_sg_bytes > - CAAM_QI_MEMCACHE_SIZE)) { + + len = offsetof(struct skcipher_edesc, sgt) + qm_sg_bytes; + len = ALIGN(len, dma_get_cache_alignment()); + len += ivsize; + + if (unlikely(len > CAAM_QI_MEMCACHE_SIZE)) { dev_err(qidev, "No space for %d S/G entries and/or %dB IV\n", qm_sg_ents, ivsize); caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, 0, @@ -1330,18 +1342,24 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, } /* allocate space for base edesc, link tables and IV */ - iv = qi_cache_alloc(flags); - if (unlikely(!iv)) { + edesc = qi_cache_alloc(flags); + if (unlikely(!edesc)) { dev_err(qidev, "could not allocate extended descriptor\n"); caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, 0, 0, DMA_NONE, 0, 0); return ERR_PTR(-ENOMEM); } - edesc = (void *)(iv + ALIGN(ivsize, __alignof__(*edesc))); + edesc->src_nents = src_nents; + edesc->dst_nents = dst_nents; + edesc->qm_sg_bytes = qm_sg_bytes; + edesc->drv_req.app_ctx = req; + edesc->drv_req.cbk = skcipher_done; + edesc->drv_req.drv_ctx = drv_ctx; /* Make sure IV is located in a DMAable area */ sg_table = &edesc->sgt[0]; + iv = skcipher_edesc_iv(edesc); memcpy(iv, req->iv, ivsize); iv_dma = dma_map_single(qidev, iv, ivsize, DMA_BIDIRECTIONAL); @@ -1353,13 +1371,7 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, return ERR_PTR(-ENOMEM); } - edesc->src_nents = src_nents; - edesc->dst_nents = dst_nents; edesc->iv_dma = iv_dma; - edesc->qm_sg_bytes = qm_sg_bytes; - edesc->drv_req.app_ctx = req; - edesc->drv_req.cbk = skcipher_done; - edesc->drv_req.drv_ctx = drv_ctx; dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0); sg_to_qm_sg(req->src, req->cryptlen, sg_table + 1, 0); diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c index 4c52c9365558..2ad2c1035856 100644 --- a/drivers/crypto/caam/qi.c +++ b/drivers/crypto/caam/qi.c @@ -8,7 +8,13 @@ */ #include +#include +#include +#include #include +#include +#include +#include #include #include "debugfs.h" @@ -755,8 +761,8 @@ int caam_qi_init(struct platform_device *caam_pdev) napi_enable(irqtask); } - qi_cache = kmem_cache_create("caamqicache", CAAM_QI_MEMCACHE_SIZE, 0, - 0, NULL); + qi_cache = kmem_cache_create("caamqicache", CAAM_QI_MEMCACHE_SIZE, + dma_get_cache_alignment(), 0, NULL); if (!qi_cache) { dev_err(qidev, "Can't allocate CAAM cache\n"); free_rsp_fqs(); From dd093fb08e8f8a958fec4eef36f9f09eac047f60 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Wed, 22 Feb 2023 10:39:39 -0600 Subject: [PATCH 10/30] virt/sev-guest: Return -EIO if certificate buffer is not large enough Commit 47894e0fa6a5 ("virt/sev-guest: Prevent IV reuse in the SNP guest driver") changed the behavior associated with the return value when the caller does not supply a large enough certificate buffer. Prior to the commit a value of -EIO was returned. Now, 0 is returned. This breaks the established ABI with the user. Change the code to detect the buffer size error and return -EIO. Fixes: 47894e0fa6a5 ("virt/sev-guest: Prevent IV reuse in the SNP guest driver") Reported-by: Larry Dewey Signed-off-by: Tom Lendacky Signed-off-by: Borislav Petkov (AMD) Tested-by: Larry Dewey Cc: Link: https://lore.kernel.org/r/2afbcae6daf13f7ad5a4296692e0a0fe1bc1e4ee.1677083979.git.thomas.lendacky@amd.com --- drivers/virt/coco/sev-guest/sev-guest.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c index 4ec4174e05a3..7b4e9009f335 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -377,9 +377,26 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in snp_dev->input.data_npages = certs_npages; } + /* + * Increment the message sequence number. There is no harm in doing + * this now because decryption uses the value stored in the response + * structure and any failure will wipe the VMPCK, preventing further + * use anyway. + */ + snp_inc_msg_seqno(snp_dev); + if (fw_err) *fw_err = err; + /* + * If an extended guest request was issued and the supplied certificate + * buffer was not large enough, a standard guest request was issued to + * prevent IV reuse. If the standard request was successful, return -EIO + * back to the caller as would have originally been returned. + */ + if (!rc && err == SNP_GUEST_REQ_INVALID_LEN) + return -EIO; + if (rc) { dev_alert(snp_dev->dev, "Detected error from ASP request. rc: %d, fw_err: %llu\n", @@ -395,9 +412,6 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in goto disable_vmpck; } - /* Increment to new message sequence after payload decryption was successful. */ - snp_inc_msg_seqno(snp_dev); - return 0; disable_vmpck: From 0fb7fb713461e44b12e72c292bf90ee300f40710 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 1 Mar 2023 22:07:48 +0100 Subject: [PATCH 11/30] genirq/msi, platform-msi: Ensure that MSI descriptors are unreferenced Miquel reported a warning in the MSI core which is triggered when interrupts are freed via platform_msi_device_domain_free(). This code got reworked to use core functions for freeing the MSI descriptors, but nothing took care to clear the msi_desc->irq entry, which then triggers the warning in msi_free_msi_desc() which uses desc->irq to validate that the descriptor has been torn down. The same issue exists in msi_domain_populate_irqs(). Up to the point that msi_free_msi_descs() grew a warning for this case, this went un-noticed. Provide the counterpart of msi_domain_populate_irqs() and invoke it in platform_msi_device_domain_free() before freeing the interrupts and MSI descriptors and also in the error path of msi_domain_populate_irqs(). Fixes: 2f2940d16823 ("genirq/msi: Remove filter from msi_free_descs_free_range()") Reported-by: Miquel Raynal Signed-off-by: Thomas Gleixner Tested-by: Miquel Raynal Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/87mt4wkwnv.ffs@tglx --- drivers/base/platform-msi.c | 1 + include/linux/msi.h | 2 ++ kernel/irq/msi.c | 23 ++++++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 5883e7634a2b..f37ad34c80ec 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -324,6 +324,7 @@ void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int vir struct platform_msi_priv_data *data = domain->host_data; msi_lock_descs(data->dev); + msi_domain_depopulate_descs(data->dev, virq, nr_irqs); irq_domain_free_irqs_common(domain, virq, nr_irqs); msi_free_msi_descs_range(data->dev, virq, virq + nr_irqs - 1); msi_unlock_descs(data->dev); diff --git a/include/linux/msi.h b/include/linux/msi.h index a112b913fff9..15dd71817996 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -631,6 +631,8 @@ int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev, int nvec, msi_alloc_info_t *args); int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, int virq, int nvec, msi_alloc_info_t *args); +void msi_domain_depopulate_descs(struct device *dev, int virq, int nvec); + struct irq_domain * __platform_msi_create_device_domain(struct device *dev, unsigned int nvec, diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index efd21b79bf32..d169ee0c1799 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -1109,14 +1109,35 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, return 0; fail: - for (--virq; virq >= virq_base; virq--) + for (--virq; virq >= virq_base; virq--) { + msi_domain_depopulate_descs(dev, virq, 1); irq_domain_free_irqs_common(domain, virq, 1); + } msi_domain_free_descs(dev, &ctrl); unlock: msi_unlock_descs(dev); return ret; } +void msi_domain_depopulate_descs(struct device *dev, int virq_base, int nvec) +{ + struct msi_ctrl ctrl = { + .domid = MSI_DEFAULT_DOMAIN, + .first = virq_base, + .last = virq_base + nvec - 1, + }; + struct msi_desc *desc; + struct xarray *xa; + unsigned long idx; + + if (!msi_ctrl_valid(dev, &ctrl)) + return; + + xa = &dev->msi.data->__domains[ctrl.domid].store; + xa_for_each_range(xa, idx, desc, ctrl.first, ctrl.last) + desc->irq = 0; +} + /* * Carefully check whether the device can use reservation mode. If * reservation mode is enabled then the early activation will assign a From bd75497a77ccae9a5e1b0f1a3fa8283d67b21f4c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:48:54 -0500 Subject: [PATCH 12/30] m68k: fix livelock in uaccess m68k equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Tested-by: Finn Thain Tested-by: Geert Uytterhoeven Acked-by: Geert Uytterhoeven Signed-off-by: Al Viro --- arch/m68k/mm/fault.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index 4d2837eb3e2a..228128e45c67 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -138,8 +138,11 @@ good_area: fault = handle_mm_fault(vma, address, flags, regs); pr_debug("handle_mm_fault returns %x\n", fault); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + goto no_context; return 0; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From d835eb3a57de50d16dd4a6b53f95dbc2bfa8ef48 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:55:52 -0500 Subject: [PATCH 13/30] riscv: fix livelock in uaccess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit riscv equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Tested-by: Björn Töpel Tested-by: Geert Uytterhoeven Signed-off-by: Al Viro --- arch/riscv/mm/fault.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index d86f7cebd4a7..c91d85349d39 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -324,8 +324,11 @@ good_area: * signal first. We do not need to release the mmap_lock because it * would already be released in __lock_page_or_retry in mm/filemap.c. */ - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + no_context(regs, addr); return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From 0b92ed09cb9ffada29ca05510ef28252b6059d6d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:46:10 -0500 Subject: [PATCH 14/30] hexagon: fix livelock in uaccess hexagon equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Acked-by: Brian Cain Signed-off-by: Al Viro --- arch/hexagon/mm/vm_fault.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c index f73c7cbfe326..4b578d02fd01 100644 --- a/arch/hexagon/mm/vm_fault.c +++ b/arch/hexagon/mm/vm_fault.c @@ -93,8 +93,11 @@ good_area: fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + goto no_context; return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From 15261678a8c2ff093ffedad730b1646d34a1716a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:53:52 -0500 Subject: [PATCH 15/30] parisc: fix livelock in uaccess parisc equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Tested-by: Helge Deller Signed-off-by: Al Viro --- arch/parisc/mm/fault.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 869204e97ec9..6941fdbf2517 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -308,8 +308,13 @@ good_area: fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) { + msg = "Page fault: fault signal on kernel memory"; + goto no_context; + } return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From dce45493aff3fdd57fed2a0da264e585dba88433 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:34:16 -0500 Subject: [PATCH 16/30] alpha: fix livelock in uaccess alpha equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Signed-off-by: Al Viro --- arch/alpha/mm/fault.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index ef427a6bdd1a..7b01ae4f3bc6 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -152,8 +152,11 @@ retry: the fault. */ fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + goto no_context; return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From 79c54c97c7735e09f9e2193a713f30e56eec00dc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 31 Jan 2023 00:03:40 -0500 Subject: [PATCH 17/30] sparc: fix livelock in uaccess sparc equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Signed-off-by: Al Viro --- arch/sparc/mm/fault_32.c | 5 ++++- arch/sparc/mm/fault_64.c | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index 91259f291c54..179295b14664 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c @@ -187,8 +187,11 @@ good_area: */ fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!from_user) + goto no_context; return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 4acc12eafbf5..d91305de694c 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -424,8 +424,13 @@ good_area: fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (regs->tstate & TSTATE_PRIV) { + insn = get_fault_insn(regs, insn); + goto handle_kernel_fault; + } goto exit_exception; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From d088af1e221c32bd67825c5dccf664f699e827b4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:47:28 -0500 Subject: [PATCH 18/30] ia64: fix livelock in uaccess ia64 equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Signed-off-by: Al Viro --- arch/ia64/mm/fault.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index ef78c2d66cdd..85c4d9ac8686 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -136,8 +136,11 @@ retry: */ fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + goto no_context; return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From a1179ac743e8f2044b67848b5109614619b65366 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:50:22 -0500 Subject: [PATCH 19/30] microblaze: fix livelock in uaccess microblaze equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Signed-off-by: Al Viro --- arch/microblaze/mm/fault.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c index 5c40c3ebe52f..687714db6f4d 100644 --- a/arch/microblaze/mm/fault.c +++ b/arch/microblaze/mm/fault.c @@ -219,8 +219,11 @@ good_area: */ fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + bad_page_fault(regs, address, SIGBUS); return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From e902e508c5b280488c62f119a05ad88f9f7eb1cb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:51:40 -0500 Subject: [PATCH 20/30] nios2: fix livelock in uaccess nios2 equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Signed-off-by: Al Viro --- arch/nios2/mm/fault.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/nios2/mm/fault.c b/arch/nios2/mm/fault.c index edaca0a6c1c1..ca64eccea551 100644 --- a/arch/nios2/mm/fault.c +++ b/arch/nios2/mm/fault.c @@ -136,8 +136,11 @@ good_area: */ fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + goto no_context; return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From caa82ae7ef52b7cf5f80a2b2fbcbdbcfd16426cc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Jan 2023 23:52:40 -0500 Subject: [PATCH 21/30] openrisc: fix livelock in uaccess openrisc equivalent of 26178ec11ef3 "x86: mm: consolidate VM_FAULT_RETRY handling" If e.g. get_user() triggers a page fault and a fatal signal is caught, we might end up with handle_mm_fault() returning VM_FAULT_RETRY and not doing anything to page tables. In such case we must *not* return to the faulting insn - that would repeat the entire thing without making any progress; what we need instead is to treat that as failed (user) memory access. Signed-off-by: Al Viro --- arch/openrisc/mm/fault.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c index b4762d66e9ef..6734fee3134f 100644 --- a/arch/openrisc/mm/fault.c +++ b/arch/openrisc/mm/fault.c @@ -162,8 +162,11 @@ good_area: fault = handle_mm_fault(vma, address, flags, regs); - if (fault_signal_pending(fault, regs)) + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + goto no_context; return; + } /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) From a76d19e6acb1ef16561b0682cd1a566463fa3d98 Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Tue, 28 Feb 2023 10:33:17 +1100 Subject: [PATCH 22/30] i2c: Disable I2C_APPLE when I2C_PASEMI is a builtin The ppc64le_allmodconfig sets I2C_PASEMI=y and leaves COMPILE_TEST to default to y and I2C_APPLE to default to m, running into a known incompatible configuration that breaks the build [1]. Specifically, a common dependency (i2c-pasemi-core.o in this case) cannot be used by both builtin and module consumers. Disable I2C_APPLE when I2C_PASEMI is a builtin to prevent this. [1]: https://lore.kernel.org/all/202112061809.XT99aPrf-lkp@intel.com Suggested-by: Arnd Bergmann Signed-off-by: Benjamin Gray Acked-by: Arnd Bergmann Acked-by: Sven Peter Signed-off-by: Wolfram Sang --- drivers/i2c/busses/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 9b8e84f20604..25eb4e8fd22f 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -914,6 +914,7 @@ config I2C_PASEMI config I2C_APPLE tristate "Apple SMBus platform driver" + depends on !I2C_PASEMI depends on ARCH_APPLE || COMPILE_TEST default ARCH_APPLE help From 1d092308ce223bb1403475737b8fb847e9e8704c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 17 Feb 2023 23:13:30 +0100 Subject: [PATCH 23/30] i2c: gxp: remove "empty" switch statement There used to be error messages which had to go. Now, it only consists of 'break's, so it can go. Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-gxp.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-gxp.c b/drivers/i2c/busses/i2c-gxp.c index da4c8e5a8039..352dedf6292f 100644 --- a/drivers/i2c/busses/i2c-gxp.c +++ b/drivers/i2c/busses/i2c-gxp.c @@ -126,19 +126,8 @@ static int gxp_i2c_master_xfer(struct i2c_adapter *adapter, time_left = wait_for_completion_timeout(&drvdata->completion, adapter->timeout); ret = num - drvdata->msgs_remaining; - if (time_left == 0) { - switch (drvdata->state) { - case GXP_I2C_WDATA_PHASE: - break; - case GXP_I2C_RDATA_PHASE: - break; - case GXP_I2C_ADDR_PHASE: - break; - default: - break; - } + if (time_left == 0) return -ETIMEDOUT; - } if (drvdata->state == GXP_I2C_ADDR_NACK || drvdata->state == GXP_I2C_DATA_NACK) From 4b3dfb0ed6336dea4a763ce9fa30a42763eb3800 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Feb 2023 15:40:59 +0100 Subject: [PATCH 24/30] i2c: gxp: return proper error on address NACK According to Documentation/i2c/fault-codes.rst, NACK after sending an address should be -ENXIO. Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-gxp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-gxp.c b/drivers/i2c/busses/i2c-gxp.c index 352dedf6292f..fda7809e72ba 100644 --- a/drivers/i2c/busses/i2c-gxp.c +++ b/drivers/i2c/busses/i2c-gxp.c @@ -129,8 +129,10 @@ static int gxp_i2c_master_xfer(struct i2c_adapter *adapter, if (time_left == 0) return -ETIMEDOUT; - if (drvdata->state == GXP_I2C_ADDR_NACK || - drvdata->state == GXP_I2C_DATA_NACK) + if (drvdata->state == GXP_I2C_ADDR_NACK) + return -ENXIO; + + if (drvdata->state == GXP_I2C_DATA_NACK) return -EIO; return ret; From 65609d3206f784489eb1ebd6fce64b84a42cc63c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 27 Feb 2023 13:06:33 +0300 Subject: [PATCH 25/30] i2c: gxp: fix an error code in probe This is passing IS_ERR() instead of PTR_ERR() so instead of an error code it prints and returns the number 1. Fixes: 4a55ed6f89f5 ("i2c: Add GXP SoC I2C Controller") Signed-off-by: Dan Carpenter Reviewed-by: Nick Hawkins Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-gxp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-gxp.c b/drivers/i2c/busses/i2c-gxp.c index fda7809e72ba..d4b55d989a26 100644 --- a/drivers/i2c/busses/i2c-gxp.c +++ b/drivers/i2c/busses/i2c-gxp.c @@ -516,7 +516,7 @@ static int gxp_i2c_probe(struct platform_device *pdev) i2cg_map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "hpe,sysreg"); if (IS_ERR(i2cg_map)) { - return dev_err_probe(&pdev->dev, IS_ERR(i2cg_map), + return dev_err_probe(&pdev->dev, PTR_ERR(i2cg_map), "failed to map i2cg_handle\n"); } From e77d587a2c04e82c6a0dffa4a32c874a4029385d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 4 Mar 2023 14:03:27 -0800 Subject: [PATCH 26/30] mm: avoid gcc complaint about pointer casting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The migration code ends up temporarily stashing information of the wrong type in unused fields of the newly allocated destination folio. That all works fine, but gcc does complain about the pointer type mis-use: mm/migrate.c: In function ‘__migrate_folio_extract’: mm/migrate.c:1050:20: note: randstruct: casting between randomized structure pointer types (ssa): ‘struct anon_vma’ and ‘struct address_space’ 1050 | *anon_vmap = (void *)dst->mapping; | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~ and gcc is actually right to complain since it really doesn't understand that this is a very temporary special case where this is ok. This could be fixed in different ways by just obfuscating the assignment sufficiently that gcc doesn't see what is going on, but the truly "proper C" way to do this is by explicitly using a union. Using unions for type conversions like this is normally hugely ugly and syntactically nasty, but this really is one of the few cases where we want to make it clear that we're not doing type conversion, we're really re-using the value bit-for-bit just using another type. IOW, this should not become a common pattern, but in this one case using that odd union is probably the best way to document to the compiler what is conceptually going on here. [ Side note: there are valid cases where we convert pointers to other pointer types, notably the whole "folio vs page" situation, where the types actually have fundamental commonalities. The fact that the gcc note is limited to just randomized structures means that we don't see equivalent warnings for those cases, but it migth also mean that we miss other cases where we do play these kinds of dodgy games, and this kind of explicit conversion might be a good idea. ] I verified that at least for an allmodconfig build on x86-64, this generates the exact same code, apart from line numbers and assembler comment changes. Fixes: 64c8902ed441 ("migrate_pages: split unmap_and_move() to _unmap() and _move()") Cc: Huang, Ying Cc: Andrew Morton Signed-off-by: Linus Torvalds --- mm/migrate.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index 37865f85df6d..98f1c11197a8 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1035,11 +1035,16 @@ out: * destination folio. This is safe because nobody is using them * except us. */ +union migration_ptr { + struct anon_vma *anon_vma; + struct address_space *mapping; +}; static void __migrate_folio_record(struct folio *dst, unsigned long page_was_mapped, struct anon_vma *anon_vma) { - dst->mapping = (void *)anon_vma; + union migration_ptr ptr = { .anon_vma = anon_vma }; + dst->mapping = ptr.mapping; dst->private = (void *)page_was_mapped; } @@ -1047,7 +1052,8 @@ static void __migrate_folio_extract(struct folio *dst, int *page_was_mappedp, struct anon_vma **anon_vmap) { - *anon_vmap = (void *)dst->mapping; + union migration_ptr ptr = { .mapping = dst->mapping }; + *anon_vmap = ptr.anon_vma; *page_was_mappedp = (unsigned long)dst->private; dst->mapping = NULL; dst->private = NULL; From 3304f18bfcf588df0fe3b703b6a6c1129d80bdc7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 4 Mar 2023 20:27:29 -0500 Subject: [PATCH 27/30] Adding VFS co-maintainer Acked-by: Christian Brauner Signed-off-by: Al Viro --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 135d93368d36..bcc2b508c8e7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8043,6 +8043,7 @@ F: include/trace/events/fs_dax.h FILESYSTEMS (VFS and infrastructure) M: Alexander Viro +M: Christian Brauner L: linux-fsdevel@vger.kernel.org S: Maintained F: fs/* From 95207db8166ab95c42a03fdc5e3abd212c9987dc Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 17 Oct 2022 03:23:49 +0900 Subject: [PATCH 28/30] Remove Intel compiler support include/linux/compiler-intel.h had no update in the past 3 years. We often forget about the third C compiler to build the kernel. For example, commit a0a12c3ed057 ("asm goto: eradicate CC_HAS_ASM_GOTO") only mentioned GCC and Clang. init/Kconfig defines CC_IS_GCC and CC_IS_CLANG but not CC_IS_ICC, and nobody has reported any issue. I guess the Intel Compiler support is broken, and nobody is caring about it. Harald Arnesen pointed out ICC (classic Intel C/C++ compiler) is deprecated: $ icc -v icc: remark #10441: The Intel(R) C++ Compiler Classic (ICC) is deprecated and will be removed from product release in the second half of 2023. The Intel(R) oneAPI DPC++/C++ Compiler (ICX) is the recommended compiler moving forward. Please transition to use this compiler. Use '-diag-disable=10441' to disable this message. icc version 2021.7.0 (gcc version 12.1.0 compatibility) Arnd Bergmann provided a link to the article, "Intel C/C++ compilers complete adoption of LLVM". lib/zstd/common/compiler.h and lib/zstd/compress/zstd_fast.c were kept untouched for better sync with https://github.com/facebook/zstd Link: https://www.intel.com/content/www/us/en/developer/articles/technical/adoption-of-llvm-complete-icx.html Signed-off-by: Masahiro Yamada Acked-by: Arnd Bergmann Reviewed-by: Nick Desaulniers Reviewed-by: Nathan Chancellor Reviewed-by: Miguel Ojeda Signed-off-by: Linus Torvalds --- arch/ia64/include/uapi/asm/cmpxchg.h | 6 +- arch/ia64/include/uapi/asm/intel_intrin.h | 162 ---------------------- arch/ia64/include/uapi/asm/intrinsics.h | 6 +- include/acpi/platform/acenv.h | 5 +- include/acpi/platform/acenvex.h | 2 +- include/acpi/platform/acintel.h | 55 -------- include/linux/compiler-intel.h | 34 ----- include/linux/compiler_attributes.h | 14 +- include/linux/compiler_types.h | 2 - scripts/cc-version.sh | 2 - scripts/min-tool-version.sh | 4 - 11 files changed, 5 insertions(+), 287 deletions(-) delete mode 100644 arch/ia64/include/uapi/asm/intel_intrin.h delete mode 100644 include/acpi/platform/acintel.h delete mode 100644 include/linux/compiler-intel.h diff --git a/arch/ia64/include/uapi/asm/cmpxchg.h b/arch/ia64/include/uapi/asm/cmpxchg.h index ca2e02685343..259ae57570bf 100644 --- a/arch/ia64/include/uapi/asm/cmpxchg.h +++ b/arch/ia64/include/uapi/asm/cmpxchg.h @@ -15,11 +15,7 @@ #include /* include compiler specific intrinsics */ #include -#ifdef __INTEL_COMPILER -# include -#else -# include -#endif +#include /* * This function doesn't exist, so you'll get a linker error if diff --git a/arch/ia64/include/uapi/asm/intel_intrin.h b/arch/ia64/include/uapi/asm/intel_intrin.h deleted file mode 100644 index dc1884dc54b5..000000000000 --- a/arch/ia64/include/uapi/asm/intel_intrin.h +++ /dev/null @@ -1,162 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _ASM_IA64_INTEL_INTRIN_H -#define _ASM_IA64_INTEL_INTRIN_H -/* - * Intel Compiler Intrinsics - * - * Copyright (C) 2002,2003 Jun Nakajima - * Copyright (C) 2002,2003 Suresh Siddha - * Copyright (C) 2005,2006 Hongjiu Lu - * - */ -#include - -#define ia64_barrier() __memory_barrier() - -#define ia64_stop() /* Nothing: As of now stop bit is generated for each - * intrinsic - */ - -#define ia64_getreg __getReg -#define ia64_setreg __setReg - -#define ia64_hint __hint -#define ia64_hint_pause __hint_pause - -#define ia64_mux1_brcst _m64_mux1_brcst -#define ia64_mux1_mix _m64_mux1_mix -#define ia64_mux1_shuf _m64_mux1_shuf -#define ia64_mux1_alt _m64_mux1_alt -#define ia64_mux1_rev _m64_mux1_rev - -#define ia64_mux1(x,v) _m_to_int64(_m64_mux1(_m_from_int64(x), (v))) -#define ia64_popcnt _m64_popcnt -#define ia64_getf_exp __getf_exp -#define ia64_shrp _m64_shrp - -#define ia64_tpa __tpa -#define ia64_invala __invala -#define ia64_invala_gr __invala_gr -#define ia64_invala_fr __invala_fr -#define ia64_nop __nop -#define ia64_sum __sum -#define ia64_ssm __ssm -#define ia64_rum __rum -#define ia64_rsm __rsm -#define ia64_fc __fc - -#define ia64_ldfs __ldfs -#define ia64_ldfd __ldfd -#define ia64_ldfe __ldfe -#define ia64_ldf8 __ldf8 -#define ia64_ldf_fill __ldf_fill - -#define ia64_stfs __stfs -#define ia64_stfd __stfd -#define ia64_stfe __stfe -#define ia64_stf8 __stf8 -#define ia64_stf_spill __stf_spill - -#define ia64_mf __mf -#define ia64_mfa __mfa - -#define ia64_fetchadd4_acq __fetchadd4_acq -#define ia64_fetchadd4_rel __fetchadd4_rel -#define ia64_fetchadd8_acq __fetchadd8_acq -#define ia64_fetchadd8_rel __fetchadd8_rel - -#define ia64_xchg1 _InterlockedExchange8 -#define ia64_xchg2 _InterlockedExchange16 -#define ia64_xchg4 _InterlockedExchange -#define ia64_xchg8 _InterlockedExchange64 - -#define ia64_cmpxchg1_rel _InterlockedCompareExchange8_rel -#define ia64_cmpxchg1_acq _InterlockedCompareExchange8_acq -#define ia64_cmpxchg2_rel _InterlockedCompareExchange16_rel -#define ia64_cmpxchg2_acq _InterlockedCompareExchange16_acq -#define ia64_cmpxchg4_rel _InterlockedCompareExchange_rel -#define ia64_cmpxchg4_acq _InterlockedCompareExchange_acq -#define ia64_cmpxchg8_rel _InterlockedCompareExchange64_rel -#define ia64_cmpxchg8_acq _InterlockedCompareExchange64_acq - -#define __ia64_set_dbr(index, val) \ - __setIndReg(_IA64_REG_INDR_DBR, index, val) -#define ia64_set_ibr(index, val) \ - __setIndReg(_IA64_REG_INDR_IBR, index, val) -#define ia64_set_pkr(index, val) \ - __setIndReg(_IA64_REG_INDR_PKR, index, val) -#define ia64_set_pmc(index, val) \ - __setIndReg(_IA64_REG_INDR_PMC, index, val) -#define ia64_set_pmd(index, val) \ - __setIndReg(_IA64_REG_INDR_PMD, index, val) -#define ia64_set_rr(index, val) \ - __setIndReg(_IA64_REG_INDR_RR, index, val) - -#define ia64_get_cpuid(index) \ - __getIndReg(_IA64_REG_INDR_CPUID, index) -#define __ia64_get_dbr(index) __getIndReg(_IA64_REG_INDR_DBR, index) -#define ia64_get_ibr(index) __getIndReg(_IA64_REG_INDR_IBR, index) -#define ia64_get_pkr(index) __getIndReg(_IA64_REG_INDR_PKR, index) -#define ia64_get_pmc(index) __getIndReg(_IA64_REG_INDR_PMC, index) -#define ia64_get_pmd(index) __getIndReg(_IA64_REG_INDR_PMD, index) -#define ia64_get_rr(index) __getIndReg(_IA64_REG_INDR_RR, index) - -#define ia64_srlz_d __dsrlz -#define ia64_srlz_i __isrlz - -#define ia64_dv_serialize_data() -#define ia64_dv_serialize_instruction() - -#define ia64_st1_rel __st1_rel -#define ia64_st2_rel __st2_rel -#define ia64_st4_rel __st4_rel -#define ia64_st8_rel __st8_rel - -/* FIXME: need st4.rel.nta intrinsic */ -#define ia64_st4_rel_nta __st4_rel - -#define ia64_ld1_acq __ld1_acq -#define ia64_ld2_acq __ld2_acq -#define ia64_ld4_acq __ld4_acq -#define ia64_ld8_acq __ld8_acq - -#define ia64_sync_i __synci -#define ia64_thash __thash -#define ia64_ttag __ttag -#define ia64_itcd __itcd -#define ia64_itci __itci -#define ia64_itrd __itrd -#define ia64_itri __itri -#define ia64_ptce __ptce -#define ia64_ptcl __ptcl -#define ia64_ptcg __ptcg -#define ia64_ptcga __ptcga -#define ia64_ptri __ptri -#define ia64_ptrd __ptrd -#define ia64_dep_mi _m64_dep_mi - -/* Values for lfhint in __lfetch and __lfetch_fault */ - -#define ia64_lfhint_none __lfhint_none -#define ia64_lfhint_nt1 __lfhint_nt1 -#define ia64_lfhint_nt2 __lfhint_nt2 -#define ia64_lfhint_nta __lfhint_nta - -#define ia64_lfetch __lfetch -#define ia64_lfetch_excl __lfetch_excl -#define ia64_lfetch_fault __lfetch_fault -#define ia64_lfetch_fault_excl __lfetch_fault_excl - -#define ia64_intrin_local_irq_restore(x) \ -do { \ - if ((x) != 0) { \ - ia64_ssm(IA64_PSR_I); \ - ia64_srlz_d(); \ - } else { \ - ia64_rsm(IA64_PSR_I); \ - } \ -} while (0) - -#define __builtin_trap() __break(0); - -#endif /* _ASM_IA64_INTEL_INTRIN_H */ diff --git a/arch/ia64/include/uapi/asm/intrinsics.h b/arch/ia64/include/uapi/asm/intrinsics.h index a0e0a064f5b1..63f27c4ec739 100644 --- a/arch/ia64/include/uapi/asm/intrinsics.h +++ b/arch/ia64/include/uapi/asm/intrinsics.h @@ -14,11 +14,7 @@ #include /* include compiler specific intrinsics */ #include -#ifdef __INTEL_COMPILER -# include -#else -# include -#endif +#include #include #define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \ diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index 03eb3d977075..9e4f7564201a 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -148,15 +148,12 @@ * *****************************************************************************/ -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) +#if defined(__GNUC__) #include #elif defined(_MSC_VER) #include "acmsvc.h" -#elif defined(__INTEL_COMPILER) -#include - #endif #if defined(_LINUX) || defined(__linux__) diff --git a/include/acpi/platform/acenvex.h b/include/acpi/platform/acenvex.h index 3a6b1db9a984..72cc7bab469e 100644 --- a/include/acpi/platform/acenvex.h +++ b/include/acpi/platform/acenvex.h @@ -35,7 +35,7 @@ #endif -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) +#if defined(__GNUC__) #include "acgccex.h" #elif defined(_MSC_VER) diff --git a/include/acpi/platform/acintel.h b/include/acpi/platform/acintel.h deleted file mode 100644 index 85b1ae86ee63..000000000000 --- a/include/acpi/platform/acintel.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ -/****************************************************************************** - * - * Name: acintel.h - VC specific defines, etc. - * - * Copyright (C) 2000 - 2022, Intel Corp. - * - *****************************************************************************/ - -#ifndef __ACINTEL_H__ -#define __ACINTEL_H__ - -/* - * Use compiler specific is a good practice for even when - * -nostdinc is specified (i.e., ACPI_USE_STANDARD_HEADERS undefined. - */ -#ifndef va_arg -#include -#endif - -/* Configuration specific to Intel 64-bit C compiler */ - -#define COMPILER_DEPENDENT_INT64 __int64 -#define COMPILER_DEPENDENT_UINT64 unsigned __int64 -#define ACPI_INLINE __inline - -/* - * Calling conventions: - * - * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces - * ACPI_INTERNAL_XFACE - Internal ACPI interfaces - * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces - */ -#define ACPI_SYSTEM_XFACE -#define ACPI_EXTERNAL_XFACE -#define ACPI_INTERNAL_XFACE -#define ACPI_INTERNAL_VAR_XFACE - -/* remark 981 - operands evaluated in no particular order */ -#pragma warning(disable:981) - -/* warn C4100: unreferenced formal parameter */ -#pragma warning(disable:4100) - -/* warn C4127: conditional expression is constant */ -#pragma warning(disable:4127) - -/* warn C4706: assignment within conditional expression */ -#pragma warning(disable:4706) - -/* warn C4214: bit field types other than int */ -#pragma warning(disable:4214) - -#endif /* __ACINTEL_H__ */ diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h deleted file mode 100644 index b17f3cd18334..000000000000 --- a/include/linux/compiler-intel.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __LINUX_COMPILER_TYPES_H -#error "Please don't include directly, include instead." -#endif - -#ifdef __ECC - -/* Compiler specific definitions for Intel ECC compiler */ - -#include - -/* Intel ECC compiler doesn't support gcc specific asm stmts. - * It uses intrinsics to do the equivalent things. - */ - -#define barrier() __memory_barrier() -#define barrier_data(ptr) barrier() - -#define RELOC_HIDE(ptr, off) \ - ({ unsigned long __ptr; \ - __ptr = (unsigned long) (ptr); \ - (typeof(ptr)) (__ptr + (off)); }) - -/* This should act as an optimization barrier on var. - * Given that this compiler does not have inline assembly, a compiler barrier - * is the best we can do. - */ -#define OPTIMIZER_HIDE_VAR(var) barrier() - -#endif - -/* icc has this, but it's called _bswap16 */ -#define __HAVE_BUILTIN_BSWAP16__ -#define __builtin_bswap16 _bswap16 diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index 4a3bd114a24f..e659cb6fded3 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -64,16 +64,10 @@ * compiler should see some alignment anyway, when the return value is * massaged by 'flags = ptr & 3; ptr &= ~3;'). * - * Optional: not supported by icc - * * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-assume_005faligned-function-attribute * clang: https://clang.llvm.org/docs/AttributeReference.html#assume-aligned */ -#if __has_attribute(__assume_aligned__) -# define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) -#else -# define __assume_aligned(a, ...) -#endif +#define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) /* * Note the long name. @@ -85,7 +79,6 @@ /* * Optional: only supported since gcc >= 9 * Optional: not supported by clang - * Optional: not supported by icc * * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-copy-function-attribute */ @@ -98,7 +91,6 @@ /* * Optional: not supported by gcc * Optional: only supported since clang >= 14.0 - * Optional: not supported by icc * * clang: https://clang.llvm.org/docs/AttributeReference.html#diagnose_as_builtin */ @@ -122,7 +114,6 @@ /* * Optional: not supported by clang - * Optional: not supported by icc * * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-designated_005finit-type-attribute */ @@ -236,7 +227,6 @@ /* * Optional: only supported since gcc >= 8 * Optional: not supported by clang - * Optional: not supported by icc * * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute */ @@ -267,7 +257,6 @@ /* * Optional: not supported by gcc. - * Optional: not supported by icc. * * clang: https://clang.llvm.org/docs/AttributeReference.html#overloadable */ @@ -287,7 +276,6 @@ * Note: the "type" argument should match any __builtin_object_size(p, type) usage. * * Optional: not supported by gcc. - * Optional: not supported by icc. * * clang: https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size */ diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 690c7c826fbf..547ea1ff806e 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -120,8 +120,6 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { } /* Compiler specific macros. */ #ifdef __clang__ #include -#elif defined(__INTEL_COMPILER) -#include #elif defined(__GNUC__) /* The above compilers also define __GNUC__, so order is important here. */ #include diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh index 2401c86fcf53..0573c92e841d 100755 --- a/scripts/cc-version.sh +++ b/scripts/cc-version.sh @@ -12,8 +12,6 @@ get_c_compiler_info() cat <<- EOF | "$@" -E -P -x c - 2>/dev/null #if defined(__clang__) Clang __clang_major__ __clang_minor__ __clang_patchlevel__ - #elif defined(__INTEL_COMPILER) - ICC __INTEL_COMPILER __INTEL_COMPILER_UPDATE #elif defined(__GNUC__) GCC __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ #else diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh index a814f1efb39d..20d483ec6f5f 100755 --- a/scripts/min-tool-version.sh +++ b/scripts/min-tool-version.sh @@ -19,10 +19,6 @@ binutils) gcc) echo 5.1.0 ;; -icc) - # temporary - echo 16.0.3 - ;; llvm) if [ "$SRCARCH" = s390 ]; then echo 15.0.0 From 596ff4a09b8981790e15572e8e7bc904df5835e7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 4 Mar 2023 13:35:43 -0800 Subject: [PATCH 29/30] cpumask: re-introduce constant-sized cpumask optimizations Commit aa47a7c215e7 ("lib/cpumask: deprecate nr_cpumask_bits") resulted in the cpumask operations potentially becoming hugely less efficient, because suddenly the cpumask was always considered to be variable-sized. The optimization was then later added back in a limited form by commit 6f9c07be9d02 ("lib/cpumask: add FORCE_NR_CPUS config option"), but that FORCE_NR_CPUS option is not useful in a generic kernel and more of a special case for embedded situations with fixed hardware. Instead, just re-introduce the optimization, with some changes. Instead of depending on CPUMASK_OFFSTACK being false, and then always using the full constant cpumask width, this introduces three different cpumask "sizes": - the exact size (nr_cpumask_bits) remains identical to nr_cpu_ids. This is used for situations where we should use the exact size. - the "small" size (small_cpumask_bits) is the NR_CPUS constant if it fits in a single word and the bitmap operations thus end up able to trigger the "small_const_nbits()" optimizations. This is used for the operations that have optimized single-word cases that get inlined, notably the bit find and scanning functions. - the "large" size (large_cpumask_bits) is the NR_CPUS constant if it is an sufficiently small constant that makes simple "copy" and "clear" operations more efficient. This is arbitrarily set at four words or less. As a an example of this situation, without this fixed size optimization, cpumask_clear() will generate code like movl nr_cpu_ids(%rip), %edx addq $63, %rdx shrq $3, %rdx andl $-8, %edx callq memset@PLT on x86-64, because it would calculate the "exact" number of longwords that need to be cleared. In contrast, with this patch, using a MAX_CPU of 64 (which is quite a reasonable value to use), the above becomes a single movq $0,cpumask instruction instead, because instead of caring to figure out exactly how many CPU's the system has, it just knows that the cpumask will be a single word and can just clear it all. Note that this does end up tightening the rules a bit from the original version in another way: operations that set bits in the cpumask are now limited to the actual nr_cpu_ids limit, whereas we used to do the nr_cpumask_bits thing almost everywhere in the cpumask code. But if you just clear bits, or scan for bits, we can use the simpler compile-time constants. In the process, remove 'cpumask_complement()' and 'for_each_cpu_not()' which were not useful, and which fundamentally have to be limited to 'nr_cpu_ids'. Better remove them now than have somebody introduce use of them later. Of course, on x86-64 with MAXSMP there is no sane small compile-time constant for the cpumask sizes, and we end up using the actual CPU bits, and will generate the above kind of horrors regardless. Please don't use MAXSMP unless you really expect to have machines with thousands of cores. Signed-off-by: Linus Torvalds --- .clang-format | 1 - arch/ia64/kernel/acpi.c | 4 +- include/linux/cpumask.h | 125 ++++++++++++++++++++++------------------ lib/cpumask_kunit.c | 14 +---- 4 files changed, 72 insertions(+), 72 deletions(-) diff --git a/.clang-format b/.clang-format index 2c61b4553374..d988e9fa9b26 100644 --- a/.clang-format +++ b/.clang-format @@ -226,7 +226,6 @@ ForEachMacros: - 'for_each_console_srcu' - 'for_each_cpu' - 'for_each_cpu_and' - - 'for_each_cpu_not' - 'for_each_cpu_wrap' - 'for_each_dapm_widgets' - 'for_each_dedup_cand' diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 96d13cb7c19f..15f6cfddcc08 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -783,11 +783,9 @@ __init void prefill_possible_map(void) static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - cpumask_t tmp_map; int cpu; - cpumask_complement(&tmp_map, cpu_present_mask); - cpu = cpumask_first(&tmp_map); + cpu = cpumask_first_zero(cpu_present_mask); if (cpu >= nr_cpu_ids) return -EINVAL; diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 10c92bd9b807..8fbe76607965 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -50,8 +50,41 @@ static inline void set_nr_cpu_ids(unsigned int nr) #endif } -/* Deprecated. Always use nr_cpu_ids. */ -#define nr_cpumask_bits nr_cpu_ids +/* + * We have several different "preferred sizes" for the cpumask + * operations, depending on operation. + * + * For example, the bitmap scanning and operating operations have + * optimized routines that work for the single-word case, but only when + * the size is constant. So if NR_CPUS fits in one single word, we are + * better off using that small constant, in order to trigger the + * optimized bit finding. That is 'small_cpumask_size'. + * + * The clearing and copying operations will similarly perform better + * with a constant size, but we limit that size arbitrarily to four + * words. We call this 'large_cpumask_size'. + * + * Finally, some operations just want the exact limit, either because + * they set bits or just don't have any faster fixed-sized versions. We + * call this just 'nr_cpumask_size'. + * + * Note that these optional constants are always guaranteed to be at + * least as big as 'nr_cpu_ids' itself is, and all our cpumask + * allocations are at least that size (see cpumask_size()). The + * optimization comes from being able to potentially use a compile-time + * constant instead of a run-time generated exact number of CPUs. + */ +#if NR_CPUS <= BITS_PER_LONG + #define small_cpumask_bits ((unsigned int)NR_CPUS) + #define large_cpumask_bits ((unsigned int)NR_CPUS) +#elif NR_CPUS <= 4*BITS_PER_LONG + #define small_cpumask_bits nr_cpu_ids + #define large_cpumask_bits ((unsigned int)NR_CPUS) +#else + #define small_cpumask_bits nr_cpu_ids + #define large_cpumask_bits nr_cpu_ids +#endif +#define nr_cpumask_bits nr_cpu_ids /* * The following particular system cpumasks and operations manage @@ -126,7 +159,7 @@ static __always_inline unsigned int cpumask_check(unsigned int cpu) */ static inline unsigned int cpumask_first(const struct cpumask *srcp) { - return find_first_bit(cpumask_bits(srcp), nr_cpumask_bits); + return find_first_bit(cpumask_bits(srcp), small_cpumask_bits); } /** @@ -137,7 +170,7 @@ static inline unsigned int cpumask_first(const struct cpumask *srcp) */ static inline unsigned int cpumask_first_zero(const struct cpumask *srcp) { - return find_first_zero_bit(cpumask_bits(srcp), nr_cpumask_bits); + return find_first_zero_bit(cpumask_bits(srcp), small_cpumask_bits); } /** @@ -150,7 +183,7 @@ static inline unsigned int cpumask_first_zero(const struct cpumask *srcp) static inline unsigned int cpumask_first_and(const struct cpumask *srcp1, const struct cpumask *srcp2) { - return find_first_and_bit(cpumask_bits(srcp1), cpumask_bits(srcp2), nr_cpumask_bits); + return find_first_and_bit(cpumask_bits(srcp1), cpumask_bits(srcp2), small_cpumask_bits); } /** @@ -161,7 +194,7 @@ unsigned int cpumask_first_and(const struct cpumask *srcp1, const struct cpumask */ static inline unsigned int cpumask_last(const struct cpumask *srcp) { - return find_last_bit(cpumask_bits(srcp), nr_cpumask_bits); + return find_last_bit(cpumask_bits(srcp), small_cpumask_bits); } /** @@ -177,7 +210,7 @@ unsigned int cpumask_next(int n, const struct cpumask *srcp) /* -1 is a legal arg here. */ if (n != -1) cpumask_check(n); - return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n + 1); + return find_next_bit(cpumask_bits(srcp), small_cpumask_bits, n + 1); } /** @@ -192,7 +225,7 @@ static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp) /* -1 is a legal arg here. */ if (n != -1) cpumask_check(n); - return find_next_zero_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1); + return find_next_zero_bit(cpumask_bits(srcp), small_cpumask_bits, n+1); } #if NR_CPUS == 1 @@ -235,7 +268,7 @@ unsigned int cpumask_next_and(int n, const struct cpumask *src1p, if (n != -1) cpumask_check(n); return find_next_and_bit(cpumask_bits(src1p), cpumask_bits(src2p), - nr_cpumask_bits, n + 1); + small_cpumask_bits, n + 1); } /** @@ -246,17 +279,7 @@ unsigned int cpumask_next_and(int n, const struct cpumask *src1p, * After the loop, cpu is >= nr_cpu_ids. */ #define for_each_cpu(cpu, mask) \ - for_each_set_bit(cpu, cpumask_bits(mask), nr_cpumask_bits) - -/** - * for_each_cpu_not - iterate over every cpu in a complemented mask - * @cpu: the (optionally unsigned) integer iterator - * @mask: the cpumask pointer - * - * After the loop, cpu is >= nr_cpu_ids. - */ -#define for_each_cpu_not(cpu, mask) \ - for_each_clear_bit(cpu, cpumask_bits(mask), nr_cpumask_bits) + for_each_set_bit(cpu, cpumask_bits(mask), small_cpumask_bits) #if NR_CPUS == 1 static inline @@ -290,7 +313,7 @@ unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int sta * After the loop, cpu is >= nr_cpu_ids. */ #define for_each_cpu_wrap(cpu, mask, start) \ - for_each_set_bit_wrap(cpu, cpumask_bits(mask), nr_cpumask_bits, start) + for_each_set_bit_wrap(cpu, cpumask_bits(mask), small_cpumask_bits, start) /** * for_each_cpu_and - iterate over every cpu in both masks @@ -307,7 +330,7 @@ unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int sta * After the loop, cpu is >= nr_cpu_ids. */ #define for_each_cpu_and(cpu, mask1, mask2) \ - for_each_and_bit(cpu, cpumask_bits(mask1), cpumask_bits(mask2), nr_cpumask_bits) + for_each_and_bit(cpu, cpumask_bits(mask1), cpumask_bits(mask2), small_cpumask_bits) /** * for_each_cpu_andnot - iterate over every cpu present in one mask, excluding @@ -325,7 +348,7 @@ unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int sta * After the loop, cpu is >= nr_cpu_ids. */ #define for_each_cpu_andnot(cpu, mask1, mask2) \ - for_each_andnot_bit(cpu, cpumask_bits(mask1), cpumask_bits(mask2), nr_cpumask_bits) + for_each_andnot_bit(cpu, cpumask_bits(mask1), cpumask_bits(mask2), small_cpumask_bits) /** * cpumask_any_but - return a "random" in a cpumask, but not this one. @@ -356,7 +379,7 @@ unsigned int cpumask_any_but(const struct cpumask *mask, unsigned int cpu) */ static inline unsigned int cpumask_nth(unsigned int cpu, const struct cpumask *srcp) { - return find_nth_bit(cpumask_bits(srcp), nr_cpumask_bits, cpumask_check(cpu)); + return find_nth_bit(cpumask_bits(srcp), small_cpumask_bits, cpumask_check(cpu)); } /** @@ -372,7 +395,7 @@ unsigned int cpumask_nth_and(unsigned int cpu, const struct cpumask *srcp1, const struct cpumask *srcp2) { return find_nth_and_bit(cpumask_bits(srcp1), cpumask_bits(srcp2), - nr_cpumask_bits, cpumask_check(cpu)); + small_cpumask_bits, cpumask_check(cpu)); } /** @@ -388,7 +411,7 @@ unsigned int cpumask_nth_andnot(unsigned int cpu, const struct cpumask *srcp1, const struct cpumask *srcp2) { return find_nth_andnot_bit(cpumask_bits(srcp1), cpumask_bits(srcp2), - nr_cpumask_bits, cpumask_check(cpu)); + small_cpumask_bits, cpumask_check(cpu)); } /** @@ -408,7 +431,7 @@ unsigned int cpumask_nth_and_andnot(unsigned int cpu, const struct cpumask *srcp return find_nth_and_andnot_bit(cpumask_bits(srcp1), cpumask_bits(srcp2), cpumask_bits(srcp3), - nr_cpumask_bits, cpumask_check(cpu)); + small_cpumask_bits, cpumask_check(cpu)); } #define CPU_BITS_NONE \ @@ -495,10 +518,14 @@ static __always_inline bool cpumask_test_and_clear_cpu(int cpu, struct cpumask * /** * cpumask_setall - set all cpus (< nr_cpu_ids) in a cpumask * @dstp: the cpumask pointer + * + * Note: since we set bits, we should use the tighter 'bitmap_set()' with + * the eact number of bits, not 'bitmap_fill()' that will fill past the + * end. */ static inline void cpumask_setall(struct cpumask *dstp) { - bitmap_fill(cpumask_bits(dstp), nr_cpumask_bits); + bitmap_set(cpumask_bits(dstp), 0, nr_cpumask_bits); } /** @@ -507,7 +534,7 @@ static inline void cpumask_setall(struct cpumask *dstp) */ static inline void cpumask_clear(struct cpumask *dstp) { - bitmap_zero(cpumask_bits(dstp), nr_cpumask_bits); + bitmap_zero(cpumask_bits(dstp), large_cpumask_bits); } /** @@ -523,7 +550,7 @@ static inline bool cpumask_and(struct cpumask *dstp, const struct cpumask *src2p) { return bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p), - cpumask_bits(src2p), nr_cpumask_bits); + cpumask_bits(src2p), small_cpumask_bits); } /** @@ -536,7 +563,7 @@ static inline void cpumask_or(struct cpumask *dstp, const struct cpumask *src1p, const struct cpumask *src2p) { bitmap_or(cpumask_bits(dstp), cpumask_bits(src1p), - cpumask_bits(src2p), nr_cpumask_bits); + cpumask_bits(src2p), small_cpumask_bits); } /** @@ -550,7 +577,7 @@ static inline void cpumask_xor(struct cpumask *dstp, const struct cpumask *src2p) { bitmap_xor(cpumask_bits(dstp), cpumask_bits(src1p), - cpumask_bits(src2p), nr_cpumask_bits); + cpumask_bits(src2p), small_cpumask_bits); } /** @@ -566,19 +593,7 @@ static inline bool cpumask_andnot(struct cpumask *dstp, const struct cpumask *src2p) { return bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p), - cpumask_bits(src2p), nr_cpumask_bits); -} - -/** - * cpumask_complement - *dstp = ~*srcp - * @dstp: the cpumask result - * @srcp: the input to invert - */ -static inline void cpumask_complement(struct cpumask *dstp, - const struct cpumask *srcp) -{ - bitmap_complement(cpumask_bits(dstp), cpumask_bits(srcp), - nr_cpumask_bits); + cpumask_bits(src2p), small_cpumask_bits); } /** @@ -590,7 +605,7 @@ static inline bool cpumask_equal(const struct cpumask *src1p, const struct cpumask *src2p) { return bitmap_equal(cpumask_bits(src1p), cpumask_bits(src2p), - nr_cpumask_bits); + small_cpumask_bits); } /** @@ -604,7 +619,7 @@ static inline bool cpumask_or_equal(const struct cpumask *src1p, const struct cpumask *src3p) { return bitmap_or_equal(cpumask_bits(src1p), cpumask_bits(src2p), - cpumask_bits(src3p), nr_cpumask_bits); + cpumask_bits(src3p), small_cpumask_bits); } /** @@ -616,7 +631,7 @@ static inline bool cpumask_intersects(const struct cpumask *src1p, const struct cpumask *src2p) { return bitmap_intersects(cpumask_bits(src1p), cpumask_bits(src2p), - nr_cpumask_bits); + small_cpumask_bits); } /** @@ -630,7 +645,7 @@ static inline bool cpumask_subset(const struct cpumask *src1p, const struct cpumask *src2p) { return bitmap_subset(cpumask_bits(src1p), cpumask_bits(src2p), - nr_cpumask_bits); + small_cpumask_bits); } /** @@ -639,7 +654,7 @@ static inline bool cpumask_subset(const struct cpumask *src1p, */ static inline bool cpumask_empty(const struct cpumask *srcp) { - return bitmap_empty(cpumask_bits(srcp), nr_cpumask_bits); + return bitmap_empty(cpumask_bits(srcp), small_cpumask_bits); } /** @@ -657,7 +672,7 @@ static inline bool cpumask_full(const struct cpumask *srcp) */ static inline unsigned int cpumask_weight(const struct cpumask *srcp) { - return bitmap_weight(cpumask_bits(srcp), nr_cpumask_bits); + return bitmap_weight(cpumask_bits(srcp), small_cpumask_bits); } /** @@ -668,7 +683,7 @@ static inline unsigned int cpumask_weight(const struct cpumask *srcp) static inline unsigned int cpumask_weight_and(const struct cpumask *srcp1, const struct cpumask *srcp2) { - return bitmap_weight_and(cpumask_bits(srcp1), cpumask_bits(srcp2), nr_cpumask_bits); + return bitmap_weight_and(cpumask_bits(srcp1), cpumask_bits(srcp2), small_cpumask_bits); } /** @@ -681,7 +696,7 @@ static inline void cpumask_shift_right(struct cpumask *dstp, const struct cpumask *srcp, int n) { bitmap_shift_right(cpumask_bits(dstp), cpumask_bits(srcp), n, - nr_cpumask_bits); + small_cpumask_bits); } /** @@ -705,7 +720,7 @@ static inline void cpumask_shift_left(struct cpumask *dstp, static inline void cpumask_copy(struct cpumask *dstp, const struct cpumask *srcp) { - bitmap_copy(cpumask_bits(dstp), cpumask_bits(srcp), nr_cpumask_bits); + bitmap_copy(cpumask_bits(dstp), cpumask_bits(srcp), large_cpumask_bits); } /** @@ -789,7 +804,7 @@ static inline int cpulist_parse(const char *buf, struct cpumask *dstp) */ static inline unsigned int cpumask_size(void) { - return BITS_TO_LONGS(nr_cpumask_bits) * sizeof(long); + return BITS_TO_LONGS(large_cpumask_bits) * sizeof(long); } /* diff --git a/lib/cpumask_kunit.c b/lib/cpumask_kunit.c index d1fc6ece21f3..a105e6369efc 100644 --- a/lib/cpumask_kunit.c +++ b/lib/cpumask_kunit.c @@ -23,16 +23,6 @@ KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask)); \ } while (0) -#define EXPECT_FOR_EACH_CPU_NOT_EQ(test, mask) \ - do { \ - const cpumask_t *m = (mask); \ - int mask_weight = cpumask_weight(m); \ - int cpu, iter = 0; \ - for_each_cpu_not(cpu, m) \ - iter++; \ - KUNIT_EXPECT_EQ_MSG((test), nr_cpu_ids - mask_weight, iter, MASK_MSG(mask)); \ - } while (0) - #define EXPECT_FOR_EACH_CPU_OP_EQ(test, op, mask1, mask2) \ do { \ const cpumask_t *m1 = (mask1); \ @@ -77,7 +67,7 @@ static void test_cpumask_weight(struct kunit *test) KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_weight(&mask_empty), MASK_MSG(&mask_empty)); KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, cpumask_weight(cpu_possible_mask), MASK_MSG(cpu_possible_mask)); - KUNIT_EXPECT_EQ_MSG(test, nr_cpumask_bits, cpumask_weight(&mask_all), MASK_MSG(&mask_all)); + KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, cpumask_weight(&mask_all), MASK_MSG(&mask_all)); } static void test_cpumask_first(struct kunit *test) @@ -113,14 +103,12 @@ static void test_cpumask_next(struct kunit *test) static void test_cpumask_iterators(struct kunit *test) { EXPECT_FOR_EACH_CPU_EQ(test, &mask_empty); - EXPECT_FOR_EACH_CPU_NOT_EQ(test, &mask_empty); EXPECT_FOR_EACH_CPU_WRAP_EQ(test, &mask_empty); EXPECT_FOR_EACH_CPU_OP_EQ(test, and, &mask_empty, &mask_empty); EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, &mask_empty); EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, &mask_empty, &mask_empty); EXPECT_FOR_EACH_CPU_EQ(test, cpu_possible_mask); - EXPECT_FOR_EACH_CPU_NOT_EQ(test, cpu_possible_mask); EXPECT_FOR_EACH_CPU_WRAP_EQ(test, cpu_possible_mask); EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, cpu_possible_mask); EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, cpu_possible_mask, &mask_empty); From fe15c26ee26efa11741a7b632e9f23b01aca4cc6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 5 Mar 2023 14:52:03 -0800 Subject: [PATCH 30/30] Linux 6.3-rc1 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index aa26f34a9b52..d7bd0eb9b346 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 -PATCHLEVEL = 2 +PATCHLEVEL = 3 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = Hurr durr I'ma ninja sloth # *DOCUMENTATION*