 Makefile                                           |  30 +++++
 arch/arm/Kconfig                                   |   4 +-
 arch/arm64/Kconfig                                 |   2 +-
 arch/arm64/kernel/setup.c                          |  27 +++++
 arch/s390/include/asm/ipl.h                        |   1 +
 arch/s390/kernel/ipl.c                             |   5 +
 arch/s390/kernel/setup.c                           |   4 +
 arch/x86/kernel/setup.c                            |  22 ++--
 crypto/akcipher.c                                  |   3 +-
 crypto/dh.c                                        |  25 ++++
 crypto/seqiv.c                                     |  15 ++-
 crypto/sig.c                                       |   3 +-
 crypto/testmgr.c                                   |   6 +-
 drivers/acpi/apei/hest.c                           |   8 ++
 drivers/acpi/irq.c                                 |  17 ++-
 drivers/acpi/scan.c                                |   9 ++
 drivers/ata/libahci.c                              |  18 +++
 drivers/char/ipmi/ipmi_dmi.c                       |  15 +++
 drivers/char/ipmi/ipmi_msghandler.c                |  16 ++-
 drivers/char/random.c                              | 126 ++++++++++++++++++++-
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         | 124 +++++++++++++++-----
 drivers/firmware/efi/libstub/fdt.c                 |   5 +
 drivers/firmware/efi/libstub/secureboot.c          |  14 ++-
 drivers/firmware/efi/secureboot.c                  |  38 +++++++
 drivers/hwtracing/coresight/coresight-etm4x-core.c |  19 ++++
 drivers/iommu/iommu.c                              |  22 ++++
 drivers/pci/quirks.c                               |  24 ++++
 drivers/usb/core/hub.c                             |   7 ++
 include/linux/crypto.h                             |   2 +
 include/linux/efi.h                                |  22 ++--
 include/linux/lsm_hook_defs.h                      |   1 +
 include/linux/random.h                             |  10 ++
 include/linux/security.h                           |   9 ++
 kernel/module/signing.c                            |   9 +-
 scripts/Makefile.lib                               |   3 +
 scripts/tags.sh                                    |   2 +
 security/integrity/platform_certs/load_uefi.c      |   6 +-
 security/lockdown/Kconfig                          |  13 +++
 security/lockdown/lockdown.c                       |  11 ++
 tools/testing/selftests/bpf/DENYLIST.rhel          |  76 +++++++++++++
 tools/testing/selftests/bpf/Makefile               |   2 +-
 tools/testing/selftests/bpf/prog_tests/ksyms_btf.c |  31 -----
 43 files changed, 701 insertions(+), 106 deletions(-)

diff --git a/Makefile b/Makefile
index ee964fb0c056..a579dc02a0fe 100644
--- a/Makefile
+++ b/Makefile
@@ -358,6 +358,17 @@ ifneq ($(filter install,$(MAKECMDGOALS)),)
     endif
 endif
 
+# CKI/cross compilation hack
+# Do we need to rebuild scripts after cross compilation?
+# If kernel was cross-compiled, these scripts have arch of build host.
+REBUILD_SCRIPTS_FOR_CROSS:=0
+
+# Regenerating config with incomplete source tree will produce different
+# config options. Disable it.
+ifeq ($(REBUILD_SCRIPTS_FOR_CROSS),1)
+may-sync-config:=
+endif
+
 ifdef mixed-build
 # ===========================================================================
 # We're called with mixed targets (*config and build targets).
@@ -1432,6 +1443,8 @@ uapi-asm-generic:
 # Generate some files
 # ---------------------------------------------------------------------------
 
+include $(srctree)/Makefile.rhelver
+
 # KERNELRELEASE can change from a few different places, meaning version.h
 # needs to be updated, so this check is forced on all builds
 
@@ -2108,6 +2121,23 @@ endif
 
 ifdef CONFIG_MODULES
 
+scripts_build:
+	$(MAKE) $(build)=scripts/basic
+	$(MAKE) $(build)=scripts/mod
+	$(MAKE) $(build)=scripts scripts/module.lds
+	$(MAKE) $(build)=scripts scripts/unifdef
+	$(MAKE) $(build)=scripts
+
+prepare_after_cross:
+	# disable STACK_VALIDATION to avoid building objtool
+	sed -i '/^CONFIG_STACK_VALIDATION/d' ./include/config/auto.conf || true
+	# build minimum set of scripts and resolve_btfids to allow building
+	# external modules
+	$(MAKE) KBUILD_EXTMOD="" M="" scripts_build V=1
+	$(MAKE) -C tools/bpf/resolve_btfids
+
+PHONY += prepare_after_cross scripts_build
+
 modules.order: $(build-dir)
 	@:
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9187240a02db..46d1258700af 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1216,9 +1216,9 @@ config HIGHMEM
 	  If unsure, say n.
 
 config HIGHPTE
-	bool "Allocate 2nd-level pagetables from highmem" if EXPERT
+	bool "Allocate 2nd-level pagetables from highmem"
 	depends on HIGHMEM && !PREEMPT_RT
-	default y
+	default n
 	help
 	  The VM uses one page of physical memory for each page table.
 	  For systems with a lot of processes, this can use a lot of
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b3afe0688919..d23a728aac03 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1489,7 +1489,7 @@ endchoice
 
 config ARM64_FORCE_52BIT
 	bool "Force 52-bit virtual addresses for userspace"
-	depends on ARM64_VA_BITS_52 && EXPERT
+	depends on ARM64_VA_BITS_52
 	help
 	  For systems with 52-bit userspace VAs enabled, the kernel will attempt
 	  to maintain compatibility with older software by providing 48-bit VAs
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 23c05dc7a8f2..d7b7b2f39e16 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -32,6 +32,8 @@
 #include <linux/sched/task.h>
 #include <linux/scs.h>
 #include <linux/mm.h>
+#include <linux/security.h>
+#include <linux/libfdt.h>
 
 #include <asm/acpi.h>
 #include <asm/fixmap.h>
@@ -207,6 +209,24 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
 	dump_stack_set_arch_desc("%s (DT)", name);
 }
 
+static void __init init_secureboot_mode(void)
+{
+	void *fdt = initial_boot_params;
+	u64 chosen;
+	const __be32 *prop;
+	int len;
+
+	chosen = fdt_path_offset(fdt, "/chosen");
+	if (chosen < 0)
+		return;
+
+	prop = fdt_getprop(fdt, chosen, "secure-boot-mode", &len);
+	if (!prop || len != sizeof(u32))
+		return;
+
+	efi_set_secure_boot((enum efi_secureboot_mode)fdt32_to_cpu(*prop));
+}
+
 static void __init request_standard_resources(void)
 {
 	struct memblock_region *region;
@@ -327,6 +347,13 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 			pr_warn(FW_BUG "Kernel image misaligned at boot, please fix your bootloader!");
 		WARN_TAINT(mmu_enabled_at_boot, TAINT_FIRMWARE_WORKAROUND,
 			   FW_BUG "Booted with MMU enabled!");
+	} else {
+		init_secureboot_mode();
+
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
+		if (efi_enabled(EFI_SECURE_BOOT))
+			security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX);
+#endif
 	}
 
 	arm64_memblock_init();
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index b0d00032479d..afb9544fb007 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -139,6 +139,7 @@ int ipl_report_add_component(struct ipl_report *report, struct kexec_buf *kbuf,
 			     unsigned char flags, unsigned short cert);
 int ipl_report_add_certificate(struct ipl_report *report, void *key,
 			       unsigned long addr, unsigned long len);
