From: Greg Kroah-Hartman Date: Mon, 16 Mar 2020 13:18:38 +0000 (+0100) Subject: 5.5-stable patches X-Git-Tag: v4.19.111~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1dd23ac39bf5d7f8913a33ad645e0bab3f0e9ba4;p=thirdparty%2Fkernel%2Fstable-queue.git 5.5-stable patches added patches: arc-define-__align_str-and-__align-symbols-for-arc.patch blk-iocost-fix-incorrect-vtime-comparison-in-iocg_is_idle.patch efi-add-a-sanity-check-to-efivar_store_raw.patch efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch fscrypt-don-t-evict-dirty-inodes-after-removing-key.patch ftrace-return-the-first-found-result-in-lookup_rec.patch fuse-fix-stack-use-after-return.patch gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch i2c-designware-pci-fix-bug_on-during-device-removal.patch iommu-dma-fix-msi-reservation-allocation.patch iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch iommu-vt-d-dmar_parse_one_rmrr-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 iommu-vt-d-fix-rcu-list-debugging-warnings.patch ipmi_si-avoid-spurious-errors-for-optional-irqs.patch kvm-nvmx-avoid-null-pointer-dereference-with-incorrect-evmcs-gpas.patch kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch macintosh-windfarm-fix-modinfo-regression.patch mips-dts-ci20-fix-interrupt-for-pcf8563-rtc.patch mips-dts-ci20-fix-pmu-definitions-for-act8600.patch mips-fix-config_mips_cmdline_dtb_extend-handling.patch mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch perf-amd-uncore-replace-manual-sampling-check-with-cap_no_interrupt-flag.patch pid-fix-error-return-value-in-some-cases.patch s390-dasd-fix-data-corruption-for-thin-provisioned-devices.patch x86-ioremap-map-efi-runtime-services-data-as-encrypted-for-sev.patch x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch --- diff --git a/queue-5.5/arc-define-__align_str-and-__align-symbols-for-arc.patch b/queue-5.5/arc-define-__align_str-and-__align-symbols-for-arc.patch new file mode 100644 index 00000000000..de007b6ea65 --- /dev/null +++ b/queue-5.5/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 +@@ -29,6 +29,8 @@ + .endm + + #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-5.5/blk-iocost-fix-incorrect-vtime-comparison-in-iocg_is_idle.patch b/queue-5.5/blk-iocost-fix-incorrect-vtime-comparison-in-iocg_is_idle.patch new file mode 100644 index 00000000000..e48e597ec70 --- /dev/null +++ b/queue-5.5/blk-iocost-fix-incorrect-vtime-comparison-in-iocg_is_idle.patch @@ -0,0 +1,37 @@ +From dcd6589b11d3b1e71f516a87a7b9646ed356b4c0 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Tue, 10 Mar 2020 13:07:46 -0400 +Subject: blk-iocost: fix incorrect vtime comparison in iocg_is_idle() + +From: Tejun Heo + +commit dcd6589b11d3b1e71f516a87a7b9646ed356b4c0 upstream. + +vtimes may wrap and time_before/after64() should be used to determine +whether a given vtime is before or after another. iocg_is_idle() was +incorrectly using plain "<" comparison do determine whether done_vtime +is before vtime. Here, the only thing we're interested in is whether +done_vtime matches vtime which indicates that there's nothing in +flight. Let's test for inequality instead. + +Signed-off-by: Tejun Heo +Fixes: 7caa47151ab2 ("blkcg: implement blk-iocost") +Cc: stable@vger.kernel.org # v5.4+ +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-iocost.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/block/blk-iocost.c ++++ b/block/blk-iocost.c +@@ -1318,7 +1318,7 @@ static bool iocg_is_idle(struct ioc_gq * + return false; + + /* is something in flight? */ +- if (atomic64_read(&iocg->done_vtime) < atomic64_read(&iocg->vtime)) ++ if (atomic64_read(&iocg->done_vtime) != atomic64_read(&iocg->vtime)) + return false; + + return true; diff --git a/queue-5.5/efi-add-a-sanity-check-to-efivar_store_raw.patch b/queue-5.5/efi-add-a-sanity-check-to-efivar_store_raw.patch new file mode 100644 index 00000000000..4dab797d11e --- /dev/null +++ b/queue-5.5/efi-add-a-sanity-check-to-efivar_store_raw.patch @@ -0,0 +1,36 @@ +From d6c066fda90d578aacdf19771a027ed484a79825 Mon Sep 17 00:00:00 2001 +From: Vladis Dronov +Date: Sun, 8 Mar 2020 09:08:55 +0100 +Subject: efi: Add a sanity check to efivar_store_raw() + +From: Vladis Dronov + +commit d6c066fda90d578aacdf19771a027ed484a79825 upstream. + +Add a sanity check to efivar_store_raw() the same way +efivar_{attr,size,data}_read() and efivar_show_raw() have it. + +Signed-off-by: Vladis Dronov +Signed-off-by: Ard Biesheuvel +Signed-off-by: Ingo Molnar +Cc: +Link: https://lore.kernel.org/r/20200305084041.24053-3-vdronov@redhat.com +Link: https://lore.kernel.org/r/20200308080859.21568-25-ardb@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/efi/efivars.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/firmware/efi/efivars.c ++++ b/drivers/firmware/efi/efivars.c +@@ -208,6 +208,9 @@ efivar_store_raw(struct efivar_entry *en + u8 *data; + int err; + ++ if (!entry || !buf) ++ return -EINVAL; ++ + if (in_compat_syscall()) { + struct compat_efi_variable *compat; + diff --git a/queue-5.5/efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch b/queue-5.5/efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch new file mode 100644 index 00000000000..599f7bf1851 --- /dev/null +++ b/queue-5.5/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 +@@ -83,13 +83,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) +@@ -116,13 +119,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); +@@ -133,12 +139,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); +@@ -250,14 +259,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 (in_compat_syscall()) { diff --git a/queue-5.5/fscrypt-don-t-evict-dirty-inodes-after-removing-key.patch b/queue-5.5/fscrypt-don-t-evict-dirty-inodes-after-removing-key.patch new file mode 100644 index 00000000000..a8ba4f008cf --- /dev/null +++ b/queue-5.5/fscrypt-don-t-evict-dirty-inodes-after-removing-key.patch @@ -0,0 +1,56 @@ +From 2b4eae95c7361e0a147b838715c8baa1380a428f Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 5 Mar 2020 00:41:38 -0800 +Subject: fscrypt: don't evict dirty inodes after removing key + +From: Eric Biggers + +commit 2b4eae95c7361e0a147b838715c8baa1380a428f upstream. + +After FS_IOC_REMOVE_ENCRYPTION_KEY removes a key, it syncs the +filesystem and tries to get and put all inodes that were unlocked by the +key so that unused inodes get evicted via fscrypt_drop_inode(). +Normally, the inodes are all clean due to the sync. + +However, after the filesystem is sync'ed, userspace can modify and close +one of the files. (Userspace is *supposed* to close the files before +removing the key. But it doesn't always happen, and the kernel can't +assume it.) This causes the inode to be dirtied and have i_count == 0. +Then, fscrypt_drop_inode() failed to consider this case and indicated +that the inode can be dropped, causing the write to be lost. + +On f2fs, other problems such as a filesystem freeze could occur due to +the inode being freed while still on f2fs's dirty inode list. + +Fix this bug by making fscrypt_drop_inode() only drop clean inodes. + +I've written an xfstest which detects this bug on ext4, f2fs, and ubifs. + +Fixes: b1c0ec3599f4 ("fscrypt: add FS_IOC_REMOVE_ENCRYPTION_KEY ioctl") +Cc: # v5.4+ +Link: https://lore.kernel.org/r/20200305084138.653498-1-ebiggers@kernel.org +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/crypto/keysetup.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/fs/crypto/keysetup.c ++++ b/fs/crypto/keysetup.c +@@ -515,6 +515,15 @@ int fscrypt_drop_inode(struct inode *ino + mk = ci->ci_master_key->payload.data[0]; + + /* ++ * With proper, non-racy use of FS_IOC_REMOVE_ENCRYPTION_KEY, all inodes ++ * protected by the key were cleaned by sync_filesystem(). But if ++ * userspace is still using the files, inodes can be dirtied between ++ * then and now. We mustn't lose any writes, so skip dirty inodes here. ++ */ ++ if (inode->i_state & I_DIRTY_ALL) ++ return 0; ++ ++ /* + * Note: since we aren't holding ->mk_secret_sem, the result here can + * immediately become outdated. But there's no correctness problem with + * unnecessarily evicting. Nor is there a correctness problem with not diff --git a/queue-5.5/ftrace-return-the-first-found-result-in-lookup_rec.patch b/queue-5.5/ftrace-return-the-first-found-result-in-lookup_rec.patch new file mode 100644 index 00000000000..5533ed6eb02 --- /dev/null +++ b/queue-5.5/ftrace-return-the-first-found-result-in-lookup_rec.patch @@ -0,0 +1,46 @@ +From d9815bff6b379ff46981bea9dfeb146081eab314 Mon Sep 17 00:00:00 2001 +From: Artem Savkov +Date: Fri, 6 Mar 2020 18:43:17 +0100 +Subject: ftrace: Return the first found result in lookup_rec() + +From: Artem Savkov + +commit d9815bff6b379ff46981bea9dfeb146081eab314 upstream. + +It appears that ip ranges can overlap so. In that case lookup_rec() +returns whatever results it got last even if it found nothing in last +searched page. + +This breaks an obscure livepatch late module patching usecase: + - load livepatch + - load the patched module + - unload livepatch + - try to load livepatch again + +To fix this return from lookup_rec() as soon as it found the record +containing searched-for ip. This used to be this way prior lookup_rec() +introduction. + +Link: http://lkml.kernel.org/r/20200306174317.21699-1-asavkov@redhat.com + +Cc: stable@vger.kernel.org +Fixes: 7e16f581a817 ("ftrace: Separate out functionality from ftrace_location_range()") +Signed-off-by: Artem Savkov +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ftrace.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -1552,6 +1552,8 @@ static struct dyn_ftrace *lookup_rec(uns + rec = bsearch(&key, pg->records, pg->index, + sizeof(struct dyn_ftrace), + ftrace_cmp_recs); ++ if (rec) ++ break; + } + return rec; + } diff --git a/queue-5.5/fuse-fix-stack-use-after-return.patch b/queue-5.5/fuse-fix-stack-use-after-return.patch new file mode 100644 index 00000000000..61f92757cc3 --- /dev/null +++ b/queue-5.5/fuse-fix-stack-use-after-return.patch @@ -0,0 +1,81 @@ +From 3e8cb8b2eaeb22f540f1cbc00cbb594047b7ba89 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Thu, 13 Feb 2020 09:16:07 +0100 +Subject: fuse: fix stack use after return + +From: Miklos Szeredi + +commit 3e8cb8b2eaeb22f540f1cbc00cbb594047b7ba89 upstream. + +Normal, synchronous requests will have their args allocated on the stack. +After the FR_FINISHED bit is set by receiving the reply from the userspace +fuse server, the originating task may return and reuse the stack frame, +resulting in an Oops if the args structure is dereferenced. + +Fix by setting a flag in the request itself upon initializing, indicating +whether it has an asynchronous ->end() callback. + +Reported-by: Kyle Sanderson +Reported-by: Michael Stapelberg +Fixes: 2b319d1f6f92 ("fuse: don't dereference req->args on finished request") +Cc: # v5.4 +Tested-by: Michael Stapelberg +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dev.c | 6 +++--- + fs/fuse/fuse_i.h | 2 ++ + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- a/fs/fuse/dev.c ++++ b/fs/fuse/dev.c +@@ -276,12 +276,10 @@ static void flush_bg_queue(struct fuse_c + void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) + { + struct fuse_iqueue *fiq = &fc->iq; +- bool async; + + if (test_and_set_bit(FR_FINISHED, &req->flags)) + goto put_request; + +- async = req->args->end; + /* + * test_and_set_bit() implies smp_mb() between bit + * changing and below intr_entry check. Pairs with +@@ -324,7 +322,7 @@ void fuse_request_end(struct fuse_conn * + wake_up(&req->waitq); + } + +- if (async) ++ if (test_bit(FR_ASYNC, &req->flags)) + req->args->end(fc, req->args, req->out.h.error); + put_request: + fuse_put_request(fc, req); +@@ -471,6 +469,8 @@ static void fuse_args_to_req(struct fuse + req->in.h.opcode = args->opcode; + req->in.h.nodeid = args->nodeid; + req->args = args; ++ if (args->end) ++ __set_bit(FR_ASYNC, &req->flags); + } + + ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) +--- a/fs/fuse/fuse_i.h ++++ b/fs/fuse/fuse_i.h +@@ -301,6 +301,7 @@ struct fuse_io_priv { + * FR_SENT: request is in userspace, waiting for an answer + * FR_FINISHED: request is finished + * FR_PRIVATE: request is on private list ++ * FR_ASYNC: request is asynchronous + */ + enum fuse_req_flag { + FR_ISREPLY, +@@ -314,6 +315,7 @@ enum fuse_req_flag { + FR_SENT, + FR_FINISHED, + FR_PRIVATE, ++ FR_ASYNC, + }; + + /** diff --git a/queue-5.5/gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch b/queue-5.5/gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch new file mode 100644 index 00000000000..909cbb6c887 --- /dev/null +++ b/queue-5.5/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 +@@ -1248,7 +1248,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-5.5/i2c-designware-pci-fix-bug_on-during-device-removal.patch b/queue-5.5/i2c-designware-pci-fix-bug_on-during-device-removal.patch new file mode 100644 index 00000000000..b8a4ad65a4d --- /dev/null +++ b/queue-5.5/i2c-designware-pci-fix-bug_on-during-device-removal.patch @@ -0,0 +1,39 @@ +From 9be8bc4dd6177cf992b93b0bd014c4f611283896 Mon Sep 17 00:00:00 2001 +From: Jarkko Nikula +Date: Thu, 13 Feb 2020 17:15:03 +0200 +Subject: i2c: designware-pci: Fix BUG_ON during device removal + +From: Jarkko Nikula + +commit 9be8bc4dd6177cf992b93b0bd014c4f611283896 upstream. + +Function i2c_dw_pci_remove() -> pci_free_irq_vectors() -> +pci_disable_msi() -> free_msi_irqs() will throw a BUG_ON() for MSI +enabled device since the driver has not released the requested IRQ before +calling the pci_free_irq_vectors(). + +Here driver requests an IRQ using devm_request_irq() but automatic +release happens only after remove callback. Fix this by explicitly +freeing the IRQ before calling pci_free_irq_vectors(). + +Fixes: 21aa3983d619 ("i2c: designware-pci: Switch over to MSI interrupts") +Cc: stable@vger.kernel.org # v5.4+ +Signed-off-by: Jarkko Nikula +Reviewed-by: Andy Shevchenko +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-designware-pcidrv.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/i2c/busses/i2c-designware-pcidrv.c ++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c +@@ -313,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci + pm_runtime_get_noresume(&pdev->dev); + + i2c_del_adapter(&dev->adapter); ++ devm_free_irq(&pdev->dev, dev->irq, dev); + pci_free_irq_vectors(pdev); + } + diff --git a/queue-5.5/iommu-dma-fix-msi-reservation-allocation.patch b/queue-5.5/iommu-dma-fix-msi-reservation-allocation.patch new file mode 100644 index 00000000000..0d9b2b5d6e8 --- /dev/null +++ b/queue-5.5/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 +@@ -177,15 +177,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-5.5/iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch b/queue-5.5/iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch new file mode 100644 index 00000000000..72020d8b560 --- /dev/null +++ b/queue-5.5/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 +@@ -440,12 +440,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, +@@ -471,14 +472,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; + } +@@ -827,14 +828,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-5.5/iommu-vt-d-dmar_parse_one_rmrr-replace-warn_taint-with-pr_warn-add_taint.patch b/queue-5.5/iommu-vt-d-dmar_parse_one_rmrr-replace-warn_taint-with-pr_warn-add_taint.patch new file mode 100644 index 00000000000..a28737dc284 --- /dev/null +++ b/queue-5.5/iommu-vt-d-dmar_parse_one_rmrr-replace-warn_taint-with-pr_warn-add_taint.patch @@ -0,0 +1,70 @@ +From 96788c7a7f1e7206519d4d736f89a2072dcfe0fc Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 9 Mar 2020 15:01:38 +0100 +Subject: iommu/vt-d: dmar_parse_one_rmrr: replace WARN_TAINT with pr_warn + add_taint + +From: Hans de Goede + +commit 96788c7a7f1e7206519d4d736f89a2072dcfe0fc 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 dmar_parse_one_rmrr ++ 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("...") call, with a +pr_warn(FW_BUG "...") + add_taint(TAINT_FIRMWARE_WORKAROUND, ...) call +avoiding the backtrace and thus also avoiding bug-reports being filed +about this against the kernel. + +Fixes: f5a68bb0752e ("iommu/vt-d: Mark firmware tainted if RMRR fails sanity check") +Signed-off-by: Hans de Goede +Signed-off-by: Joerg Roedel +Acked-by: Lu Baolu +Cc: stable@vger.kernel.org +Cc: Barret Rhoden +Link: https://lore.kernel.org/r/20200309140138.3753-3-hdegoede@redhat.com +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1808874 +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 +@@ -4330,14 +4330,16 @@ int __init dmar_parse_one_rmrr(struct ac + struct dmar_rmrr_unit *rmrru; + + rmrr = (struct acpi_dmar_reserved_memory *)header; +- if (arch_rmrr_sanity_check(rmrr)) +- WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, ++ if (arch_rmrr_sanity_check(rmrr)) { ++ pr_warn(FW_BUG + "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + rmrr->base_address, rmrr->end_address, + 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); ++ } + + rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL); + if (!rmrru) diff --git a/queue-5.5/iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch b/queue-5.5/iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch new file mode 100644 index 00000000000..876fa21c2ef --- /dev/null +++ b/queue-5.5/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 +@@ -5568,8 +5568,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-5.5/iommu-vt-d-fix-rcu-list-debugging-warnings.patch b/queue-5.5/iommu-vt-d-fix-rcu-list-debugging-warnings.patch new file mode 100644 index 00000000000..c93903883d6 --- /dev/null +++ b/queue-5.5/iommu-vt-d-fix-rcu-list-debugging-warnings.patch @@ -0,0 +1,61 @@ +From 02d715b4a8182f4887d82df82a7b83aced647760 Mon Sep 17 00:00:00 2001 +From: Amol Grover +Date: Sun, 23 Feb 2020 22:25:39 +0530 +Subject: iommu/vt-d: Fix RCU list debugging warnings + +From: Amol Grover + +commit 02d715b4a8182f4887d82df82a7b83aced647760 upstream. + +dmar_drhd_units is traversed using list_for_each_entry_rcu() +outside of an RCU read side critical section but under the +protection of dmar_global_lock. Hence add corresponding lockdep +expression to silence the following false-positive warnings: + +[ 1.603975] ============================= +[ 1.603976] WARNING: suspicious RCU usage +[ 1.603977] 5.5.4-stable #17 Not tainted +[ 1.603978] ----------------------------- +[ 1.603980] drivers/iommu/intel-iommu.c:4769 RCU-list traversed in non-reader section!! + +[ 1.603869] ============================= +[ 1.603870] WARNING: suspicious RCU usage +[ 1.603872] 5.5.4-stable #17 Not tainted +[ 1.603874] ----------------------------- +[ 1.603875] drivers/iommu/dmar.c:293 RCU-list traversed in non-reader section!! + +Tested-by: Madhuparna Bhowmik +Signed-off-by: Amol Grover +Cc: stable@vger.kernel.org +Acked-by: Lu Baolu +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/dmar.h | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/include/linux/dmar.h ++++ b/include/linux/dmar.h +@@ -69,8 +69,9 @@ struct dmar_pci_notify_info { + extern struct rw_semaphore dmar_global_lock; + extern struct list_head dmar_drhd_units; + +-#define for_each_drhd_unit(drhd) \ +- list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) ++#define for_each_drhd_unit(drhd) \ ++ list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ ++ dmar_rcu_check()) + + #define for_each_active_drhd_unit(drhd) \ + list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ +@@ -81,7 +82,8 @@ extern struct list_head dmar_drhd_units; + if (i=drhd->iommu, drhd->ignored) {} else + + #define for_each_iommu(i, drhd) \ +- list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ ++ list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ ++ dmar_rcu_check()) \ + if (i=drhd->iommu, 0) {} else + + static inline bool dmar_rcu_check(void) diff --git a/queue-5.5/ipmi_si-avoid-spurious-errors-for-optional-irqs.patch b/queue-5.5/ipmi_si-avoid-spurious-errors-for-optional-irqs.patch new file mode 100644 index 00000000000..367df24b435 --- /dev/null +++ b/queue-5.5/ipmi_si-avoid-spurious-errors-for-optional-irqs.patch @@ -0,0 +1,48 @@ +From 443d372d6a96cd94ad119e5c14bb4d63a536a7f6 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 5 Feb 2020 10:31:46 +0100 +Subject: ipmi_si: Avoid spurious errors for optional IRQs + +From: Takashi Iwai + +commit 443d372d6a96cd94ad119e5c14bb4d63a536a7f6 upstream. + +Although the IRQ assignment in ipmi_si driver is optional, +platform_get_irq() spews error messages unnecessarily: + ipmi_si dmi-ipmi-si.0: IRQ index 0 not found + +Fix this by switching to platform_get_irq_optional(). + +Cc: stable@vger.kernel.org # 5.4.x +Cc: John Donnelly +Fixes: 7723f4c5ecdb ("driver core: platform: Add an error message to platform_get_irq*()") +Reported-and-tested-by: Patrick Vo +Signed-off-by: Takashi Iwai +Message-Id: <20200205093146.1352-1-tiwai@suse.de> +Signed-off-by: Corey Minyard +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_si_platform.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/char/ipmi/ipmi_si_platform.c ++++ b/drivers/char/ipmi/ipmi_si_platform.c +@@ -194,7 +194,7 @@ static int platform_ipmi_probe(struct pl + else + io.slave_addr = slave_addr; + +- io.irq = platform_get_irq(pdev, 0); ++ io.irq = platform_get_irq_optional(pdev, 0); + if (io.irq > 0) + io.irq_setup = ipmi_std_irq_setup; + else +@@ -378,7 +378,7 @@ static int acpi_ipmi_probe(struct platfo + io.irq = tmp; + io.irq_setup = acpi_gpe_irq_setup; + } else { +- int irq = platform_get_irq(pdev, 0); ++ int irq = platform_get_irq_optional(pdev, 0); + + if (irq > 0) { + io.irq = irq; diff --git a/queue-5.5/kvm-nvmx-avoid-null-pointer-dereference-with-incorrect-evmcs-gpas.patch b/queue-5.5/kvm-nvmx-avoid-null-pointer-dereference-with-incorrect-evmcs-gpas.patch new file mode 100644 index 00000000000..e2ffe1e7876 --- /dev/null +++ b/queue-5.5/kvm-nvmx-avoid-null-pointer-dereference-with-incorrect-evmcs-gpas.patch @@ -0,0 +1,62 @@ +From 95fa10103dabc38be5de8efdfced5e67576ed896 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Mon, 9 Mar 2020 16:52:11 +0100 +Subject: KVM: nVMX: avoid NULL pointer dereference with incorrect EVMCS GPAs + +From: Vitaly Kuznetsov + +commit 95fa10103dabc38be5de8efdfced5e67576ed896 upstream. + +When an EVMCS enabled L1 guest on KVM will tries doing enlightened VMEnter +with EVMCS GPA = 0 the host crashes because the + +evmcs_gpa != vmx->nested.hv_evmcs_vmptr + +condition in nested_vmx_handle_enlightened_vmptrld() will evaluate to +false (as nested.hv_evmcs_vmptr is zeroed after init). The crash will +happen on vmx->nested.hv_evmcs pointer dereference. + +Another problematic EVMCS ptr value is '-1' but it only causes host crash +after nested_release_evmcs() invocation. The problem is exactly the same as +with '0', we mistakenly think that the EVMCS pointer hasn't changed and +thus nested.hv_evmcs_vmptr is valid. + +Resolve the issue by adding an additional !vmx->nested.hv_evmcs +check to nested_vmx_handle_enlightened_vmptrld(), this way we will +always be trying kvm_vcpu_map() when nested.hv_evmcs is NULL +and this is supposed to catch all invalid EVMCS GPAs. + +Also, initialize hv_evmcs_vmptr to '0' in nested_release_evmcs() +to be consistent with initialization where we don't currently +set hv_evmcs_vmptr to '-1'. + +Cc: stable@vger.kernel.org +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/vmx/nested.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -234,7 +234,7 @@ static inline void nested_release_evmcs( + return; + + kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true); +- vmx->nested.hv_evmcs_vmptr = -1ull; ++ vmx->nested.hv_evmcs_vmptr = 0; + vmx->nested.hv_evmcs = NULL; + } + +@@ -1932,7 +1932,8 @@ static int nested_vmx_handle_enlightened + if (!nested_enlightened_vmentry(vcpu, &evmcs_gpa)) + return 1; + +- if (unlikely(evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) { ++ if (unlikely(!vmx->nested.hv_evmcs || ++ evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) { + if (!vmx->nested.hv_evmcs) + vmx->nested.current_vmptr = -1ull; + diff --git a/queue-5.5/kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch b/queue-5.5/kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch new file mode 100644 index 00000000000..1d65bdd3d1e --- /dev/null +++ b/queue-5.5/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 +@@ -5195,6 +5195,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-5.5/macintosh-windfarm-fix-modinfo-regression.patch b/queue-5.5/macintosh-windfarm-fix-modinfo-regression.patch new file mode 100644 index 00000000000..1589b2effe0 --- /dev/null +++ b/queue-5.5/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 +@@ -312,9 +312,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 +@@ -580,9 +580,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 +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -91,9 +92,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); + +@@ -164,9 +170,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 +@@ -166,9 +166,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 +@@ -120,9 +120,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 +@@ -341,9 +341,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-5.5/mips-dts-ci20-fix-interrupt-for-pcf8563-rtc.patch b/queue-5.5/mips-dts-ci20-fix-interrupt-for-pcf8563-rtc.patch new file mode 100644 index 00000000000..85c176d39b8 --- /dev/null +++ b/queue-5.5/mips-dts-ci20-fix-interrupt-for-pcf8563-rtc.patch @@ -0,0 +1,44 @@ +From 130ab8819d81bd96f1a71e8461a8f73edf1fbe82 Mon Sep 17 00:00:00 2001 +From: "H. Nikolaus Schaller" +Date: Fri, 6 Mar 2020 18:28:30 +0100 +Subject: MIPS: DTS: CI20: fix interrupt for pcf8563 RTC + +From: H. Nikolaus Schaller + +commit 130ab8819d81bd96f1a71e8461a8f73edf1fbe82 upstream. + +Interrupts should not be specified by interrupt line but by +gpio parent and reference. + +Fixes: 73f2b940474d ("MIPS: CI20: DTS: Add I2C nodes") +Cc: stable@vger.kernel.org +Signed-off-by: H. Nikolaus Schaller +Reviewed-by: Paul Cercueil +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/boot/dts/ingenic/ci20.dts | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/mips/boot/dts/ingenic/ci20.dts ++++ b/arch/mips/boot/dts/ingenic/ci20.dts +@@ -4,6 +4,7 @@ + #include "jz4780.dtsi" + #include + #include ++#include + #include + + / { +@@ -270,7 +271,9 @@ + rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; +- interrupts = <110>; ++ ++ interrupt-parent = <&gpf>; ++ interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + }; + }; + diff --git a/queue-5.5/mips-dts-ci20-fix-pmu-definitions-for-act8600.patch b/queue-5.5/mips-dts-ci20-fix-pmu-definitions-for-act8600.patch new file mode 100644 index 00000000000..b2dca53d772 --- /dev/null +++ b/queue-5.5/mips-dts-ci20-fix-pmu-definitions-for-act8600.patch @@ -0,0 +1,124 @@ +From e8d87a0b822d4b3d9a94a5da915f93aa1b674c93 Mon Sep 17 00:00:00 2001 +From: "H. Nikolaus Schaller" +Date: Fri, 6 Mar 2020 18:27:58 +0100 +Subject: MIPS: DTS: CI20: fix PMU definitions for ACT8600 + +From: H. Nikolaus Schaller + +commit e8d87a0b822d4b3d9a94a5da915f93aa1b674c93 upstream. + +There is a ACT8600 on the CI20 board and the bindings of the +ACT8865 driver have changed without updating the CI20 device +tree. Therefore the PMU can not be probed successfully and +is running in power-on reset state. + +Fix DT to match the latest act8865-regulator bindings. + +Fixes: 73f2b940474d ("MIPS: CI20: DTS: Add I2C nodes") +Cc: stable@vger.kernel.org +Signed-off-by: H. Nikolaus Schaller +Reviewed-by: Paul Cercueil +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/boot/dts/ingenic/ci20.dts | 39 ++++++++++++++++++++++-------------- + 1 file changed, 24 insertions(+), 15 deletions(-) + +--- a/arch/mips/boot/dts/ingenic/ci20.dts ++++ b/arch/mips/boot/dts/ingenic/ci20.dts +@@ -4,6 +4,7 @@ + #include "jz4780.dtsi" + #include + #include ++#include + + / { + compatible = "img,ci20", "ingenic,jz4780"; +@@ -163,63 +164,71 @@ + + regulators { + vddcore: SUDCDC1 { +- regulator-name = "VDDCORE"; ++ regulator-name = "DCDC_REG1"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + vddmem: SUDCDC2 { +- regulator-name = "VDDMEM"; ++ regulator-name = "DCDC_REG2"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + vcc_33: SUDCDC3 { +- regulator-name = "VCC33"; ++ regulator-name = "DCDC_REG3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + vcc_50: SUDCDC4 { +- regulator-name = "VCC50"; ++ regulator-name = "SUDCDC_REG4"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + vcc_25: LDO_REG5 { +- regulator-name = "VCC25"; ++ regulator-name = "LDO_REG5"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + wifi_io: LDO_REG6 { +- regulator-name = "WIFIIO"; ++ regulator-name = "LDO_REG6"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + vcc_28: LDO_REG7 { +- regulator-name = "VCC28"; ++ regulator-name = "LDO_REG7"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + vcc_15: LDO_REG8 { +- regulator-name = "VCC15"; ++ regulator-name = "LDO_REG8"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; +- vcc_18: LDO_REG9 { +- regulator-name = "VCC18"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; ++ vrtc_18: LDO_REG9 { ++ regulator-name = "LDO_REG9"; ++ /* Despite the datasheet stating 3.3V ++ * for REG9 and the driver expecting that, ++ * REG9 outputs 1.8V. ++ * Likely the CI20 uses a proprietary ++ * factory programmed chip variant. ++ * Since this is a simple on/off LDO the ++ * exact values do not matter. ++ */ ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + vcc_11: LDO_REG10 { +- regulator-name = "VCC11"; +- regulator-min-microvolt = <1100000>; +- regulator-max-microvolt = <1100000>; ++ regulator-name = "LDO_REG10"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + }; diff --git a/queue-5.5/mips-fix-config_mips_cmdline_dtb_extend-handling.patch b/queue-5.5/mips-fix-config_mips_cmdline_dtb_extend-handling.patch new file mode 100644 index 00000000000..919e15c8301 --- /dev/null +++ b/queue-5.5/mips-fix-config_mips_cmdline_dtb_extend-handling.patch @@ -0,0 +1,38 @@ +From 8e029eb0bcd6a7fab6dc9191152c085784c31ee6 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Tue, 25 Feb 2020 12:28:09 -0300 +Subject: MIPS: Fix CONFIG_MIPS_CMDLINE_DTB_EXTEND handling + +From: Paul Cercueil + +commit 8e029eb0bcd6a7fab6dc9191152c085784c31ee6 upstream. + +The CONFIG_MIPS_CMDLINE_DTB_EXTEND option is used so that the kernel +arguments provided in the 'bootargs' property in devicetree are extended +with the kernel arguments provided by the bootloader. + +The code was broken, as it didn't actually take any of the kernel +arguments provided in devicetree when that option was set. + +Fixes: 7784cac69735 ("MIPS: cmdline: Clean up boot_command_line initialization") +Cc: stable@vger.kernel.org +Signed-off-by: Paul Cercueil +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/setup.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -606,7 +606,8 @@ static void __init bootcmdline_init(char + * If we're configured to take boot arguments from DT, look for those + * now. + */ +- if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)) ++ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) || ++ IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)) + of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs); + #endif + diff --git a/queue-5.5/mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch b/queue-5.5/mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch new file mode 100644 index 00000000000..e08612a4dac --- /dev/null +++ b/queue-5.5/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 +@@ -447,10 +447,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-5.5/perf-amd-uncore-replace-manual-sampling-check-with-cap_no_interrupt-flag.patch b/queue-5.5/perf-amd-uncore-replace-manual-sampling-check-with-cap_no_interrupt-flag.patch new file mode 100644 index 00000000000..0948f8f8cc1 --- /dev/null +++ b/queue-5.5/perf-amd-uncore-replace-manual-sampling-check-with-cap_no_interrupt-flag.patch @@ -0,0 +1,80 @@ +From f967140dfb7442e2db0868b03b961f9c59418a1b Mon Sep 17 00:00:00 2001 +From: Kim Phillips +Date: Wed, 11 Mar 2020 14:13:21 -0500 +Subject: perf/amd/uncore: Replace manual sampling check with CAP_NO_INTERRUPT flag + +From: Kim Phillips + +commit f967140dfb7442e2db0868b03b961f9c59418a1b upstream. + +Enable the sampling check in kernel/events/core.c::perf_event_open(), +which returns the more appropriate -EOPNOTSUPP. + +BEFORE: + + $ sudo perf record -a -e instructions,l3_request_g1.caching_l3_cache_accesses true + Error: + The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (l3_request_g1.caching_l3_cache_accesses). + /bin/dmesg | grep -i perf may provide additional information. + +With nothing relevant in dmesg. + +AFTER: + + $ sudo perf record -a -e instructions,l3_request_g1.caching_l3_cache_accesses true + Error: + l3_request_g1.caching_l3_cache_accesses: PMU Hardware doesn't support sampling/overflow-interrupts. Try 'perf stat' + +Fixes: c43ca5091a37 ("perf/x86/amd: Add support for AMD NB and L2I "uncore" counters") +Signed-off-by: Kim Phillips +Signed-off-by: Borislav Petkov +Acked-by: Peter Zijlstra +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20200311191323.13124-1-kim.phillips@amd.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/events/amd/uncore.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +--- a/arch/x86/events/amd/uncore.c ++++ b/arch/x86/events/amd/uncore.c +@@ -190,15 +190,12 @@ static int amd_uncore_event_init(struct + + /* + * NB and Last level cache counters (MSRs) are shared across all cores +- * that share the same NB / Last level cache. Interrupts can be directed +- * to a single target core, however, event counts generated by processes +- * running on other cores cannot be masked out. So we do not support +- * sampling and per-thread events. ++ * that share the same NB / Last level cache. On family 16h and below, ++ * Interrupts can be directed to a single target core, however, event ++ * counts generated by processes running on other cores cannot be masked ++ * out. So we do not support sampling and per-thread events via ++ * CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts: + */ +- if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) +- return -EINVAL; +- +- /* and we do not enable counter overflow interrupts */ + hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; + hwc->idx = -1; + +@@ -306,7 +303,7 @@ static struct pmu amd_nb_pmu = { + .start = amd_uncore_start, + .stop = amd_uncore_stop, + .read = amd_uncore_read, +- .capabilities = PERF_PMU_CAP_NO_EXCLUDE, ++ .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, + }; + + static struct pmu amd_llc_pmu = { +@@ -317,7 +314,7 @@ static struct pmu amd_llc_pmu = { + .start = amd_uncore_start, + .stop = amd_uncore_stop, + .read = amd_uncore_read, +- .capabilities = PERF_PMU_CAP_NO_EXCLUDE, ++ .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, + }; + + static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) diff --git a/queue-5.5/pid-fix-error-return-value-in-some-cases.patch b/queue-5.5/pid-fix-error-return-value-in-some-cases.patch new file mode 100644 index 00000000000..c2d33eb6900 --- /dev/null +++ b/queue-5.5/pid-fix-error-return-value-in-some-cases.patch @@ -0,0 +1,47 @@ +From b26ebfe12f34f372cf041c6f801fa49c3fb382c5 Mon Sep 17 00:00:00 2001 +From: Corey Minyard +Date: Fri, 6 Mar 2020 11:23:14 -0600 +Subject: pid: Fix error return value in some cases + +From: Corey Minyard + +commit b26ebfe12f34f372cf041c6f801fa49c3fb382c5 upstream. + +Recent changes to alloc_pid() allow the pid number to be specified on +the command line. If set_tid_size is set, then the code scanning the +levels will hard-set retval to -EPERM, overriding it's previous -ENOMEM +value. + +After the code scanning the levels, there are error returns that do not +set retval, assuming it is still set to -ENOMEM. + +So set retval back to -ENOMEM after scanning the levels. + +Fixes: 49cb2fc42ce4 ("fork: extend clone3() to support setting a PID") +Signed-off-by: Corey Minyard +Acked-by: Christian Brauner +Cc: Andrei Vagin +Cc: Dmitry Safonov <0x7f454c46@gmail.com> +Cc: Oleg Nesterov +Cc: Adrian Reber +Cc: # 5.5 +Link: https://lore.kernel.org/r/20200306172314.12232-1-minyard@acm.org +[christian.brauner@ubuntu.com: fixup commit message] +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/pid.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/pid.c ++++ b/kernel/pid.c +@@ -247,6 +247,8 @@ struct pid *alloc_pid(struct pid_namespa + tmp = tmp->parent; + } + ++ retval = -ENOMEM; ++ + if (unlikely(is_child_reaper(pid))) { + if (pid_ns_prepare_proc(ns)) + goto out_free; diff --git a/queue-5.5/s390-dasd-fix-data-corruption-for-thin-provisioned-devices.patch b/queue-5.5/s390-dasd-fix-data-corruption-for-thin-provisioned-devices.patch new file mode 100644 index 00000000000..52ad16e1fd4 --- /dev/null +++ b/queue-5.5/s390-dasd-fix-data-corruption-for-thin-provisioned-devices.patch @@ -0,0 +1,421 @@ +From 5e6bdd37c5526ef01326df5dabb93011ee89237e Mon Sep 17 00:00:00 2001 +From: Stefan Haberland +Date: Thu, 12 Mar 2020 14:17:15 +0100 +Subject: s390/dasd: fix data corruption for thin provisioned devices + +From: Stefan Haberland + +commit 5e6bdd37c5526ef01326df5dabb93011ee89237e upstream. + +Devices are formatted in multiple of tracks. +For an Extent Space Efficient (ESE) volume we get errors when accessing +unformatted tracks. In this case the driver either formats the track on +the flight for write requests or returns zero data for read requests. + +In case a request spans multiple tracks, the indication of an unformatted +track presented for the first track is incorrectly applied to all tracks +covered by the request. As a result, tracks containing data will be handled +as empty, resulting in zero data being returned on read, or overwriting +existing data with zero on write. + +Fix by determining the track that gets the NRF error. +For write requests only format the track that is surely not formatted. +For Read requests all tracks before have returned valid data and should not +be touched. +All tracks after the unformatted track might be formatted or not. Those are +returned to the blocklayer to build a new request. + +When using alias devices there is a chance that multiple write requests +trigger a format of the same track which might lead to data loss. Ensure +that a track is formatted only once by maintaining a list of currently +processed tracks. + +Fixes: 5e2b17e712cf ("s390/dasd: Add dynamic formatting support for ESE volumes") +Cc: stable@vger.kernel.org # 5.3+ +Signed-off-by: Stefan Haberland +Reviewed-by: Jan Hoeppner +Reviewed-by: Peter Oberparleiter +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/s390/block/dasd.c | 27 ++++++ + drivers/s390/block/dasd_eckd.c | 163 +++++++++++++++++++++++++++++++++++++++-- + drivers/s390/block/dasd_int.h | 15 +++ + 3 files changed, 193 insertions(+), 12 deletions(-) + +--- a/drivers/s390/block/dasd.c ++++ b/drivers/s390/block/dasd.c +@@ -178,6 +178,8 @@ struct dasd_block *dasd_alloc_block(void + (unsigned long) block); + INIT_LIST_HEAD(&block->ccw_queue); + spin_lock_init(&block->queue_lock); ++ INIT_LIST_HEAD(&block->format_list); ++ spin_lock_init(&block->format_lock); + timer_setup(&block->timer, dasd_block_timeout, 0); + spin_lock_init(&block->profile.lock); + +@@ -1779,20 +1781,26 @@ void dasd_int_handler(struct ccw_device + + if (dasd_ese_needs_format(cqr->block, irb)) { + if (rq_data_dir((struct request *)cqr->callback_data) == READ) { +- device->discipline->ese_read(cqr); ++ device->discipline->ese_read(cqr, irb); + cqr->status = DASD_CQR_SUCCESS; + cqr->stopclk = now; + dasd_device_clear_timer(device); + dasd_schedule_device_bh(device); + return; + } +- fcqr = device->discipline->ese_format(device, cqr); ++ fcqr = device->discipline->ese_format(device, cqr, irb); + if (IS_ERR(fcqr)) { ++ if (PTR_ERR(fcqr) == -EINVAL) { ++ cqr->status = DASD_CQR_ERROR; ++ return; ++ } + /* + * If we can't format now, let the request go + * one extra round. Maybe we can format later. + */ + cqr->status = DASD_CQR_QUEUED; ++ dasd_schedule_device_bh(device); ++ return; + } else { + fcqr->status = DASD_CQR_QUEUED; + cqr->status = DASD_CQR_QUEUED; +@@ -2748,11 +2756,13 @@ static void __dasd_cleanup_cqr(struct da + { + struct request *req; + blk_status_t error = BLK_STS_OK; ++ unsigned int proc_bytes; + int status; + + req = (struct request *) cqr->callback_data; + dasd_profile_end(cqr->block, cqr, req); + ++ proc_bytes = cqr->proc_bytes; + status = cqr->block->base->discipline->free_cp(cqr, req); + if (status < 0) + error = errno_to_blk_status(status); +@@ -2783,7 +2793,18 @@ static void __dasd_cleanup_cqr(struct da + blk_mq_end_request(req, error); + blk_mq_run_hw_queues(req->q, true); + } else { +- blk_mq_complete_request(req); ++ /* ++ * Partial completed requests can happen with ESE devices. ++ * During read we might have gotten a NRF error and have to ++ * complete a request partially. ++ */ ++ if (proc_bytes) { ++ blk_update_request(req, BLK_STS_OK, ++ blk_rq_bytes(req) - proc_bytes); ++ blk_mq_requeue_request(req, true); ++ } else { ++ blk_mq_complete_request(req); ++ } + } + } + +--- a/drivers/s390/block/dasd_eckd.c ++++ b/drivers/s390/block/dasd_eckd.c +@@ -207,6 +207,45 @@ static void set_ch_t(struct ch_t *geo, _ + geo->head |= head; + } + ++/* ++ * calculate failing track from sense data depending if ++ * it is an EAV device or not ++ */ ++static int dasd_eckd_track_from_irb(struct irb *irb, struct dasd_device *device, ++ sector_t *track) ++{ ++ struct dasd_eckd_private *private = device->private; ++ u8 *sense = NULL; ++ u32 cyl; ++ u8 head; ++ ++ sense = dasd_get_sense(irb); ++ if (!sense) { ++ DBF_DEV_EVENT(DBF_WARNING, device, "%s", ++ "ESE error no sense data\n"); ++ return -EINVAL; ++ } ++ if (!(sense[27] & DASD_SENSE_BIT_2)) { ++ DBF_DEV_EVENT(DBF_WARNING, device, "%s", ++ "ESE error no valid track data\n"); ++ return -EINVAL; ++ } ++ ++ if (sense[27] & DASD_SENSE_BIT_3) { ++ /* enhanced addressing */ ++ cyl = sense[30] << 20; ++ cyl |= (sense[31] & 0xF0) << 12; ++ cyl |= sense[28] << 8; ++ cyl |= sense[29]; ++ } else { ++ cyl = sense[29] << 8; ++ cyl |= sense[30]; ++ } ++ head = sense[31] & 0x0F; ++ *track = cyl * private->rdc_data.trk_per_cyl + head; ++ return 0; ++} ++ + static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data, + struct dasd_device *device) + { +@@ -2986,6 +3025,37 @@ static int dasd_eckd_format_device(struc + 0, NULL); + } + ++static bool test_and_set_format_track(struct dasd_format_entry *to_format, ++ struct dasd_block *block) ++{ ++ struct dasd_format_entry *format; ++ unsigned long flags; ++ bool rc = false; ++ ++ spin_lock_irqsave(&block->format_lock, flags); ++ list_for_each_entry(format, &block->format_list, list) { ++ if (format->track == to_format->track) { ++ rc = true; ++ goto out; ++ } ++ } ++ list_add_tail(&to_format->list, &block->format_list); ++ ++out: ++ spin_unlock_irqrestore(&block->format_lock, flags); ++ return rc; ++} ++ ++static void clear_format_track(struct dasd_format_entry *format, ++ struct dasd_block *block) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&block->format_lock, flags); ++ list_del_init(&format->list); ++ spin_unlock_irqrestore(&block->format_lock, flags); ++} ++ + /* + * Callback function to free ESE format requests. + */ +@@ -2993,15 +3063,19 @@ static void dasd_eckd_ese_format_cb(stru + { + struct dasd_device *device = cqr->startdev; + struct dasd_eckd_private *private = device->private; ++ struct dasd_format_entry *format = data; + ++ clear_format_track(format, cqr->basedev->block); + private->count--; + dasd_ffree_request(cqr, device); + } + + static struct dasd_ccw_req * +-dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) ++dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr, ++ struct irb *irb) + { + struct dasd_eckd_private *private; ++ struct dasd_format_entry *format; + struct format_data_t fdata; + unsigned int recs_per_trk; + struct dasd_ccw_req *fcqr; +@@ -3011,23 +3085,39 @@ dasd_eckd_ese_format(struct dasd_device + struct request *req; + sector_t first_trk; + sector_t last_trk; ++ sector_t curr_trk; + int rc; + + req = cqr->callback_data; +- base = cqr->block->base; ++ block = cqr->block; ++ base = block->base; + private = base->private; +- block = base->block; + blksize = block->bp_block; + recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); ++ format = &startdev->format_entry; + + first_trk = blk_rq_pos(req) >> block->s2b_shift; + sector_div(first_trk, recs_per_trk); + last_trk = + (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; + sector_div(last_trk, recs_per_trk); ++ rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); ++ if (rc) ++ return ERR_PTR(rc); ++ ++ if (curr_trk < first_trk || curr_trk > last_trk) { ++ DBF_DEV_EVENT(DBF_WARNING, startdev, ++ "ESE error track %llu not within range %llu - %llu\n", ++ curr_trk, first_trk, last_trk); ++ return ERR_PTR(-EINVAL); ++ } ++ format->track = curr_trk; ++ /* test if track is already in formatting by another thread */ ++ if (test_and_set_format_track(format, block)) ++ return ERR_PTR(-EEXIST); + +- fdata.start_unit = first_trk; +- fdata.stop_unit = last_trk; ++ fdata.start_unit = curr_trk; ++ fdata.stop_unit = curr_trk; + fdata.blksize = blksize; + fdata.intensity = private->uses_cdl ? DASD_FMT_INT_COMPAT : 0; + +@@ -3044,6 +3134,7 @@ dasd_eckd_ese_format(struct dasd_device + return fcqr; + + fcqr->callback = dasd_eckd_ese_format_cb; ++ fcqr->callback_data = (void *) format; + + return fcqr; + } +@@ -3051,29 +3142,87 @@ dasd_eckd_ese_format(struct dasd_device + /* + * When data is read from an unformatted area of an ESE volume, this function + * returns zeroed data and thereby mimics a read of zero data. ++ * ++ * The first unformatted track is the one that got the NRF error, the address is ++ * encoded in the sense data. ++ * ++ * All tracks before have returned valid data and should not be touched. ++ * All tracks after the unformatted track might be formatted or not. This is ++ * currently not known, remember the processed data and return the remainder of ++ * the request to the blocklayer in __dasd_cleanup_cqr(). + */ +-static void dasd_eckd_ese_read(struct dasd_ccw_req *cqr) ++static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb) + { ++ struct dasd_eckd_private *private; ++ sector_t first_trk, last_trk; ++ sector_t first_blk, last_blk; + unsigned int blksize, off; ++ unsigned int recs_per_trk; + struct dasd_device *base; + struct req_iterator iter; ++ struct dasd_block *block; ++ unsigned int skip_block; ++ unsigned int blk_count; + struct request *req; + struct bio_vec bv; ++ sector_t curr_trk; ++ sector_t end_blk; + char *dst; ++ int rc; + + req = (struct request *) cqr->callback_data; + base = cqr->block->base; + blksize = base->block->bp_block; ++ block = cqr->block; ++ private = base->private; ++ skip_block = 0; ++ blk_count = 0; ++ ++ recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); ++ first_trk = first_blk = blk_rq_pos(req) >> block->s2b_shift; ++ sector_div(first_trk, recs_per_trk); ++ last_trk = last_blk = ++ (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; ++ sector_div(last_trk, recs_per_trk); ++ rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); ++ if (rc) ++ return rc; ++ ++ /* sanity check if the current track from sense data is valid */ ++ if (curr_trk < first_trk || curr_trk > last_trk) { ++ DBF_DEV_EVENT(DBF_WARNING, base, ++ "ESE error track %llu not within range %llu - %llu\n", ++ curr_trk, first_trk, last_trk); ++ return -EINVAL; ++ } ++ ++ /* ++ * if not the first track got the NRF error we have to skip over valid ++ * blocks ++ */ ++ if (curr_trk != first_trk) ++ skip_block = curr_trk * recs_per_trk - first_blk; ++ ++ /* we have no information beyond the current track */ ++ end_blk = (curr_trk + 1) * recs_per_trk; + + rq_for_each_segment(bv, req, iter) { + dst = page_address(bv.bv_page) + bv.bv_offset; + for (off = 0; off < bv.bv_len; off += blksize) { +- if (dst && rq_data_dir(req) == READ) { ++ if (first_blk + blk_count >= end_blk) { ++ cqr->proc_bytes = blk_count * blksize; ++ return 0; ++ } ++ if (dst && !skip_block) { + dst += off; + memset(dst, 0, blksize); ++ } else { ++ skip_block--; + } ++ blk_count++; + } + } ++ return 0; + } + + /* +--- a/drivers/s390/block/dasd_int.h ++++ b/drivers/s390/block/dasd_int.h +@@ -187,6 +187,7 @@ struct dasd_ccw_req { + + void (*callback)(struct dasd_ccw_req *, void *data); + void *callback_data; ++ unsigned int proc_bytes; /* bytes for partial completion */ + }; + + /* +@@ -387,8 +388,9 @@ struct dasd_discipline { + int (*ext_pool_warn_thrshld)(struct dasd_device *); + int (*ext_pool_oos)(struct dasd_device *); + int (*ext_pool_exhaust)(struct dasd_device *, struct dasd_ccw_req *); +- struct dasd_ccw_req *(*ese_format)(struct dasd_device *, struct dasd_ccw_req *); +- void (*ese_read)(struct dasd_ccw_req *); ++ struct dasd_ccw_req *(*ese_format)(struct dasd_device *, ++ struct dasd_ccw_req *, struct irb *); ++ int (*ese_read)(struct dasd_ccw_req *, struct irb *); + }; + + extern struct dasd_discipline *dasd_diag_discipline_pointer; +@@ -474,6 +476,11 @@ struct dasd_profile { + spinlock_t lock; + }; + ++struct dasd_format_entry { ++ struct list_head list; ++ sector_t track; ++}; ++ + struct dasd_device { + /* Block device stuff. */ + struct dasd_block *block; +@@ -539,6 +546,7 @@ struct dasd_device { + struct dentry *debugfs_dentry; + struct dentry *hosts_dentry; + struct dasd_profile profile; ++ struct dasd_format_entry format_entry; + }; + + struct dasd_block { +@@ -564,6 +572,9 @@ struct dasd_block { + + struct dentry *debugfs_dentry; + struct dasd_profile profile; ++ ++ struct list_head format_list; ++ spinlock_t format_lock; + }; + + struct dasd_attention_data { diff --git a/queue-5.5/series b/queue-5.5/series index cc95dbed01f..202e2a4eaa8 100644 --- a/queue-5.5/series +++ b/queue-5.5/series @@ -94,3 +94,30 @@ pinctrl-qcom-assign-irq_eoi-conditionally.patch ktest-add-timeout-for-ssh-sync-testing.patch block-fix-partition-support-for-host-aware-zoned-block-devices.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 +kvm-nvmx-avoid-null-pointer-dereference-with-incorrect-evmcs-gpas.patch +arc-define-__align_str-and-__align-symbols-for-arc.patch +fuse-fix-stack-use-after-return.patch +mips-dts-ci20-fix-pmu-definitions-for-act8600.patch +mips-dts-ci20-fix-interrupt-for-pcf8563-rtc.patch +mips-fix-config_mips_cmdline_dtb_extend-handling.patch +s390-dasd-fix-data-corruption-for-thin-provisioned-devices.patch +ipmi_si-avoid-spurious-errors-for-optional-irqs.patch +ftrace-return-the-first-found-result-in-lookup_rec.patch +blk-iocost-fix-incorrect-vtime-comparison-in-iocg_is_idle.patch +fscrypt-don-t-evict-dirty-inodes-after-removing-key.patch +pid-fix-error-return-value-in-some-cases.patch +macintosh-windfarm-fix-modinfo-regression.patch +x86-ioremap-map-efi-runtime-services-data-as-encrypted-for-sev.patch +efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch +efi-add-a-sanity-check-to-efivar_store_raw.patch +i2c-designware-pci-fix-bug_on-during-device-removal.patch +mt76-fix-array-overflow-on-receiving-too-many-fragments-for-a-packet.patch +perf-amd-uncore-replace-manual-sampling-check-with-cap_no_interrupt-flag.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-dmar_parse_one_rmrr-replace-warn_taint-with-pr_warn-add_taint.patch +iommu-vt-d-fix-rcu-list-debugging-warnings.patch +iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch diff --git a/queue-5.5/x86-ioremap-map-efi-runtime-services-data-as-encrypted-for-sev.patch b/queue-5.5/x86-ioremap-map-efi-runtime-services-data-as-encrypted-for-sev.patch new file mode 100644 index 00000000000..36c9d3254b3 --- /dev/null +++ b/queue-5.5/x86-ioremap-map-efi-runtime-services-data-as-encrypted-for-sev.patch @@ -0,0 +1,80 @@ +From 985e537a4082b4635754a57f4f95430790afee6a Mon Sep 17 00:00:00 2001 +From: Tom Lendacky +Date: Tue, 10 Mar 2020 18:35:57 +0100 +Subject: x86/ioremap: Map EFI runtime services data as encrypted for SEV + +From: Tom Lendacky + +commit 985e537a4082b4635754a57f4f95430790afee6a upstream. + +The dmidecode program fails to properly decode the SMBIOS data supplied +by OVMF/UEFI when running in an SEV guest. The SMBIOS area, under SEV, is +encrypted and resides in reserved memory that is marked as EFI runtime +services data. + +As a result, when memremap() is attempted for the SMBIOS data, it +can't be mapped as regular RAM (through try_ram_remap()) and, since +the address isn't part of the iomem resources list, it isn't mapped +encrypted through the fallback ioremap(). + +Add a new __ioremap_check_other() to deal with memory types like +EFI_RUNTIME_SERVICES_DATA which are not covered by the resource ranges. + +This allows any runtime services data which has been created encrypted, +to be mapped encrypted too. + + [ bp: Move functionality to a separate function. ] + +Signed-off-by: Tom Lendacky +Signed-off-by: Borislav Petkov +Reviewed-by: Joerg Roedel +Tested-by: Joerg Roedel +Cc: # 5.3 +Link: https://lkml.kernel.org/r/2d9e16eb5b53dc82665c95c6764b7407719df7a0.1582645327.git.thomas.lendacky@amd.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/mm/ioremap.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/arch/x86/mm/ioremap.c ++++ b/arch/x86/mm/ioremap.c +@@ -106,6 +106,19 @@ static unsigned int __ioremap_check_encr + return 0; + } + ++/* ++ * The EFI runtime services data area is not covered by walk_mem_res(), but must ++ * be mapped encrypted when SEV is active. ++ */ ++static void __ioremap_check_other(resource_size_t addr, struct ioremap_desc *desc) ++{ ++ if (!sev_active()) ++ return; ++ ++ if (efi_mem_type(addr) == EFI_RUNTIME_SERVICES_DATA) ++ desc->flags |= IORES_MAP_ENCRYPTED; ++} ++ + static int __ioremap_collect_map_flags(struct resource *res, void *arg) + { + struct ioremap_desc *desc = arg; +@@ -124,6 +137,9 @@ static int __ioremap_collect_map_flags(s + * To avoid multiple resource walks, this function walks resources marked as + * IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a + * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES). ++ * ++ * After that, deal with misc other ranges in __ioremap_check_other() which do ++ * not fall into the above category. + */ + static void __ioremap_check_mem(resource_size_t addr, unsigned long size, + struct ioremap_desc *desc) +@@ -135,6 +151,8 @@ static void __ioremap_check_mem(resource + memset(desc, 0, sizeof(struct ioremap_desc)); + + walk_mem_res(start, end, desc, __ioremap_collect_map_flags); ++ ++ __ioremap_check_other(addr, desc); + } + + /* diff --git a/queue-5.5/x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch b/queue-5.5/x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch new file mode 100644 index 00000000000..2d0a132fb72 --- /dev/null +++ b/queue-5.5/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/mce/intel.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/cpu/mce/intel.c ++++ b/arch/x86/kernel/cpu/mce/intel.c +@@ -492,17 +492,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); + } + }