From: Greg Kroah-Hartman Date: Mon, 16 Mar 2020 13:17:48 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.19.111~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=24e4957af868fd8b795e894c70df31e6735da9f7;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: arc-define-__align_str-and-__align-symbols-for-arc.patch efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch efi-make-efi_rts_work-accessible-to-efi-page-fault-handler.patch gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch iommu-dma-fix-msi-reservation-allocation.patch iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch macintosh-windfarm-fix-modinfo-regression.patch mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch --- diff --git a/queue-4.19/arc-define-__align_str-and-__align-symbols-for-arc.patch b/queue-4.19/arc-define-__align_str-and-__align-symbols-for-arc.patch new file mode 100644 index 00000000000..17e39085553 --- /dev/null +++ b/queue-4.19/arc-define-__align_str-and-__align-symbols-for-arc.patch @@ -0,0 +1,35 @@ +From 8d92e992a785f35d23f845206cf8c6cafbc264e0 Mon Sep 17 00:00:00 2001 +From: Eugeniy Paltsev +Date: Wed, 11 Mar 2020 19:26:43 +0300 +Subject: ARC: define __ALIGN_STR and __ALIGN symbols for ARC + +From: Eugeniy Paltsev + +commit 8d92e992a785f35d23f845206cf8c6cafbc264e0 upstream. + +The default defintions use fill pattern 0x90 for padding which for ARC +generates unintended "ldh_s r12,[r0,0x20]" corresponding to opcode 0x9090 + +So use ".align 4" which insert a "nop_s" instruction instead. + +Cc: stable@vger.kernel.org +Acked-by: Vineet Gupta +Signed-off-by: Eugeniy Paltsev +Signed-off-by: Vineet Gupta +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arc/include/asm/linkage.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arc/include/asm/linkage.h ++++ b/arch/arc/include/asm/linkage.h +@@ -14,6 +14,8 @@ + #ifdef __ASSEMBLY__ + + #define ASM_NL ` /* use '`' to mark new line in macro */ ++#define __ALIGN .align 4 ++#define __ALIGN_STR __stringify(__ALIGN) + + /* annotation for data we want in DCCM - if enabled in .config */ + .macro ARCFP_DATA nm diff --git a/queue-4.19/efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch b/queue-4.19/efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch new file mode 100644 index 00000000000..5790803142b --- /dev/null +++ b/queue-4.19/efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch @@ -0,0 +1,138 @@ +From 286d3250c9d6437340203fb64938bea344729a0e Mon Sep 17 00:00:00 2001 +From: Vladis Dronov +Date: Sun, 8 Mar 2020 09:08:54 +0100 +Subject: efi: Fix a race and a buffer overflow while reading efivars via sysfs + +From: Vladis Dronov + +commit 286d3250c9d6437340203fb64938bea344729a0e upstream. + +There is a race and a buffer overflow corrupting a kernel memory while +reading an EFI variable with a size more than 1024 bytes via the older +sysfs method. This happens because accessing struct efi_variable in +efivar_{attr,size,data}_read() and friends is not protected from +a concurrent access leading to a kernel memory corruption and, at best, +to a crash. The race scenario is the following: + +CPU0: CPU1: +efivar_attr_read() + var->DataSize = 1024; + efivar_entry_get(... &var->DataSize) + down_interruptible(&efivars_lock) + efivar_attr_read() // same EFI var + var->DataSize = 1024; + efivar_entry_get(... &var->DataSize) + down_interruptible(&efivars_lock) + virt_efi_get_variable() + // returns EFI_BUFFER_TOO_SMALL but + // var->DataSize is set to a real + // var size more than 1024 bytes + up(&efivars_lock) + virt_efi_get_variable() + // called with var->DataSize set + // to a real var size, returns + // successfully and overwrites + // a 1024-bytes kernel buffer + up(&efivars_lock) + +This can be reproduced by concurrent reading of an EFI variable which size +is more than 1024 bytes: + + ts# for cpu in $(seq 0 $(nproc --ignore=1)); do ( taskset -c $cpu \ + cat /sys/firmware/efi/vars/KEKDefault*/size & ) ; done + +Fix this by using a local variable for a var's data buffer size so it +does not get overwritten. + +Fixes: e14ab23dde12b80d ("efivars: efivar_entry API") +Reported-by: Bob Sanders and the LTP testsuite +Signed-off-by: Vladis Dronov +Signed-off-by: Ard Biesheuvel +Signed-off-by: Ingo Molnar +Cc: +Link: https://lore.kernel.org/r/20200305084041.24053-2-vdronov@redhat.com +Link: https://lore.kernel.org/r/20200308080859.21568-24-ardb@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/efi/efivars.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +--- a/drivers/firmware/efi/efivars.c ++++ b/drivers/firmware/efi/efivars.c +@@ -139,13 +139,16 @@ static ssize_t + efivar_attr_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); + char *str = buf; ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) +@@ -172,13 +175,16 @@ static ssize_t + efivar_size_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); + char *str = buf; ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + str += sprintf(str, "0x%lx\n", var->DataSize); +@@ -189,12 +195,15 @@ static ssize_t + efivar_data_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + memcpy(buf, var->Data, var->DataSize); +@@ -314,14 +323,16 @@ efivar_show_raw(struct efivar_entry *ent + { + struct efi_variable *var = &entry->var; + struct compat_efi_variable *compat; ++ unsigned long datasize = sizeof(var->Data); + size_t size; ++ int ret; + + if (!entry || !buf) + return 0; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &entry->var.Attributes, +- &entry->var.DataSize, entry->var.Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); ++ var->DataSize = datasize; ++ if (ret) + return -EIO; + + if (is_compat()) { diff --git a/queue-4.19/efi-make-efi_rts_work-accessible-to-efi-page-fault-handler.patch b/queue-4.19/efi-make-efi_rts_work-accessible-to-efi-page-fault-handler.patch new file mode 100644 index 00000000000..af30af7185c --- /dev/null +++ b/queue-4.19/efi-make-efi_rts_work-accessible-to-efi-page-fault-handler.patch @@ -0,0 +1,164 @@ +From 9dbbedaa6171247c4c7c40b83f05b200a117c2e0 Mon Sep 17 00:00:00 2001 +From: Sai Praneeth +Date: Tue, 11 Sep 2018 12:15:21 -0700 +Subject: efi: Make efi_rts_work accessible to efi page fault handler + +From: Sai Praneeth + +commit 9dbbedaa6171247c4c7c40b83f05b200a117c2e0 upstream. + +After the kernel has booted, if any accesses by firmware causes a page +fault, the efi page fault handler would freeze efi_rts_wq and schedules +a new process. To do this, the efi page fault handler needs +efi_rts_work. Hence, make it accessible. + +There will be no race conditions in accessing this structure, because +all the calls to efi runtime services are already serialized. + +Tested-by: Bhupesh Sharma +Suggested-by: Matt Fleming +Based-on-code-from: Ricardo Neri +Signed-off-by: Sai Praneeth Prakhya +Signed-off-by: Ard Biesheuvel +Fixes: 3eb420e70d87 (“efi: Use a work queue to invoke EFI Runtime Services”) +Signed-off-by: Wen Yang +Cc: Caspar Zhang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/efi/runtime-wrappers.c | 53 +++++--------------------------- + include/linux/efi.h | 36 +++++++++++++++++++++ + 2 files changed, 45 insertions(+), 44 deletions(-) + +--- a/drivers/firmware/efi/runtime-wrappers.c ++++ b/drivers/firmware/efi/runtime-wrappers.c +@@ -45,39 +45,7 @@ + #define __efi_call_virt(f, args...) \ + __efi_call_virt_pointer(efi.systab->runtime, f, args) + +-/* efi_runtime_service() function identifiers */ +-enum efi_rts_ids { +- GET_TIME, +- SET_TIME, +- GET_WAKEUP_TIME, +- SET_WAKEUP_TIME, +- GET_VARIABLE, +- GET_NEXT_VARIABLE, +- SET_VARIABLE, +- QUERY_VARIABLE_INFO, +- GET_NEXT_HIGH_MONO_COUNT, +- UPDATE_CAPSULE, +- QUERY_CAPSULE_CAPS, +-}; +- +-/* +- * efi_runtime_work: Details of EFI Runtime Service work +- * @arg<1-5>: EFI Runtime Service function arguments +- * @status: Status of executing EFI Runtime Service +- * @efi_rts_id: EFI Runtime Service function identifier +- * @efi_rts_comp: Struct used for handling completions +- */ +-struct efi_runtime_work { +- void *arg1; +- void *arg2; +- void *arg3; +- void *arg4; +- void *arg5; +- efi_status_t status; +- struct work_struct work; +- enum efi_rts_ids efi_rts_id; +- struct completion efi_rts_comp; +-}; ++struct efi_runtime_work efi_rts_work; + + /* + * efi_queue_work: Queue efi_runtime_service() and wait until it's done +@@ -91,7 +59,6 @@ struct efi_runtime_work { + */ + #define efi_queue_work(_rts, _arg1, _arg2, _arg3, _arg4, _arg5) \ + ({ \ +- struct efi_runtime_work efi_rts_work; \ + efi_rts_work.status = EFI_ABORTED; \ + \ + init_completion(&efi_rts_work.efi_rts_comp); \ +@@ -191,18 +158,16 @@ extern struct semaphore __efi_uv_runtime + */ + static void efi_call_rts(struct work_struct *work) + { +- struct efi_runtime_work *efi_rts_work; + void *arg1, *arg2, *arg3, *arg4, *arg5; + efi_status_t status = EFI_NOT_FOUND; + +- efi_rts_work = container_of(work, struct efi_runtime_work, work); +- arg1 = efi_rts_work->arg1; +- arg2 = efi_rts_work->arg2; +- arg3 = efi_rts_work->arg3; +- arg4 = efi_rts_work->arg4; +- arg5 = efi_rts_work->arg5; ++ arg1 = efi_rts_work.arg1; ++ arg2 = efi_rts_work.arg2; ++ arg3 = efi_rts_work.arg3; ++ arg4 = efi_rts_work.arg4; ++ arg5 = efi_rts_work.arg5; + +- switch (efi_rts_work->efi_rts_id) { ++ switch (efi_rts_work.efi_rts_id) { + case GET_TIME: + status = efi_call_virt(get_time, (efi_time_t *)arg1, + (efi_time_cap_t *)arg2); +@@ -260,8 +225,8 @@ static void efi_call_rts(struct work_str + */ + pr_err("Requested executing invalid EFI Runtime Service.\n"); + } +- efi_rts_work->status = status; +- complete(&efi_rts_work->efi_rts_comp); ++ efi_rts_work.status = status; ++ complete(&efi_rts_work.efi_rts_comp); + } + + static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -1664,6 +1664,42 @@ struct linux_efi_tpm_eventlog { + + extern int efi_tpm_eventlog_init(void); + ++/* efi_runtime_service() function identifiers */ ++enum efi_rts_ids { ++ GET_TIME, ++ SET_TIME, ++ GET_WAKEUP_TIME, ++ SET_WAKEUP_TIME, ++ GET_VARIABLE, ++ GET_NEXT_VARIABLE, ++ SET_VARIABLE, ++ QUERY_VARIABLE_INFO, ++ GET_NEXT_HIGH_MONO_COUNT, ++ UPDATE_CAPSULE, ++ QUERY_CAPSULE_CAPS, ++}; ++ ++/* ++ * efi_runtime_work: Details of EFI Runtime Service work ++ * @arg<1-5>: EFI Runtime Service function arguments ++ * @status: Status of executing EFI Runtime Service ++ * @efi_rts_id: EFI Runtime Service function identifier ++ * @efi_rts_comp: Struct used for handling completions ++ */ ++struct efi_runtime_work { ++ void *arg1; ++ void *arg2; ++ void *arg3; ++ void *arg4; ++ void *arg5; ++ efi_status_t status; ++ struct work_struct work; ++ enum efi_rts_ids efi_rts_id; ++ struct completion efi_rts_comp; ++}; ++ ++extern struct efi_runtime_work efi_rts_work; ++ + /* Workqueue to queue EFI Runtime Services */ + extern struct workqueue_struct *efi_rts_wq; + diff --git a/queue-4.19/gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch b/queue-4.19/gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch new file mode 100644 index 00000000000..7c50ef362a7 --- /dev/null +++ b/queue-4.19/gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch @@ -0,0 +1,34 @@ +From 21039132650281de06a169cbe8a0f7e5c578fd8b Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Tue, 10 Mar 2020 09:31:41 -0400 +Subject: gfs2_atomic_open(): fix O_EXCL|O_CREAT handling on cold dcache + +From: Al Viro + +commit 21039132650281de06a169cbe8a0f7e5c578fd8b upstream. + +with the way fs/namei.c:do_last() had been done, ->atomic_open() +instances needed to recognize the case when existing file got +found with O_EXCL|O_CREAT, either by falling back to finish_no_open() +or failing themselves. gfs2 one didn't. + +Fixes: 6d4ade986f9c (GFS2: Add atomic_open support) +Cc: stable@kernel.org # v3.11 +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/gfs2/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1251,7 +1251,7 @@ static int gfs2_atomic_open(struct inode + if (!(file->f_mode & FMODE_OPENED)) + return finish_no_open(file, d); + dput(d); +- return 0; ++ return excl && (flags & O_CREAT) ? -EEXIST : 0; + } + + BUG_ON(d != NULL); diff --git a/queue-4.19/iommu-dma-fix-msi-reservation-allocation.patch b/queue-4.19/iommu-dma-fix-msi-reservation-allocation.patch new file mode 100644 index 00000000000..fe3abddeb2c --- /dev/null +++ b/queue-4.19/iommu-dma-fix-msi-reservation-allocation.patch @@ -0,0 +1,66 @@ +From 65ac74f1de3334852fb7d9b1b430fa5a06524276 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Wed, 4 Mar 2020 11:11:17 +0000 +Subject: iommu/dma: Fix MSI reservation allocation + +From: Marc Zyngier + +commit 65ac74f1de3334852fb7d9b1b430fa5a06524276 upstream. + +The way cookie_init_hw_msi_region() allocates the iommu_dma_msi_page +structures doesn't match the way iommu_put_dma_cookie() frees them. + +The former performs a single allocation of all the required structures, +while the latter tries to free them one at a time. It doesn't quite +work for the main use case (the GICv3 ITS where the range is 64kB) +when the base granule size is 4kB. + +This leads to a nice slab corruption on teardown, which is easily +observable by simply creating a VF on a SRIOV-capable device, and +tearing it down immediately (no need to even make use of it). +Fortunately, this only affects systems where the ITS isn't translated +by the SMMU, which are both rare and non-standard. + +Fix it by allocating iommu_dma_msi_page structures one at a time. + +Fixes: 7c1b058c8b5a3 ("iommu/dma: Handle IOMMU API reserved regions") +Signed-off-by: Marc Zyngier +Reviewed-by: Eric Auger +Cc: Robin Murphy +Cc: Joerg Roedel +Cc: Will Deacon +Cc: stable@vger.kernel.org +Reviewed-by: Robin Murphy +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/dma-iommu.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -190,15 +190,15 @@ static int cookie_init_hw_msi_region(str + start -= iova_offset(iovad, start); + num_pages = iova_align(iovad, end - start) >> iova_shift(iovad); + +- msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL); +- if (!msi_page) +- return -ENOMEM; +- + for (i = 0; i < num_pages; i++) { +- msi_page[i].phys = start; +- msi_page[i].iova = start; +- INIT_LIST_HEAD(&msi_page[i].list); +- list_add(&msi_page[i].list, &cookie->msi_page_list); ++ msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL); ++ if (!msi_page) ++ return -ENOMEM; ++ ++ msi_page->phys = start; ++ msi_page->iova = start; ++ INIT_LIST_HEAD(&msi_page->list); ++ list_add(&msi_page->list, &cookie->msi_page_list); + start += iovad->granule; + } + diff --git a/queue-4.19/iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch b/queue-4.19/iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch new file mode 100644 index 00000000000..aab27a52e1e --- /dev/null +++ b/queue-4.19/iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch @@ -0,0 +1,100 @@ +From 59833696442c674acbbd297772ba89e7ad8c753d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 9 Mar 2020 15:01:37 +0100 +Subject: iommu/vt-d: dmar: replace WARN_TAINT with pr_warn + add_taint + +From: Hans de Goede + +commit 59833696442c674acbbd297772ba89e7ad8c753d upstream. + +Quoting from the comment describing the WARN functions in +include/asm-generic/bug.h: + + * WARN(), WARN_ON(), WARN_ON_ONCE, and so on can be used to report + * significant kernel issues that need prompt attention if they should ever + * appear at runtime. + * + * Do not use these macros when checking for invalid external inputs + +The (buggy) firmware tables which the dmar code was calling WARN_TAINT +for really are invalid external inputs. They are not under the kernel's +control and the issues in them cannot be fixed by a kernel update. +So logging a backtrace, which invites bug reports to be filed about this, +is not helpful. + +Some distros, e.g. Fedora, have tools watching for the kernel backtraces +logged by the WARN macros and offer the user an option to file a bug for +this when these are encountered. The WARN_TAINT in warn_invalid_dmar() ++ another iommu WARN_TAINT, addressed in another patch, have lead to over +a 100 bugs being filed this way. + +This commit replaces the WARN_TAINT("...") calls, with +pr_warn(FW_BUG "...") + add_taint(TAINT_FIRMWARE_WORKAROUND, ...) calls +avoiding the backtrace and thus also avoiding bug-reports being filed +about this against the kernel. + +Fixes: fd0c8894893c ("intel-iommu: Set a more specific taint flag for invalid BIOS DMAR tables") +Fixes: e625b4a95d50 ("iommu/vt-d: Parse ANDD records") +Signed-off-by: Hans de Goede +Signed-off-by: Joerg Roedel +Acked-by: Lu Baolu +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200309140138.3753-2-hdegoede@redhat.com +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1564895 +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/dmar.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -451,12 +451,13 @@ static int __init dmar_parse_one_andd(st + + /* Check for NUL termination within the designated length */ + if (strnlen(andd->device_name, header->length - 8) == header->length - 8) { +- WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn(FW_BUG + "Your BIOS is broken; ANDD object name is not NUL-terminated\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + return -EINVAL; + } + pr_info("ANDD device: %x name: %s\n", andd->device_number, +@@ -482,14 +483,14 @@ static int dmar_parse_one_rhsa(struct ac + return 0; + } + } +- WARN_TAINT( +- 1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn(FW_BUG + "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + drhd->reg_base_addr, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + + return 0; + } +@@ -838,14 +839,14 @@ int __init dmar_table_init(void) + + static void warn_invalid_dmar(u64 addr, const char *message) + { +- WARN_TAINT_ONCE( +- 1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn_once(FW_BUG + "Your BIOS is broken; DMAR reported at address %llx%s!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + addr, message, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + } + + static int __ref diff --git a/queue-4.19/iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch b/queue-4.19/iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch new file mode 100644 index 00000000000..1470796a4bf --- /dev/null +++ b/queue-4.19/iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch @@ -0,0 +1,41 @@ +From 77a1bce84bba01f3f143d77127b72e872b573795 Mon Sep 17 00:00:00 2001 +From: Yonghyun Hwang +Date: Wed, 26 Feb 2020 12:30:06 -0800 +Subject: iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page + +From: Yonghyun Hwang + +commit 77a1bce84bba01f3f143d77127b72e872b573795 upstream. + +intel_iommu_iova_to_phys() has a bug when it translates an IOVA for a huge +page onto its corresponding physical address. This commit fixes the bug by +accomodating the level of page entry for the IOVA and adds IOVA's lower +address to the physical address. + +Cc: +Acked-by: Lu Baolu +Reviewed-by: Moritz Fischer +Signed-off-by: Yonghyun Hwang +Fixes: 3871794642579 ("VT-d: Changes to support KVM") +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/intel-iommu.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -5144,8 +5144,10 @@ static phys_addr_t intel_iommu_iova_to_p + u64 phys = 0; + + pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); +- if (pte) +- phys = dma_pte_addr(pte); ++ if (pte && dma_pte_present(pte)) ++ phys = dma_pte_addr(pte) + ++ (iova & (BIT_MASK(level_to_offset_bits(level) + ++ VTD_PAGE_SHIFT) - 1)); + + return phys; + } diff --git a/queue-4.19/kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch b/queue-4.19/kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch new file mode 100644 index 00000000000..f49c43223e9 --- /dev/null +++ b/queue-4.19/kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch @@ -0,0 +1,50 @@ +From 342993f96ab24d5864ab1216f46c0b199c2baf8e Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Tue, 3 Mar 2020 15:33:15 +0100 +Subject: KVM: x86: clear stale x86_emulate_ctxt->intercept value + +From: Vitaly Kuznetsov + +commit 342993f96ab24d5864ab1216f46c0b199c2baf8e upstream. + +After commit 07721feee46b ("KVM: nVMX: Don't emulate instructions in guest +mode") Hyper-V guests on KVM stopped booting with: + + kvm_nested_vmexit: rip fffff802987d6169 reason EPT_VIOLATION info1 181 + info2 0 int_info 0 int_info_err 0 + kvm_page_fault: address febd0000 error_code 181 + kvm_emulate_insn: 0:fffff802987d6169: f3 a5 + kvm_emulate_insn: 0:fffff802987d6169: f3 a5 FAIL + kvm_inj_exception: #UD (0x0) + +"f3 a5" is a "rep movsw" instruction, which should not be intercepted +at all. Commit c44b4c6ab80e ("KVM: emulate: clean up initializations in +init_decode_cache") reduced the number of fields cleared by +init_decode_cache() claiming that they are being cleared elsewhere, +'intercept', however, is left uncleared if the instruction does not have +any of the "slow path" flags (NotImpl, Stack, Op3264, Sse, Mmx, CheckPerm, +NearBranch, No16 and of course Intercept itself). + +Fixes: c44b4c6ab80e ("KVM: emulate: clean up initializations in init_decode_cache") +Fixes: 07721feee46b ("KVM: nVMX: Don't emulate instructions in guest mode") +Cc: stable@vger.kernel.org +Suggested-by: Paolo Bonzini +Signed-off-by: Vitaly Kuznetsov +Reviewed-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/emulate.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -5112,6 +5112,7 @@ int x86_decode_insn(struct x86_emulate_c + ctxt->fetch.ptr = ctxt->fetch.data; + ctxt->fetch.end = ctxt->fetch.data + insn_len; + ctxt->opcode_len = 1; ++ ctxt->intercept = x86_intercept_none; + if (insn_len > 0) + memcpy(ctxt->fetch.data, insn, insn_len); + else { diff --git a/queue-4.19/macintosh-windfarm-fix-modinfo-regression.patch b/queue-4.19/macintosh-windfarm-fix-modinfo-regression.patch new file mode 100644 index 00000000000..3de39395858 --- /dev/null +++ b/queue-4.19/macintosh-windfarm-fix-modinfo-regression.patch @@ -0,0 +1,173 @@ +From bcf3588d8ed3517e6ffaf083f034812aee9dc8e2 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Tue, 3 Mar 2020 13:50:46 +0100 +Subject: macintosh: windfarm: fix MODINFO regression + +From: Wolfram Sang + +commit bcf3588d8ed3517e6ffaf083f034812aee9dc8e2 upstream. + +Commit af503716ac14 made sure OF devices get an OF style modalias with +I2C events. It assumed all in-tree users were converted, yet it missed +some Macintosh drivers. + +Add an OF module device table for all windfarm drivers to make them +automatically load again. + +Fixes: af503716ac14 ("i2c: core: report OF style module alias for devices registered via OF") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=199471 +Reported-by: Erhard Furtner +Tested-by: Erhard Furtner +Acked-by: Michael Ellerman (powerpc) +Signed-off-by: Wolfram Sang +Cc: stable@kernel.org # v4.17+ +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/macintosh/windfarm_ad7417_sensor.c | 7 +++++++ + drivers/macintosh/windfarm_fcu_controls.c | 7 +++++++ + drivers/macintosh/windfarm_lm75_sensor.c | 16 +++++++++++++++- + drivers/macintosh/windfarm_lm87_sensor.c | 7 +++++++ + drivers/macintosh/windfarm_max6690_sensor.c | 7 +++++++ + drivers/macintosh/windfarm_smu_sat.c | 7 +++++++ + 6 files changed, 50 insertions(+), 1 deletion(-) + +--- a/drivers/macintosh/windfarm_ad7417_sensor.c ++++ b/drivers/macintosh/windfarm_ad7417_sensor.c +@@ -313,9 +313,16 @@ static const struct i2c_device_id wf_ad7 + }; + MODULE_DEVICE_TABLE(i2c, wf_ad7417_id); + ++static const struct of_device_id wf_ad7417_of_id[] = { ++ { .compatible = "ad7417", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_ad7417_of_id); ++ + static struct i2c_driver wf_ad7417_driver = { + .driver = { + .name = "wf_ad7417", ++ .of_match_table = wf_ad7417_of_id, + }, + .probe = wf_ad7417_probe, + .remove = wf_ad7417_remove, +--- a/drivers/macintosh/windfarm_fcu_controls.c ++++ b/drivers/macintosh/windfarm_fcu_controls.c +@@ -583,9 +583,16 @@ static const struct i2c_device_id wf_fcu + }; + MODULE_DEVICE_TABLE(i2c, wf_fcu_id); + ++static const struct of_device_id wf_fcu_of_id[] = { ++ { .compatible = "fcu", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_fcu_of_id); ++ + static struct i2c_driver wf_fcu_driver = { + .driver = { + .name = "wf_fcu", ++ .of_match_table = wf_fcu_of_id, + }, + .probe = wf_fcu_probe, + .remove = wf_fcu_remove, +--- a/drivers/macintosh/windfarm_lm75_sensor.c ++++ b/drivers/macintosh/windfarm_lm75_sensor.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -92,9 +93,14 @@ static int wf_lm75_probe(struct i2c_clie + const struct i2c_device_id *id) + { + struct wf_lm75_sensor *lm; +- int rc, ds1775 = id->driver_data; ++ int rc, ds1775; + const char *name, *loc; + ++ if (id) ++ ds1775 = id->driver_data; ++ else ++ ds1775 = !!of_device_get_match_data(&client->dev); ++ + DBG("wf_lm75: creating %s device at address 0x%02x\n", + ds1775 ? "ds1775" : "lm75", client->addr); + +@@ -165,9 +171,17 @@ static const struct i2c_device_id wf_lm7 + }; + MODULE_DEVICE_TABLE(i2c, wf_lm75_id); + ++static const struct of_device_id wf_lm75_of_id[] = { ++ { .compatible = "lm75", .data = (void *)0}, ++ { .compatible = "ds1775", .data = (void *)1 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_lm75_of_id); ++ + static struct i2c_driver wf_lm75_driver = { + .driver = { + .name = "wf_lm75", ++ .of_match_table = wf_lm75_of_id, + }, + .probe = wf_lm75_probe, + .remove = wf_lm75_remove, +--- a/drivers/macintosh/windfarm_lm87_sensor.c ++++ b/drivers/macintosh/windfarm_lm87_sensor.c +@@ -168,9 +168,16 @@ static const struct i2c_device_id wf_lm8 + }; + MODULE_DEVICE_TABLE(i2c, wf_lm87_id); + ++static const struct of_device_id wf_lm87_of_id[] = { ++ { .compatible = "lm87cimt", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_lm87_of_id); ++ + static struct i2c_driver wf_lm87_driver = { + .driver = { + .name = "wf_lm87", ++ .of_match_table = wf_lm87_of_id, + }, + .probe = wf_lm87_probe, + .remove = wf_lm87_remove, +--- a/drivers/macintosh/windfarm_max6690_sensor.c ++++ b/drivers/macintosh/windfarm_max6690_sensor.c +@@ -121,9 +121,16 @@ static const struct i2c_device_id wf_max + }; + MODULE_DEVICE_TABLE(i2c, wf_max6690_id); + ++static const struct of_device_id wf_max6690_of_id[] = { ++ { .compatible = "max6690", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_max6690_of_id); ++ + static struct i2c_driver wf_max6690_driver = { + .driver = { + .name = "wf_max6690", ++ .of_match_table = wf_max6690_of_id, + }, + .probe = wf_max6690_probe, + .remove = wf_max6690_remove, +--- a/drivers/macintosh/windfarm_smu_sat.c ++++ b/drivers/macintosh/windfarm_smu_sat.c +@@ -343,9 +343,16 @@ static const struct i2c_device_id wf_sat + }; + MODULE_DEVICE_TABLE(i2c, wf_sat_id); + ++static const struct of_device_id wf_sat_of_id[] = { ++ { .compatible = "smu-sat", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_sat_of_id); ++ + static struct i2c_driver wf_sat_driver = { + .driver = { + .name = "wf_smu_sat", ++ .of_match_table = wf_sat_of_id, + }, + .probe = wf_sat_probe, + .remove = wf_sat_remove, diff --git a/queue-4.19/mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch b/queue-4.19/mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch new file mode 100644 index 00000000000..efba8422a69 --- /dev/null +++ b/queue-4.19/mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch @@ -0,0 +1,42 @@ +From b102f0c522cf668c8382c56a4f771b37d011cda2 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 20 Feb 2020 12:41:39 +0100 +Subject: mt76: fix array overflow on receiving too many fragments for a packet + +From: Felix Fietkau + +commit b102f0c522cf668c8382c56a4f771b37d011cda2 upstream. + +If the hardware receives an oversized packet with too many rx fragments, +skb_shinfo(skb)->frags can overflow and corrupt memory of adjacent pages. +This becomes especially visible if it corrupts the freelist pointer of +a slab page. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mediatek/mt76/dma.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/mediatek/mt76/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/dma.c +@@ -396,10 +396,13 @@ mt76_add_fragment(struct mt76_dev *dev, + struct page *page = virt_to_head_page(data); + int offset = data - page_address(page); + struct sk_buff *skb = q->rx_head; ++ struct skb_shared_info *shinfo = skb_shinfo(skb); + +- offset += q->buf_offset; +- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, offset, len, +- q->buf_size); ++ if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) { ++ offset += q->buf_offset; ++ skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len, ++ q->buf_size); ++ } + + if (more) + return; diff --git a/queue-4.19/series b/queue-4.19/series index 0578ecc81d8..9b4f22c03ac 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -56,3 +56,14 @@ workqueue-don-t-use-wq_select_unbound_cpu-for-bound-works.patch drm-amd-display-remove-duplicated-assignment-to-grph_obj_type.patch ktest-add-timeout-for-ssh-sync-testing.patch cifs_atomic_open-fix-double-put-on-late-allocation-failure.patch +gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch +kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch +arc-define-__align_str-and-__align-symbols-for-arc.patch +macintosh-windfarm-fix-modinfo-regression.patch +efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch +efi-make-efi_rts_work-accessible-to-efi-page-fault-handler.patch +mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch +x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch +iommu-dma-fix-msi-reservation-allocation.patch +iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch +iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch diff --git a/queue-4.19/x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch b/queue-4.19/x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch new file mode 100644 index 00000000000..6f5bc821410 --- /dev/null +++ b/queue-4.19/x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch @@ -0,0 +1,66 @@ +From 59b5809655bdafb0767d3fd00a3e41711aab07e6 Mon Sep 17 00:00:00 2001 +From: Tony Luck +Date: Tue, 25 Feb 2020 17:17:37 -0800 +Subject: x86/mce: Fix logic and comments around MSR_PPIN_CTL + +From: Tony Luck + +commit 59b5809655bdafb0767d3fd00a3e41711aab07e6 upstream. + +There are two implemented bits in the PPIN_CTL MSR: + +Bit 0: LockOut (R/WO) + Set 1 to prevent further writes to MSR_PPIN_CTL. + +Bit 1: Enable_PPIN (R/W) + If 1, enables MSR_PPIN to be accessible using RDMSR. + If 0, an attempt to read MSR_PPIN will cause #GP. + +So there are four defined values: + 0: PPIN is disabled, PPIN_CTL may be updated + 1: PPIN is disabled. PPIN_CTL is locked against updates + 2: PPIN is enabled. PPIN_CTL may be updated + 3: PPIN is enabled. PPIN_CTL is locked against updates + +Code would only enable the X86_FEATURE_INTEL_PPIN feature for case "2". +When it should have done so for both case "2" and case "3". + +Fix the final test to just check for the enable bit. Also fix some of +the other comments in this function. + +Fixes: 3f5a7896a509 ("x86/mce: Include the PPIN in MCE records when available") +Signed-off-by: Tony Luck +Signed-off-by: Borislav Petkov +Cc: +Link: https://lkml.kernel.org/r/20200226011737.9958-1-tony.luck@intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/mcheck/mce_intel.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c ++++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c +@@ -489,17 +489,18 @@ static void intel_ppin_init(struct cpuin + return; + + if ((val & 3UL) == 1UL) { +- /* PPIN available but disabled: */ ++ /* PPIN locked in disabled mode */ + return; + } + +- /* If PPIN is disabled, but not locked, try to enable: */ +- if (!(val & 3UL)) { ++ /* If PPIN is disabled, try to enable */ ++ if (!(val & 2UL)) { + wrmsrl_safe(MSR_PPIN_CTL, val | 2UL); + rdmsrl_safe(MSR_PPIN_CTL, &val); + } + +- if ((val & 3UL) == 2UL) ++ /* Is the enable bit set? */ ++ if (val & 2UL) + set_cpu_cap(c, X86_FEATURE_INTEL_PPIN); + } + }