+bool ipl_get_secureboot(void);
 
 /*
  * DIAG 308 support
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 3c346b02ceb9..30e16a0d4490 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -2527,3 +2527,8 @@ int ipl_report_free(struct ipl_report *report)
 }
 
 #endif
+
+bool ipl_get_secureboot(void)
+{
+	return !!ipl_secure_flag;
+}
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b60284328fe3..e4d37b08ca29 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -47,6 +47,7 @@
 #include <linux/crash_dump.h>
 #include <linux/memory.h>
 #include <linux/start_kernel.h>
+#include <linux/security.h>
 #include <linux/hugetlb.h>
 #include <linux/kmemleak.h>
 
@@ -917,6 +918,9 @@ void __init setup_arch(char **cmdline_p)
 
 	log_component_list();
 
+	if (ipl_get_secureboot())
+		security_lock_kernel_down("Secure IPL mode", LOCKDOWN_INTEGRITY_MAX);
+
 	/* Have one command line that is parsed and saved in /proc/cmdline */
 	/* boot_command_line has been already set up in early.c */
 	*cmdline_p = boot_command_line;
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 46882ce79c3a..9c73814c31e0 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -21,6 +21,7 @@
 #include <linux/pci.h>
 #include <linux/random.h>
 #include <linux/root_dev.h>
+#include <linux/security.h>
 #include <linux/static_call.h>
 #include <linux/sysfb.h>
 #include <linux/swiotlb.h>
@@ -995,6 +996,13 @@ void __init setup_arch(char **cmdline_p)
 	if (efi_enabled(EFI_BOOT))
 		efi_init();
 
+	efi_set_secure_boot(boot_params.secure_boot);
+
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
+	if (efi_enabled(EFI_SECURE_BOOT))
+		security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX);
+#endif
+
 	reserve_ibft_region();
 	x86_init.resources.dmi_setup();
 
@@ -1156,19 +1164,7 @@ void __init setup_arch(char **cmdline_p)
 	/* Allocate bigger log buffer */
 	setup_log_buf(1);
 
-	if (efi_enabled(EFI_BOOT)) {
-		switch (boot_params.secure_boot) {
-		case efi_secureboot_mode_disabled:
-			pr_info("Secure boot disabled\n");
-			break;
-		case efi_secureboot_mode_enabled:
-			pr_info("Secure boot enabled\n");
-			break;
-		default:
-			pr_info("Secure boot could not be determined\n");
-			break;
-		}
-	}
+	efi_set_secure_boot(boot_params.secure_boot);
 
 	reserve_initrd();
 
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
index 630bb19738be..8da7eedce31e 100644
--- a/crypto/akcipher.c
+++ b/crypto/akcipher.c
@@ -138,8 +138,7 @@ int crypto_register_akcipher(struct akcipher_alg *alg)
 
 	if (!alg->encrypt)
 		alg->encrypt = akcipher_default_op;
-	if (!alg->decrypt)
-		alg->decrypt = akcipher_default_op;
+	alg->decrypt = akcipher_default_op;
 	if (!alg->set_priv_key)
 		alg->set_priv_key = akcipher_default_set_key;
 
diff --git a/crypto/dh.c b/crypto/dh.c
index 7ad4768716c8..01ccc24db074 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -227,10 +227,35 @@ static int dh_compute_value(struct kpp_request *req)
 
 		/* SP800-56A rev 3 5.6.2.1.3 key check */
 		} else {
+			MPI val_pct;
+
 			if (dh_is_pubkey_valid(ctx, val)) {
 				ret = -EAGAIN;
 				goto err_free_val;
 			}
+
+			/*
+			 * SP800-56Arev3, 5.6.2.1.4: ("Owner Assurance
+			 * of Pair-wise Consistency"): recompute the
+			 * public key and check if the results match.
+			 */
+			val_pct = mpi_alloc(0);
+			if (!val_pct) {
+				ret = -ENOMEM;
+				goto err_free_val;
+			}
+
+			ret = _compute_val(ctx, base, val_pct);
+			if (ret) {
+				mpi_free(val_pct);
+				goto err_free_val;
+			}
+
+			if (mpi_cmp(val, val_pct) != 0) {
+				fips_fail_notify();
+				panic("dh: pair-wise consistency test failed\n");
+			}
+			mpi_free(val_pct);
 		}
 	}
 
diff --git a/crypto/seqiv.c b/crypto/seqiv.c
index 678bb4145d78..fcc059e7d3db 100644
--- a/crypto/seqiv.c
+++ b/crypto/seqiv.c
@@ -123,6 +123,19 @@ static int seqiv_aead_decrypt(struct aead_request *req)
 	return crypto_aead_decrypt(subreq);
 }
 
