From: Greg Kroah-Hartman Date: Mon, 16 Mar 2020 13:17:27 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.19.111~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=18246be03b96f2cb0167a44fe7438bd93288b071;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-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 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 x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch --- diff --git a/queue-4.14/arc-define-__align_str-and-__align-symbols-for-arc.patch b/queue-4.14/arc-define-__align_str-and-__align-symbols-for-arc.patch new file mode 100644 index 00000000000..17e39085553 --- /dev/null +++ b/queue-4.14/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.14/efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.patch b/queue-4.14/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.14/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.14/gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch b/queue-4.14/gfs2_atomic_open-fix-o_excl-o_creat-handling-on-cold-dcache.patch new file mode 100644 index 00000000000..b117be3b38c --- /dev/null +++ b/queue-4.14/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 +@@ -1255,7 +1255,7 @@ static int gfs2_atomic_open(struct inode + if (!(*opened & FILE_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.14/iommu-dma-fix-msi-reservation-allocation.patch b/queue-4.14/iommu-dma-fix-msi-reservation-allocation.patch new file mode 100644 index 00000000000..7213ff994f0 --- /dev/null +++ b/queue-4.14/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 +@@ -208,15 +208,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.14/iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch b/queue-4.14/iommu-vt-d-dmar-replace-warn_taint-with-pr_warn-add_taint.patch new file mode 100644 index 00000000000..7dcfc122769 --- /dev/null +++ b/queue-4.14/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; + } +@@ -835,14 +836,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.14/iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch b/queue-4.14/iommu-vt-d-fix-a-bug-in-intel_iommu_iova_to_phys-for-huge-page.patch new file mode 100644 index 00000000000..7365f48096d --- /dev/null +++ b/queue-4.14/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 +@@ -5124,8 +5124,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.14/kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch b/queue-4.14/kvm-x86-clear-stale-x86_emulate_ctxt-intercept-value.patch new file mode 100644 index 00000000000..d977020ca3b --- /dev/null +++ b/queue-4.14/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 +@@ -5062,6 +5062,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.14/series b/queue-4.14/series index 947f71854a3..ed93d4286e1 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -43,3 +43,11 @@ 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 +efi-fix-a-race-and-a-buffer-overflow-while-reading-efivars-via-sysfs.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.14/x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch b/queue-4.14/x86-mce-fix-logic-and-comments-around-msr_ppin_ctl.patch new file mode 100644 index 00000000000..6f5bc821410 --- /dev/null +++ b/queue-4.14/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); + } + }