+static int aead_init_seqiv(struct crypto_aead *aead)
+{
+	int err;
+
+	err = aead_init_geniv(aead);
+	if (err)
+		return err;
+
+	crypto_aead_set_flags(aead, CRYPTO_TFM_FIPS_COMPLIANCE);
+
+	return 0;
+}
+
 static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
 {
 	struct aead_instance *inst;
@@ -140,7 +153,7 @@ static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
 	inst->alg.encrypt = seqiv_aead_encrypt;
 	inst->alg.decrypt = seqiv_aead_decrypt;
 
-	inst->alg.init = aead_init_geniv;
+	inst->alg.init = aead_init_seqiv;
 	inst->alg.exit = aead_exit_geniv;
 
 	inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
diff --git a/crypto/sig.c b/crypto/sig.c
index 7d2048da5c3a..6b4e2163fcc5 100644
--- a/crypto/sig.c
+++ b/crypto/sig.c
@@ -112,8 +112,7 @@ static int sig_prepare_alg(struct sig_alg *alg)
 {
 	struct crypto_alg *base = &alg->base;
 
-	if (!alg->sign)
-		alg->sign = sig_default_sign;
+	alg->sign = sig_default_sign;
 	if (!alg->verify)
 		alg->verify = sig_default_verify;
 	if (!alg->set_priv_key)
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 4958211fbfa9..ee6d34885696 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -3831,7 +3831,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
 	 * Don't invoke decrypt test which requires a private key
 	 * for vectors with only a public key.
 	 */
-	if (vecs->public_key_vec) {
+	if (1 || vecs->public_key_vec) {
 		err = 0;
 		goto free_all;
 	}
@@ -3967,7 +3967,7 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs)
 	 * Don't invoke sign test (which requires a private key)
 	 * for vectors with only a public key.
 	 */
-	if (vecs->public_key_vec)
+	if (1 || vecs->public_key_vec)
 		return 0;
 
 	sig_size = crypto_sig_maxsize(tfm);
@@ -4790,14 +4790,12 @@ static const struct alg_test_desc alg_test_descs[] = {
 	}, {
 		.alg = "ecdh-nist-p256",
 		.test = alg_test_kpp,
-		.fips_allowed = 1,
 		.suite = {
 			.kpp = __VECS(ecdh_p256_tv_template)
 		}
 	}, {
 		.alg = "ecdh-nist-p384",
 		.test = alg_test_kpp,
-		.fips_allowed = 1,
 		.suite = {
 			.kpp = __VECS(ecdh_p384_tv_template)
 		}
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 20d757687e3d..90a13f20f052 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -142,6 +142,14 @@ static int apei_hest_parse(apei_hest_func_t func, void *data)
 	if (hest_disable || !hest_tab)
 		return -EINVAL;
 
+#ifdef CONFIG_ARM64
+	/* Ignore broken firmware */
+	if (!strncmp(hest_tab->header.oem_id, "HPE   ", 6) &&
+	    !strncmp(hest_tab->header.oem_table_id, "ProLiant", 8) &&
+	    MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM)
+		return -EINVAL;
+#endif
+
 	hest_hdr = (struct acpi_hest_header *)(hest_tab + 1);
 	for (i = 0; i < hest_tab->error_source_count; i++) {
 		len = hest_esrc_len(hest_hdr);
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
index d1595156c86a..9485212f1a6d 100644
--- a/drivers/acpi/irq.c
+++ b/drivers/acpi/irq.c
@@ -143,6 +143,7 @@ struct acpi_irq_parse_one_ctx {
 	unsigned int index;
 	unsigned long *res_flags;
 	struct irq_fwspec *fwspec;
+	bool skip_producer_check;
 };
 
 /**
@@ -216,7 +217,8 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
 		return AE_CTRL_TERMINATE;
 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		eirq = &ares->data.extended_irq;
-		if (eirq->producer_consumer == ACPI_PRODUCER)
+		if (!ctx->skip_producer_check &&
+		    eirq->producer_consumer == ACPI_PRODUCER)
 			return AE_OK;
 		if (ctx->index >= eirq->interrupt_count) {
 			ctx->index -= eirq->interrupt_count;
@@ -252,8 +254,19 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
 static int acpi_irq_parse_one(acpi_handle handle, unsigned int index,
 			      struct irq_fwspec *fwspec, unsigned long *flags)
 {
-	struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec };
+	struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec, false };
 
+	/*
+	 * Firmware on arm64-based HPE m400 platform incorrectly marks
+	 * its UART interrupt as ACPI_PRODUCER rather than ACPI_CONSUMER.
+	 * Don't do the producer/consumer check for that device.
+	 */
+	if (IS_ENABLED(CONFIG_ARM64)) {
+		struct acpi_device *adev = acpi_get_acpi_dev(handle);
+
+		if (adev && !strcmp(acpi_device_hid(adev), "APMC0D08"))
+			ctx.skip_producer_check = true;
+	}
 	acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_parse_one_cb, &ctx);
 	return ctx.rc;
 }
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9a7ac2eb9ce0..6556c3d7b269 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1794,6 +1794,15 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
 	if (!acpi_match_device_ids(device, ignore_serial_bus_ids))
 		return false;
 
+	/*
+	 * Firmware on some arm64 X-Gene platforms will make the UART
+	 * device appear as both a UART and a slave of that UART. Just
+	 * bail out here for X-Gene UARTs.
+	 */
+	if (IS_ENABLED(CONFIG_ARM64) &&
+	    !strcmp(acpi_device_hid(device), "APMC0D08"))
+		return false;
+
 	INIT_LIST_HEAD(&resource_list);
 	acpi_dev_get_resources(device, &resource_list,
 			       acpi_check_serial_bus_slave,
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 6d72eb017b49..0a6701eb8d37 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -727,6 +727,24 @@ int ahci_stop_engine(struct ata_port *ap)
 	tmp &= ~PORT_CMD_START;
 	writel(tmp, port_mmio + PORT_CMD);
 
+#ifdef CONFIG_ARM64
+	/* Rev Ax of Cavium CN99XX needs a hack for port stop */
+	if (dev_is_pci(ap->host->dev) &&
+	    to_pci_dev(ap->host->dev)->vendor == 0x14e4 &&
+	    to_pci_dev(ap->host->dev)->device == 0x9027 &&
+	    midr_is_cpu_model_range(read_cpuid_id(),
+			MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN),
+			MIDR_CPU_VAR_REV(0, 0),
+			MIDR_CPU_VAR_REV(0, MIDR_REVISION_MASK))) {
+		tmp = readl(hpriv->mmio + 0x8000);
+		udelay(100);
+		writel(tmp | (1 << 26), hpriv->mmio + 0x8000);
+		udelay(100);
+		writel(tmp & ~(1 << 26), hpriv->mmio + 0x8000);
+		dev_warn(ap->host->dev, "CN99XX SATA reset workaround applied\n");
+	}
+#endif
+
 	/* wait for engine to stop. This could be as long as 500 msec */
 	tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
 				PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c
index 505e32911c34..26f7ee0ccf40 100644
--- a/drivers/char/ipmi/ipmi_dmi.c
+++ b/drivers/char/ipmi/ipmi_dmi.c
@@ -215,6 +215,21 @@ static int __init scan_for_dmi_ipmi(void)
 {
 	const struct dmi_device *dev = NULL;
 
+#ifdef CONFIG_ARM64
+	/* RHEL-only
+	 * If this is ARM-based HPE m400, return now, because that platform
+	 * reports the host-side ipmi address as intel port-io space, which
+	 * does not exist in the ARM architecture.
+	 */
+	const char *dmistr = dmi_get_system_info(DMI_PRODUCT_NAME);
+
+	if (dmistr && (strcmp("ProLiant m400 Server", dmistr) == 0)) {
+		pr_debug("%s does not support host ipmi\n", dmistr);
+		return 0;
+	}
+	/* END RHEL-only */
+#endif
+
 	while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev)))
 		dmi_decode_ipmi((const struct dmi_header *) dev->device_data);
 
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index ab4c85f3d6fe..92de1165f6ef 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -34,6 +34,7 @@
 #include <linux/uuid.h>
 #include <linux/nospec.h>
 #include <linux/vmalloc.h>
+#include <linux/dmi.h>
 #include <linux/delay.h>
 
 #define IPMI_DRIVER_VERSION "39.2"
@@ -5643,8 +5644,21 @@ static int __init ipmi_init_msghandler_mod(void)
 {
 	int rv;
 
-	pr_info("version " IPMI_DRIVER_VERSION "\n");
+#ifdef CONFIG_ARM64
+	/* RHEL-only
+	 * If this is ARM-based HPE m400, return now, because that platform
+	 * reports the host-side ipmi address as intel port-io space, which
+	 * does not exist in the ARM architecture.
+	 */
+	const char *dmistr = dmi_get_system_info(DMI_PRODUCT_NAME);
 
+	if (dmistr && (strcmp("ProLiant m400 Server", dmistr) == 0)) {
+		pr_debug("%s does not support host ipmi\n", dmistr);
+		return -ENOSYS;
+	}
+	/* END RHEL-only */
+#endif
+	pr_info("version " IPMI_DRIVER_VERSION "\n");
 	mutex_lock(&ipmi_interfaces_mutex);
 	rv = ipmi_register_driver();
 	mutex_unlock(&ipmi_interfaces_mutex);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index b4da1fb976c1..1e112e2b405b 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -51,9 +51,11 @@
 #include <linux/completion.h>
 #include <linux/uuid.h>
 #include <linux/uaccess.h>
+#include <linux/rcupdate.h>
 #include <linux/suspend.h>
 #include <linux/siphash.h>
 #include <linux/sched/isolation.h>
+#include <linux/fips.h>
 #include <crypto/chacha.h>
 #include <crypto/blake2s.h>
 #include <vdso/datapage.h>
@@ -320,6 +322,11 @@ static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE],
 	memzero_explicit(first_block, sizeof(first_block));
 }
 
+/*
+ * Hook for external RNG.
+ */
+static const struct random_extrng __rcu *extrng;
+
 /*
  * This function returns a ChaCha state that you may use for generating
  * random data. It also returns up to 32 bytes on its own of random data
@@ -732,7 +739,8 @@ static void __cold _credit_init_bits(size_t bits)
 			queue_work(system_dfl_wq, &set_ready);
 		atomic_notifier_call_chain(&random_ready_notifier, 0, NULL);
 		if (IS_ENABLED(CONFIG_VDSO_GETRANDOM))
-			WRITE_ONCE(vdso_k_rng_data->is_ready, true);
+			if (!fips_enabled)
+				WRITE_ONCE(vdso_k_rng_data->is_ready, true);
 		wake_up_interruptible(&crng_init_wait);
 		kill_fasync(&fasync, SIGIO, POLL_IN);
 		pr_notice("crng init done\n");
@@ -751,6 +759,9 @@ static void __cold _credit_init_bits(size_t bits)
 }
 
 
+static const struct file_operations extrng_random_fops;
+static const struct file_operations extrng_urandom_fops;
+
 /**********************************************************************
  *
  * Entropy collection routines.
@@ -967,6 +978,19 @@ void __init add_bootloader_randomness(const void *buf, size_t len)
 		credit_init_bits(len * 8);
 }
 
+void random_register_extrng(const struct random_extrng *rng)
+{
+	rcu_assign_pointer(extrng, rng);
+}
+EXPORT_SYMBOL_GPL(random_register_extrng);
+
+void random_unregister_extrng(void)
+{
+	RCU_INIT_POINTER(extrng, NULL);
+	synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(random_unregister_extrng);
+
 #if IS_ENABLED(CONFIG_VMGENID)
 static BLOCKING_NOTIFIER_HEAD(vmfork_chain);
 
@@ -1381,6 +1405,7 @@ SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags
 {
 	struct iov_iter iter;
 	int ret;
+	const struct random_extrng *rng;
 
 	if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
 		return -EINVAL;
@@ -1392,6 +1417,21 @@ SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags
 	if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
 		return -EINVAL;
 
+	rcu_read_lock();
+	rng = rcu_dereference(extrng);
+	if (rng && !try_module_get(rng->owner))
+		rng = NULL;
+	rcu_read_unlock();
+
+	if (rng) {
+		ret = import_ubuf(ITER_DEST, ubuf, len, &iter);
+		if (unlikely(ret))
+			return ret;
+		ret = rng->extrng_read_iter(&iter, !!(flags & GRND_RANDOM));
+		module_put(rng->owner);
+		return ret;
+	}
+
 	if (!crng_ready() && !(flags & GRND_INSECURE)) {
 		if (flags & GRND_NONBLOCK)
 			return -EAGAIN;
@@ -1412,6 +1452,12 @@ static __poll_t random_poll(struct file *file, poll_table *wait)
 	return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
 }
 
+static __poll_t extrng_poll(struct file *file, poll_table * wait)
+{
+	/* extrng pool is always full, always read, no writes */
+	return EPOLLIN | EPOLLRDNORM;
+}
+
 static ssize_t write_pool_user(struct iov_iter *iter)
 {
 	u8 block[BLAKE2S_BLOCK_SIZE];
@@ -1552,7 +1598,58 @@ static int random_fasync(int fd, struct file *filp, int on)
 	return fasync_helper(fd, filp, on, &fasync);
 }
 
+static int random_open(struct inode *inode, struct file *filp)
+{
+	const struct random_extrng *rng;
+
+	rcu_read_lock();
+	rng = rcu_dereference(extrng);
+	if (rng && !try_module_get(rng->owner))
+		rng = NULL;
+	rcu_read_unlock();
+
+	if (!rng)
+		return 0;
+
+	filp->f_op = &extrng_random_fops;
+	filp->private_data = rng->owner;
+
+	return 0;
+}
+
+static int urandom_open(struct inode *inode, struct file *filp)
+{
+	const struct random_extrng *rng;
+
+	rcu_read_lock();
+	rng = rcu_dereference(extrng);
+	if (rng && !try_module_get(rng->owner))
+		rng = NULL;
+	rcu_read_unlock();
+
+	if (!rng)
+		return 0;
+
+	filp->f_op = &extrng_urandom_fops;
+	filp->private_data = rng->owner;
+
+	return 0;
+}
+
+static int extrng_release(struct inode *inode, struct file *filp)
+{
+	module_put(filp->private_data);
+	return 0;
+}
+
+static ssize_t
+extrng_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
+{
+	return rcu_dereference_raw(extrng)->extrng_read_iter(iter, false);
+}
+
 const struct file_operations random_fops = {
+	.open  = random_open,
 	.read_iter = random_read_iter,
 	.write_iter = random_write_iter,
 	.poll = random_poll,
@@ -1565,6 +1662,7 @@ const struct file_operations random_fops = {
 };
 
 const struct file_operations urandom_fops = {
+	.open  = urandom_open,
 	.read_iter = urandom_read_iter,
 	.write_iter = random_write_iter,
 	.unlocked_ioctl = random_ioctl,
@@ -1575,6 +1673,32 @@ const struct file_operations urandom_fops = {
 	.splice_write = iter_file_splice_write,
 };
 
+static const struct file_operations extrng_random_fops = {
+	.open  = random_open,
+	.read_iter  = extrng_read_iter,
+	.write_iter = random_write_iter,
+	.poll  = extrng_poll,
+	.unlocked_ioctl = random_ioctl,
+	.compat_ioctl = compat_ptr_ioctl,
+	.fasync = random_fasync,
+	.llseek = noop_llseek,
+	.release = extrng_release,
+	.splice_read = copy_splice_read,
+	.splice_write = iter_file_splice_write,
+};
+
+static const struct file_operations extrng_urandom_fops = {
+	.open  = urandom_open,
+	.read_iter  = extrng_read_iter,
+	.write_iter = random_write_iter,
+	.unlocked_ioctl = random_ioctl,
+	.compat_ioctl = compat_ptr_ioctl,
+	.fasync = random_fasync,
+	.llseek = noop_llseek,
+	.release = extrng_release,
+	.splice_read = copy_splice_read,
+	.splice_write = iter_file_splice_write,
+};
 
 /********************************************************************
  *
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 8efbcf699e4f..96d5a1ca981d 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -25,6 +25,7 @@ subdir-$(CONFIG_EFI_STUB)		+= libstub
 obj-$(CONFIG_EFI_BOOTLOADER_CONTROL)	+= efibc.o
 obj-$(CONFIG_EFI_TEST)			+= test/
 obj-$(CONFIG_EFI_DEV_PATH_PARSER)	+= dev-path-parser.o
+obj-$(CONFIG_EFI)			+= secureboot.o
 obj-$(CONFIG_APPLE_PROPERTIES)		+= apple-properties.o
 obj-$(CONFIG_EFI_RCI2_TABLE)		+= rci2-table.o
 obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE)	+= embedded-firmware.o
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 0327a39d31fa..5b5332b4de78 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -33,6 +33,7 @@
 #include <linux/memblock.h>
 #include <linux/security.h>
 #include <linux/notifier.h>
+#include <linux/bsearch.h>
 
 #include <asm/early_ioremap.h>
 
@@ -1017,40 +1018,101 @@ int efi_mem_type(unsigned long phys_addr)
 	return md.type;
 }
 
+struct efi_error_code {
+	efi_status_t status;
+	int errno;
+	const char *description;
+};
+
+static const struct efi_error_code efi_error_codes[] = {
+	{ EFI_SUCCESS, 0, "Success"},
+#if 0
+	{ EFI_LOAD_ERROR, -EPICK_AN_ERRNO, "Load Error"},
+#endif
+	{ EFI_INVALID_PARAMETER, -EINVAL, "Invalid Parameter"},
+	{ EFI_UNSUPPORTED, -ENOSYS, "Unsupported"},
+	{ EFI_BAD_BUFFER_SIZE, -ENOSPC, "Bad Buffer Size"},
+	{ EFI_BUFFER_TOO_SMALL, -ENOSPC, "Buffer Too Small"},
+	{ EFI_NOT_READY, -EAGAIN, "Not Ready"},
+	{ EFI_DEVICE_ERROR, -EIO, "Device Error"},
+	{ EFI_WRITE_PROTECTED, -EROFS, "Write Protected"},
+	{ EFI_OUT_OF_RESOURCES, -ENOMEM, "Out of Resources"},
+#if 0
+	{ EFI_VOLUME_CORRUPTED, -EPICK_AN_ERRNO, "Volume Corrupt"},
+	{ EFI_VOLUME_FULL, -EPICK_AN_ERRNO, "Volume Full"},
+	{ EFI_NO_MEDIA, -EPICK_AN_ERRNO, "No Media"},
+	{ EFI_MEDIA_CHANGED, -EPICK_AN_ERRNO, "Media changed"},
+#endif
+	{ EFI_NOT_FOUND, -ENOENT, "Not Found"},
+#if 0
+	{ EFI_ACCESS_DENIED, -EPICK_AN_ERRNO, "Access Denied"},
+	{ EFI_NO_RESPONSE, -EPICK_AN_ERRNO, "No Response"},
+	{ EFI_NO_MAPPING, -EPICK_AN_ERRNO, "No mapping"},
+	{ EFI_TIMEOUT, -EPICK_AN_ERRNO, "Time out"},
+	{ EFI_NOT_STARTED, -EPICK_AN_ERRNO, "Not started"},
+	{ EFI_ALREADY_STARTED, -EPICK_AN_ERRNO, "Already started"},
+#endif
+	{ EFI_ABORTED, -EINTR, "Aborted"},
+#if 0
+	{ EFI_ICMP_ERROR, -EPICK_AN_ERRNO, "ICMP Error"},
+	{ EFI_TFTP_ERROR, -EPICK_AN_ERRNO, "TFTP Error"},
+	{ EFI_PROTOCOL_ERROR, -EPICK_AN_ERRNO, "Protocol Error"},
+	{ EFI_INCOMPATIBLE_VERSION, -EPICK_AN_ERRNO, "Incompatible Version"},
+#endif
+	{ EFI_SECURITY_VIOLATION, -EACCES, "Security Policy Violation"},
+#if 0
+	{ EFI_CRC_ERROR, -EPICK_AN_ERRNO, "CRC Error"},
+	{ EFI_END_OF_MEDIA, -EPICK_AN_ERRNO, "End of Media"},
+	{ EFI_END_OF_FILE, -EPICK_AN_ERRNO, "End of File"},
+	{ EFI_INVALID_LANGUAGE, -EPICK_AN_ERRNO, "Invalid Languages"},
+	{ EFI_COMPROMISED_DATA, -EPICK_AN_ERRNO, "Compromised Data"},
+
+	// warnings
+	{ EFI_WARN_UNKOWN_GLYPH, -EPICK_AN_ERRNO, "Warning Unknown Glyph"},
+	{ EFI_WARN_DELETE_FAILURE, -EPICK_AN_ERRNO, "Warning Delete Failure"},
+	{ EFI_WARN_WRITE_FAILURE, -EPICK_AN_ERRNO, "Warning Write Failure"},
+	{ EFI_WARN_BUFFER_TOO_SMALL, -EPICK_AN_ERRNO, "Warning Buffer Too Small"},
+#endif
+};
+
+static int
+efi_status_cmp_bsearch(const void *key, const void *item)
+{
+	u64 status = (u64)(uintptr_t)key;
+	struct efi_error_code *code = (struct efi_error_code *)item;
+
+	if (status < code->status)
+		return -1;
+	if (status > code->status)
+		return 1;
+	return 0;
+}
+
 int efi_status_to_err(efi_status_t status)
 {
-	int err;
-
-	switch (status) {
-	case EFI_SUCCESS:
-		err = 0;
-		break;
-	case EFI_INVALID_PARAMETER:
-		err = -EINVAL;
-		break;
-	case EFI_OUT_OF_RESOURCES:
-		err = -ENOSPC;
-		break;
-	case EFI_DEVICE_ERROR:
-		err = -EIO;
-		break;
-	case EFI_WRITE_PROTECTED:
-		err = -EROFS;
-		break;
-	case EFI_SECURITY_VIOLATION:
-		err = -EACCES;
-		break;
-	case EFI_NOT_FOUND:
-		err = -ENOENT;
-		break;
-	case EFI_ABORTED:
-		err = -EINTR;
-		break;
-	default:
-		err = -EINVAL;
-	}
+	struct efi_error_code *found;
+	size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code);
 
-	return err;
+	found = bsearch((void *)(uintptr_t)status, efi_error_codes,
+			num, sizeof(struct efi_error_code),
+			efi_status_cmp_bsearch);
+	if (!found)
+		return -EINVAL;
+	return found->errno;
+}
+
+const char *
+efi_status_to_str(efi_status_t status)
+{
+	struct efi_error_code *found;
+	size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code);
+
+	found = bsearch((void *)(uintptr_t)status, efi_error_codes,
+			num, sizeof(struct efi_error_code),
+			efi_status_cmp_bsearch);
+	if (!found)
+		return "Unknown error code";
+	return found->description;
 }
 EXPORT_SYMBOL_GPL(efi_status_to_err);
 
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 23b3543d3041..0d08a549a10b 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -132,6 +132,11 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
 		}
 	}
 
+	fdt_val32 = cpu_to_fdt32((u32)efi_get_secureboot());
+	status = fdt_setprop_var(fdt, node, "secure-boot-mode", fdt_val32);
+	if (status)
+		goto fdt_set_fail;
+
 	/* Shrink the FDT back to its minimum size: */
 	fdt_pack(fdt);
 
diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
index 516f4f0069bd..380354755108 100644
--- a/drivers/firmware/efi/libstub/secureboot.c
+++ b/drivers/firmware/efi/libstub/secureboot.c
@@ -29,10 +29,13 @@ enum efi_secureboot_mode efi_get_secureboot(void)
 {
 	u32 attr;
 	unsigned long size;
-	enum efi_secureboot_mode mode;
+	static enum efi_secureboot_mode mode;
 	efi_status_t status;
 	u8 moksbstate;
 
+	if (mode != efi_secureboot_mode_unset)
+		return mode;
+
 	mode = efi_get_secureboot_mode(get_var);
 	if (mode == efi_secureboot_mode_unknown) {
 		efi_err("Could not determine UEFI Secure Boot status.\n");
@@ -53,10 +56,13 @@ enum efi_secureboot_mode efi_get_secureboot(void)
 	/* If it fails, we don't care why. Default to secure */
 	if (status != EFI_SUCCESS)
 		goto secure_boot_enabled;
-	if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1)
-		return efi_secureboot_mode_disabled;
+	if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1) {
+		mode = efi_secureboot_mode_disabled;
+		return mode;
+	}
 
 secure_boot_enabled:
 	efi_info("UEFI Secure Boot is enabled.\n");
-	return efi_secureboot_mode_enabled;
+	mode = efi_secureboot_mode_enabled;
+	return mode;
 }
diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c
new file mode 100644
index 000000000000..de0a3714a5d4
--- /dev/null
+++ b/drivers/firmware/efi/secureboot.c
@@ -0,0 +1,38 @@
+/* Core kernel secure boot support.
+ *
+ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/efi.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+
+/*
+ * Decide what to do when UEFI secure boot mode is enabled.
+ */
+void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
+{
+	if (efi_enabled(EFI_BOOT)) {
+		switch (mode) {
+		case efi_secureboot_mode_disabled:
+			pr_info("Secure boot disabled\n");
+			break;
+		case efi_secureboot_mode_enabled:
+			set_bit(EFI_SECURE_BOOT, &efi.flags);
+			pr_info("Secure boot enabled\n");
+			break;
+		default:
+			pr_warn("Secure boot could not be determined (mode %u)\n",
+				   mode);
+			break;
+		}
+	}
+}
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 14bb31bd6a0b..0529359d7440 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/device.h>
+#include <linux/dmi.h>
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/fs.h>
@@ -2447,6 +2448,16 @@ static const struct amba_id etm4_ids[] = {
 	{},
 };
 
+static const struct dmi_system_id broken_coresight[] = {
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HPE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Apollo 70"),
+		},
+	},
+	{ }	/* terminating entry */
+};
+
 MODULE_DEVICE_TABLE(amba, etm4_ids);
 
 static struct amba_driver etm4x_amba_driver = {
@@ -2521,6 +2532,11 @@ static int __init etm4x_init(void)
 {
 	int ret;
 
+	if (dmi_check_system(broken_coresight)) {
+		pr_info("ETM4 disabled due to firmware bug\n");
+		return 0;
+	}
+
 	ret = etm4_pm_setup();
 
 	/* etm4_pm_setup() does its own cleanup - exit on error */
@@ -2547,6 +2563,9 @@ static int __init etm4x_init(void)
 
 static void __exit etm4x_exit(void)
 {
+	if (dmi_check_system(broken_coresight))
+		return;
+
 	amba_driver_unregister(&etm4x_amba_driver);
 	platform_driver_unregister(&etm4_platform_driver);
 	etm4_pm_clear();
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index e8f13dcebbde..dd7014ca962c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -8,6 +8,7 @@
 
 #include <linux/amba/bus.h>
 #include <linux/device.h>
+#include <linux/dmi.h>
 #include <linux/kernel.h>
 #include <linux/bits.h>
 #include <linux/bug.h>
@@ -3135,6 +3136,27 @@ int iommu_fwspec_add_ids(struct device *dev, const u32 *ids, int num_ids)
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
 
+#ifdef CONFIG_ARM64
+static int __init iommu_quirks(void)
+{
+	const char *vendor, *name;
+
+	vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+	name = dmi_get_system_info(DMI_PRODUCT_NAME);
+
+	if (vendor &&
+	    (strncmp(vendor, "GIGABYTE", 8) == 0 && name &&
+	     (strncmp(name, "R120", 4) == 0 ||
+	      strncmp(name, "R270", 4) == 0))) {
+		pr_warn("Gigabyte %s detected, force iommu passthrough mode", name);
+		iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
+	}
+
+	return 0;
+}
+arch_initcall(iommu_quirks);
+#endif
+
 /**
  * iommu_setup_default_domain - Set the default_domain for the group
  * @group: Group to change
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index b09f27f7846f..b54fe538511a 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4496,6 +4496,30 @@ static void quirk_aspeed_pci_bridge_no_alias(struct pci_dev *pdev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASPEED, 0x1150, quirk_aspeed_pci_bridge_no_alias);
 
+/*
+ * PCI BAR 5 is not setup correctly for the on-board AHCI controller
+ * on Broadcom's Vulcan processor. Added a quirk to fix BAR 5 by
+ * using BAR 4's resources which are populated correctly and NOT
+ * actually used by the AHCI controller.
+ */
+static void quirk_fix_vulcan_ahci_bars(struct pci_dev *dev)
+{
+	struct resource *r =  &dev->resource[4];
+
+	if (!(r->flags & IORESOURCE_MEM) || (r->start == 0))
+		return;
+
+	/* Set BAR5 resource to BAR4 */
+	dev->resource[5] = *r;
+
+	/* Update BAR5 in pci config space */
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_5, r->start);
+
+	/* Clear BAR4's resource */
+	memset(r, 0, sizeof(*r));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9027, quirk_fix_vulcan_ahci_bars);
+
 /*
  * Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero)
  * class code.  Fix it.
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d92bf887739d..039fd5620282 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5902,6 +5902,13 @@ static void hub_event(struct work_struct *work)
 			(u16) hub->change_bits[0],
 			(u16) hub->event_bits[0]);
 
+	/* Don't disconnect USB-SATA on TrimSlice */
+	if (strcmp(dev_name(hdev->bus->controller), "tegra-ehci.0") == 0) {
+		if ((hdev->state == 7) && (hub->change_bits[0] == 0) &&
+				(hub->event_bits[0] == 0x2))
+			hub->event_bits[0] = 0;
+	}
+
 	/* Lock the device, then check to see if we were
 	 * disconnected while waiting for the lock to succeed. */
 	usb_lock_device(hdev);
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index b7c97f1c47c9..0a484f45b24a 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -152,6 +152,8 @@
 #define CRYPTO_TFM_REQ_MAY_BACKLOG	0x00000400
 #define CRYPTO_TFM_REQ_ON_STACK		0x00000800
 
+#define CRYPTO_TFM_FIPS_COMPLIANCE	0x80000000
+
 /*
  * Miscellaneous stuff.
  */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index ccbc35479684..8eb9a1276ba7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -45,6 +45,8 @@ struct screen_info;
 #define EFI_ABORTED		(21 | (1UL << (BITS_PER_LONG-1)))
 #define EFI_SECURITY_VIOLATION	(26 | (1UL << (BITS_PER_LONG-1)))
 
+#define EFI_IS_ERROR(x)		((x) & (1UL << (BITS_PER_LONG-1)))
+
 typedef unsigned long efi_status_t;
 typedef u8 efi_bool_t;
 typedef u16 efi_char16_t;		/* UNICODE character */
@@ -847,6 +849,14 @@ extern int __init parse_efi_signature_list(
 #define EFI_MEM_ATTR		9	/* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
 #define EFI_MEM_NO_SOFT_RESERVE	10	/* Is the kernel configured to ignore soft reservations? */
 #define EFI_PRESERVE_BS_REGIONS	11	/* Are EFI boot-services memory segments available? */
+#define EFI_SECURE_BOOT		12	/* Are we in Secure Boot mode? */
+
+enum efi_secureboot_mode {
+	efi_secureboot_mode_unset,
+	efi_secureboot_mode_unknown,
+	efi_secureboot_mode_disabled,
+	efi_secureboot_mode_enabled,
+};
 
 #ifdef CONFIG_EFI
 /*
@@ -858,6 +868,8 @@ static inline bool efi_enabled(int feature)
 }
 extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
 
+extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode);
+
 bool __pure __efi_soft_reserve_enabled(void);
 
 static inline bool __pure efi_soft_reserve_enabled(void)
@@ -879,6 +891,8 @@ static inline bool efi_enabled(int feature)
 static inline void
 efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {}
 
+static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {}
+
 static inline bool efi_soft_reserve_enabled(void)
 {
 	return false;
@@ -893,6 +907,7 @@ static inline void efi_find_mirror(void) {}
 #endif
 
 extern int efi_status_to_err(efi_status_t status);
+extern const char *efi_status_to_str(efi_status_t status);
 
 /*
  * Variable Attributes
@@ -1110,13 +1125,6 @@ extern unsigned long efi_call_virt_save_flags(void);
 
 void efi_runtime_assert_lock_held(void);
 
-enum efi_secureboot_mode {
-	efi_secureboot_mode_unset,
-	efi_secureboot_mode_unknown,
-	efi_secureboot_mode_disabled,
-	efi_secureboot_mode_enabled,
-};
-
 static inline
 enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var)
 {
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 65c9609ec207..2cc243ec73f6 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -456,6 +456,7 @@ LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap)
 
 LSM_HOOK(int, 0, locked_down, enum lockdown_reason what)
 
+
 #ifdef CONFIG_PERF_EVENTS
 LSM_HOOK(int, 0, perf_event_open, int type)
 LSM_HOOK(int, 0, perf_event_alloc, struct perf_event *event)
diff --git a/include/linux/random.h b/include/linux/random.h
index 8a8064dc3970..3238fab8f749 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,13 @@
 
 #include <uapi/linux/random.h>
 
+struct iov_iter;
+
+struct random_extrng {
+	ssize_t (*extrng_read_iter)(struct iov_iter *iter, bool reseed);
+	struct module *owner;
+};
+
 struct notifier_block;
 
 void add_device_randomness(const void *buf, size_t len);
@@ -135,6 +142,9 @@ int random_prepare_cpu(unsigned int cpu);
 int random_online_cpu(unsigned int cpu);
 #endif
 
+void random_register_extrng(const struct random_extrng *rng);
+void random_unregister_extrng(void);
+
 #ifndef MODULE
 extern const struct file_operations random_fops, urandom_fops;
 #endif
diff --git a/include/linux/security.h b/include/linux/security.h
index 153e9043058f..2ee3a8990968 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -2439,4 +2439,13 @@ static inline void security_initramfs_populated(void)
 }
 #endif /* CONFIG_SECURITY */
 
+#ifdef CONFIG_SECURITY_LOCKDOWN_LSM
+extern int security_lock_kernel_down(const char *where, enum lockdown_reason level);
+#else
+static inline int security_lock_kernel_down(const char *where, enum lockdown_reason level)
+{
+	return 0;
+}
+#endif /* CONFIG_SECURITY_LOCKDOWN_LSM */
+
 #endif /* ! __LINUX_SECURITY_H */
diff --git a/kernel/module/signing.c b/kernel/module/signing.c
index 590ba29c85ab..02153d857531 100644
--- a/kernel/module/signing.c
+++ b/kernel/module/signing.c
@@ -61,10 +61,17 @@ int mod_verify_sig(const void *mod, struct load_info *info)
 	modlen -= sig_len + sizeof(ms);
 	info->len = modlen;
 
-	return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+	ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
 				      VERIFY_USE_SECONDARY_KEYRING,
 				      VERIFYING_MODULE_SIGNATURE,
 				      NULL, NULL);
+	if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) {
+		ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+				VERIFY_USE_PLATFORM_KEYRING,
+				VERIFYING_MODULE_SIGNATURE,
+				NULL, NULL);
+	}
+	return ret;
 }
 
 int module_sig_check(struct load_info *info, int flags)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0a4fdd8bd975..dcb12dad419f 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -207,7 +207,10 @@ objtool-args-$(CONFIG_STACK_VALIDATION)			+= --stackval
 objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE)		+= --static-call
 objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION)		+= --uaccess
 objtool-args-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV))	+= --no-unreachable
+# RHEL-only: don't enforce OBJTOOL_WERROR for out of tree modules
+ifeq ($(KBUILD_EXTMOD),)
 objtool-args-$(CONFIG_OBJTOOL_WERROR)			+= --werror
+endif
 
 objtool-args = $(objtool-args-y)					\
 	$(if $(delay-objtool), --link)					\
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 243373683f98..2affd5e58ee8 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -16,6 +16,8 @@ fi
 ignore="$(echo "$RCS_FIND_IGNORE" | sed 's|\\||g' )"
 # tags and cscope files should also ignore MODVERSION *.mod.c files
 ignore="$ignore ( -name *.mod.c ) -prune -o"
+# RHEL tags and cscope should also ignore redhat/rpm
+ignore="$ignore ( -path redhat/rpm ) -prune -o"
 
 # ignore arbitrary directories
 if [ -n "${IGNORE_DIRS}" ]; then
diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
index c0d6948446c3..bed56532e206 100644
--- a/security/integrity/platform_certs/load_uefi.c
+++ b/security/integrity/platform_certs/load_uefi.c
@@ -74,7 +74,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
 		return NULL;
 
 	if (*status != EFI_BUFFER_TOO_SMALL) {
-		pr_err("Couldn't get size: 0x%lx\n", *status);
+		pr_err("Couldn't get size: %s (0x%lx)\n",
+		       efi_status_to_str(*status), *status);
 		return NULL;
 	}
 
@@ -85,7 +86,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
 	*status = efi.get_variable(name, guid, NULL, &lsize, db);
 	if (*status != EFI_SUCCESS) {
 		kfree(db);
-		pr_err("Error reading db var: 0x%lx\n", *status);
+		pr_err("Error reading db var: %s (0x%lx)\n",
+		       efi_status_to_str(*status), *status);
 		return NULL;
 	}
 
diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig
index e84ddf484010..d0501353a4b9 100644
--- a/security/lockdown/Kconfig
+++ b/security/lockdown/Kconfig
@@ -16,6 +16,19 @@ config SECURITY_LOCKDOWN_LSM_EARLY
 	  subsystem is fully initialised. If enabled, lockdown will
 	  unconditionally be called before any other LSMs.
 
+config LOCK_DOWN_IN_EFI_SECURE_BOOT
+	bool "Lock down the kernel in EFI Secure Boot mode"
+	default n
+	depends on EFI && SECURITY_LOCKDOWN_LSM_EARLY
+	help
+	  UEFI Secure Boot provides a mechanism for ensuring that the firmware
+	  will only load signed bootloaders and kernels.  Secure boot mode may
+	  be determined from EFI variables provided by the system firmware if
+	  not indicated by the boot parameters.
+
+	  Enabling this option results in kernel lockdown being triggered if
+	  EFI Secure Boot is set.
+
 choice
 	prompt "Kernel default lockdown mode"
 	default LOCK_DOWN_KERNEL_FORCE_NONE
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
index 8d46886d2cca..14a9cdff942b 100644
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -72,6 +72,17 @@ static int lockdown_is_locked_down(enum lockdown_reason what)
 	return 0;
 }
 
+/**
+ * security_lock_kernel_down() - Put the kernel into lock-down mode.
+ *
+ * @where: Where the lock-down is originating from (e.g. command line option)
+ * @level: The lock-down level (can only increase)
+ */
+int security_lock_kernel_down(const char *where, enum lockdown_reason level)
+{
+	return lock_kernel_down(where, level);
+}
+
 static struct security_hook_list lockdown_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
 };
diff --git a/tools/testing/selftests/bpf/DENYLIST.rhel b/tools/testing/selftests/bpf/DENYLIST.rhel
new file mode 100644
index 000000000000..9424a83c6f48
--- /dev/null
+++ b/tools/testing/selftests/bpf/DENYLIST.rhel
@@ -0,0 +1,76 @@
+# Tests that need CONFIG_FUNCTION_ERROR_INJECTION
+# Typical observed errors are:
+#     <...some function...> is not sleepable
+#     <...some function...> is not modifiable
+cgrp_local_storage/yes_rcu_lock
+cgrp_local_storage/no_rcu_lock
+cgrp_local_storage/cgrp1_yes_rcu_lock
+cgrp_local_storage/cgrp1_no_rcu_lock
+compute_live_registers/addr_space_cast
+dynptr/test_read_write
+dynptr/test_dynptr_data
+dynptr/test_dynptr_copy
+dynptr/test_dynptr_copy_xdp
+dynptr/test_dynptr_memset_zero
+dynptr/test_dynptr_memset_notzero
+dynptr/test_dynptr_memset_zero_offset
+dynptr/test_dynptr_memset_zero_adjusted
+dynptr/test_dynptr_memset_overflow
+dynptr/test_dynptr_memset_overflow_offset
+dynptr/test_dynptr_memset_readonly
+dynptr/test_dynptr_memset_xdp_chunks
+dynptr/test_dynptr_skb_meta_data
+dynptr/test_dynptr_skb_meta_flags
+dynptr/test_ringbuf
+dynptr/test_skb_readonly
+dynptr/test_dynptr_skb_data
+dynptr/test_adjust
+dynptr/test_adjust_err
+dynptr/test_zero_size_dynptr
+dynptr/test_dynptr_is_null
+dynptr/test_dynptr_is_rdonly
+dynptr/test_dynptr_clone
+dynptr/test_dynptr_skb_no_buff
+dynptr/test_dynptr_skb_strcmp
+dynptr/test_dynptr_skb_tp_btf
+dynptr/test_probe_read_user_dynptr
+dynptr/test_probe_read_kernel_dynptr
+dynptr/test_probe_read_user_str_dynptr
+dynptr/test_probe_read_kernel_str_dynptr
+dynptr/test_copy_from_user_dynptr
+dynptr/test_copy_from_user_str_dynptr
+dynptr/test_copy_from_user_task_dynptr
+dynptr/test_copy_from_user_task_str_dynptr
+irq/irq_sleepable_helper
+irq/irq_sleepable_kfunc
+iters/iter_css_task_for_each_sleep
+iters/iter_ret_rcu_test_protected
+iters/iter_ret_rcu_test_type
+iters/iter_ret_rcu_test_protected_nostruct
+iters/iter_ret_rcu_test_type_nostruct
+iters/task
+iters/css
+iters/iter_tasks_without_lock
+iters/iter_css_without_lock
+iters/iter_tasks_lock_and_unlock
+iters/iter_css_lock_and_unlock
+map_excl/map_excl_allowed
+map_in_map/sleepable_acc_map_in_array
+map_in_map/sleepable_acc_map_in_htab
+mem_rdonly_untrusted/helper_param_not_ok
+module_attach
+preempt_lock/preempt_sleepable_helper
+preempt_lock/preempt_sleepable_kfunc
+rcu_read_lock/success
+rcu_read_lock/rcuptr_acquire
+read_vsyscall
+refcounted_kptr/rbtree_sleepable_rcu
+refcounted_kptr/rbtree_sleepable_rcu_no_explicit_rcu_lock
+refcounted_kptr_fail/rbtree_fail_sleepable_lock_across_rcu
+test_lsm/lsm_basic
+verifier_global_subprogs/arg_tag_ctx_fmod_ret
+
+kprobe_multi_test/attach_override                # needs CONFIG_BPF_KPROBE_OVERRIDE
+libbpf_probe_prog_types/BPF_PROG_TYPE_LIRC_MODE2 # needs CONFIG_BPF_LIRC_MODE2
+test_bpffs                                       # needs CONFIG_BPF_PRELOAD
+tunnel                                           # needs CONFIG_NET_FOU
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index b642ee489ea6..7e3204186a8b 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -532,7 +532,7 @@ LSKELS := fexit_sleep.c trace_printk.c trace_vprintk.c map_ptr_kern.c 	\
 LSKELS_SIGNED := fentry_test.c fexit_test.c atomics.c
 
 # Generate both light skeleton and libbpf skeleton for these
-LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c kfunc_call_test.c \
+LSKELS_EXTRA := test_ksyms_module.c kfunc_call_test.c \
 	kfunc_call_test_subprog.c
 SKEL_BLACKLIST += $$(LSKELS) $$(LSKELS_SIGNED)
 
diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c b/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
index 1d7a2f1e0731..b22f3a9cb8b8 100644
--- a/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
+++ b/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
@@ -7,7 +7,6 @@
 #include "test_ksyms_btf.skel.h"
 #include "test_ksyms_btf_null_check.skel.h"
 #include "test_ksyms_weak.skel.h"
-#include "test_ksyms_weak.lskel.h"
 #include "test_ksyms_btf_write_check.skel.h"
 
 static int duration;
@@ -111,33 +110,6 @@ static void test_weak_syms(void)
 	test_ksyms_weak__destroy(skel);
 }
 
-static void test_weak_syms_lskel(void)
-{
-	struct test_ksyms_weak_lskel *skel;
-	struct test_ksyms_weak_lskel__data *data;
-	int err;
-
-	skel = test_ksyms_weak_lskel__open_and_load();
-	if (!ASSERT_OK_PTR(skel, "test_ksyms_weak_lskel__open_and_load"))
-		return;
-
-	err = test_ksyms_weak_lskel__attach(skel);
-	if (!ASSERT_OK(err, "test_ksyms_weak_lskel__attach"))
-		goto cleanup;
-
-	/* trigger tracepoint */
-	usleep(1);
-
-	data = skel->data;
-	ASSERT_EQ(data->out__existing_typed, 0, "existing typed ksym");
-	ASSERT_NEQ(data->out__existing_typeless, -1, "existing typeless ksym");
-	ASSERT_EQ(data->out__non_existent_typeless, 0, "nonexistent typeless ksym");
-	ASSERT_EQ(data->out__non_existent_typed, 0, "nonexistent typed ksym");
-
-cleanup:
-	test_ksyms_weak_lskel__destroy(skel);
-}
-
 static void test_write_check(bool test_handler1)
 {
 	struct test_ksyms_btf_write_check *skel;
@@ -180,9 +152,6 @@ void test_ksyms_btf(void)
 	if (test__start_subtest("weak_ksyms"))
 		test_weak_syms();
 
-	if (test__start_subtest("weak_ksyms_lskel"))
-		test_weak_syms_lskel();
-
 	if (test__start_subtest("write_check1"))
 		test_write_check(true);
 
