4.9.202-stable review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 4.9.202-stable review
This is the start of the stable review cycle for the 4.9.202 release. There are 31 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 17 Nov 2019 06:18:35 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.202-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.9.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.9.202-rc1
Gomez Iglesias, Antonio <[email protected]>
Documentation: Add ITLB_MULTIHIT documentation
Junaid Shahid <[email protected]>
kvm: x86: mmu: Recovery of shattered NX large pages
Junaid Shahid <[email protected]>
kvm: Add helper function for creating VM worker threads
Paolo Bonzini <[email protected]>
kvm: mmu: ITLB_MULTIHIT mitigation
Tyler Hicks <[email protected]>
cpu/speculation: Uninline and export CPU mitigations helpers
Vineela Tummalapalli <[email protected]>
x86/bugs: Add ITLB_MULTIHIT bug infrastructure
Paolo Bonzini <[email protected]>
KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is active
Paolo Bonzini <[email protected]>
KVM: x86: add tracepoints around __direct_map and FNAME(fetch)
Ben Hutchings <[email protected]>
KVM: x86: Add is_executable_pte()
Paolo Bonzini <[email protected]>
KVM: x86: change kvm_mmu_page_get_gfn BUG_ON to WARN_ON
Paolo Bonzini <[email protected]>
KVM: x86: remove now unneeded hugepage gfn adjustment
Paolo Bonzini <[email protected]>
KVM: x86: make FNAME(fetch) and __direct_map more similar
Junaid Shahid <[email protected]>
kvm: x86: Do not release the page inside mmu_set_spte()
Junaid Shahid <[email protected]>
kvm: Convert kvm_lock to a mutex
Paolo Bonzini <[email protected]>
KVM: x86: extend usage of RET_MMIO_PF_* constants
Paolo Bonzini <[email protected]>
KVM: x86: simplify ept_misconfig
Josh Poimboeuf <[email protected]>
x86/speculation/taa: Fix printing of TAA_MSG_SMT on IBRS_ALL CPUs
Michal Hocko <[email protected]>
x86/tsx: Add config options to set tsx=on|off|auto
Pawan Gupta <[email protected]>
x86/speculation/taa: Add documentation for TSX Async Abort
Pawan Gupta <[email protected]>
x86/tsx: Add "auto" option to the tsx= cmdline parameter
Pawan Gupta <[email protected]>
kvm/x86: Export MDS_NO=0 to guests when TSX is enabled
Pawan Gupta <[email protected]>
x86/speculation/taa: Add sysfs reporting for TSX Async Abort
Pawan Gupta <[email protected]>
x86/speculation/taa: Add mitigation for TSX Async Abort
Pawan Gupta <[email protected]>
x86/cpu: Add a "tsx=" cmdline option with TSX disabled by default
Pawan Gupta <[email protected]>
x86/cpu: Add a helper function x86_read_arch_cap_msr()
Pawan Gupta <[email protected]>
x86/msr: Add the IA32_TSX_CTRL MSR
Paolo Bonzini <[email protected]>
KVM: x86: use Intel speculation bugs and features as derived in generic x86 code
Jack Pham <[email protected]>
usb: gadget: core: unmap request from DMA only if previously mapped
Jonas Gorski <[email protected]>
MIPS: BCM63XX: fix switch core reset on BCM6368
Kefeng Wang <[email protected]>
Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto()
Junaid Shahid <[email protected]>
kvm: mmu: Don't read PDPTEs when paging is not enabled
-------------
Diffstat:
Documentation/ABI/testing/sysfs-devices-system-cpu | 2 + Documentation/hw-vuln/index.rst | 2 + Documentation/hw-vuln/multihit.rst | 163 ++++++++ Documentation/hw-vuln/tsx_async_abort.rst | 276 +++++++++++++ Documentation/kernel-parameters.txt | 92 +++++ Documentation/virtual/kvm/locking.txt | 6 +- Documentation/x86/index.rst | 1 + Documentation/x86/tsx_async_abort.rst | 117 ++++++ Makefile | 4 +- arch/mips/bcm63xx/reset.c | 2 +- arch/s390/kvm/kvm-s390.c | 4 +- arch/x86/Kconfig | 45 ++ arch/x86/include/asm/cpufeatures.h | 2 + arch/x86/include/asm/kvm_host.h | 6 + arch/x86/include/asm/msr-index.h | 16 + arch/x86/include/asm/nospec-branch.h | 4 +- arch/x86/include/asm/processor.h | 7 + arch/x86/kernel/cpu/Makefile | 2 +- arch/x86/kernel/cpu/bugs.c | 161 +++++++- arch/x86/kernel/cpu/common.c | 93 +++-- arch/x86/kernel/cpu/cpu.h | 18 + arch/x86/kernel/cpu/intel.c | 5 + arch/x86/kernel/cpu/tsx.c | 140 +++++++ arch/x86/kvm/cpuid.c | 8 + arch/x86/kvm/mmu.c | 452 +++++++++++++++++---- arch/x86/kvm/mmu.h | 21 +- arch/x86/kvm/mmutrace.h | 59 +++ arch/x86/kvm/paging_tmpl.h | 79 ++-- arch/x86/kvm/svm.c | 10 +- arch/x86/kvm/vmx.c | 27 +- arch/x86/kvm/x86.c | 61 ++- drivers/base/cpu.c | 17 + drivers/bluetooth/hci_ldisc.c | 3 +- drivers/usb/gadget/udc/core.c | 5 +- include/linux/cpu.h | 30 +- include/linux/kvm_host.h | 8 +- include/linux/usb/gadget.h | 2 + kernel/cpu.c | 27 +- virt/kvm/kvm_main.c | 132 +++++- 39 files changed, 1855 insertions(+), 254 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/31 kvm: mmu: Dont read PDPTEs when paging is not enabled
From: Junaid Shahid <[email protected]>
[ Upstream commit d35b34a9a70edae7ef923f100e51b8b5ae9fe899 ]
kvm should not attempt to read guest PDPTEs when CR0.PG = 0 and CR4.PAE = 1.
--- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/x86.c +2 -2
@@ -587,7 +587,7 @@ static bool pdptrs_changed(struct kvm_vcgfn_t gfn;int r; -if (is_long_mode (vcpu) || !is_pae (vcpu)) +if (is_long_mode (vcpu) || !is_pae (vcpu) || !is_paging (vcpu))return false; if (!test_bit(VCPU_EXREG_PDPTR,
@@ -7491,7 +7491,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(structkvm_update_cpuid (vcpu); idx =srcu_read_lock (&vcpu->kvm->srcu); -if (!is_long_mode (vcpu) &&is_pae (vcpu)) { +if (!is_long_mode (vcpu) &&is_pae (vcpu) &&is_paging (vcpu)) {load_pdptrs (vcpu, vcpu->arch.walk_mmu,kvm_read_cr3 (vcpu)); mmu_reset_needed =1 ; }
Greg Kroah-Hartman
maintainerPATCH 2/31 Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto()
In reply to Greg Kroah-HartmanFrom: Kefeng Wang <[email protected]>
commit 56897b217a1d0a91c9920cb418d6b3fe922f590a upstream.
task A: task B: hci_uart_set_proto flush_to_ldisc - p->open(hu) -> h5_open //alloc h5 - receive_buf
- set_bit HCI_UART_PROTO_READY - tty_port_default_receive_buf
- hci_uart_register_dev - tty_ldisc_receive_buf
- hci_uart_tty_receive
- test_bit HCI_UART_PROTO_READY
- h5_recv
- clear_bit HCI_UART_PROTO_READY while() {
- p->open(hu) -> h5_close //free h5
- h5_rx_3wire_hdr
- h5_reset() //use-after-free
}
It could use ioctl to set hci uart proto, but there is a use-after-free issue when hci_uart_register_dev() fail in hci_uart_set_proto(), see stack above, fix this by setting HCI_UART_PROTO_READY bit only when hci_uart_register_dev() return success.
--- drivers/bluetooth/hci_ldisc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/bluetooth/hci_ldisc.c +1 -2
@@ -653,15 +653,14 @@ static int hci_uart_set_proto(struct hcireturn err; hu->proto = p; -set_bit (HCI_UART_PROTO_READY , &hu->flags); err =hci_uart_register_dev (hu);if (err) { -clear_bit (HCI_UART_PROTO_READY , &hu->flags); p->close (hu);return err; } +set_bit (HCI_UART_PROTO_READY , &hu->flags);return 0 ; }
Re: [PATCH 4.9 02/31] Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto()
Hi Greg,
Quoted 24 lines · Greg Kroah-Hartman
From: Kefeng Wang <[email protected]>
commit
56897b217a1d0a91c9920cb418d6b3fe922f590aupstream.task A: task B:
hci_uart_set_protoflush_to_ldisc
-p->open(hu)->h5_open//alloc h5 -receive_buf
-set_bitHCI_UART_PROTO_READY-tty_port_default_receive_buf
-hci_uart_register_dev-tty_ldisc_receive_buf
-hci_uart_tty_receive
-test_bitHCI_UART_PROTO_READY
-h5_recv
-clear_bitHCI_UART_PROTO_READYwhile(){
-p->open(hu)->h5_close//free h5
-h5_rx_3wire_hdr
-h5_reset()//use-after-free
}It could use ioctl to set hci uart proto, but there is a use-after-free issue when
hci_uart_register_dev()fail inhci_uart_set_proto(), see stack above, fix this by settingHCI_UART_PROTO_READYbit only whenhci_uart_register_dev()return success.
Quoted 5 lines
Reported-by [email protected]Signed-off-by Kefeng Wang <[email protected]>Reviewed-by Jeremy Cline <[email protected]>Signed-off-by Marcel Holtmann <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
I was just about to ask why this had not been merged into 4.9. Spent a while searching archives for any discussion to explain its absence, but couldn't find anything. Also watched your kernel-recipes talk...
BTW, this also seems to be missing from 4.4 branch, although it was merged for 3.16 (per https://lore.kernel.org/stable/?q=Postpone+HCI).
I gather that the usual rule is that a fix must be in newer versions before it can go into older ones. Or at least, some patches were rejected on that basis. If this is in fact the policy, perhaps it could be added to stable-kernel-rules.rst ?
-Ralph
Quoted 25 lines
---
drivers/bluetooth/hci_ldisc.c| 3 +--1 file changed, 1 insertion(+), 2 deletions(-)drivers/bluetooth/hci_ldisc.c +1
-2@@ -653,15 +653,14 @@ static int hci_uart_set_proto(struct hcireturn err; hu->proto = p; -set_bit (HCI_UART_PROTO_READY , &hu->flags); err =hci_uart_register_dev (hu);if (err) { -clear_bit (HCI_UART_PROTO_READY , &hu->flags); p->close (hu);return err; } +set_bit (HCI_UART_PROTO_READY , &hu->flags);return 0 ; }
Greg Kroah-Hartman
maintainerRe: [PATCH 4.9 02/31] Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto()
Quoted 33 lines · Ralph Siemsen
Hi Greg,
Quoted 24 lines · Greg Kroah-Hartman
From: Kefeng Wang <[email protected]>
commit
56897b217a1d0a91c9920cb418d6b3fe922f590aupstream.task A: task B:
hci_uart_set_protoflush_to_ldisc
-p->open(hu)->h5_open//alloc h5 -receive_buf
-set_bitHCI_UART_PROTO_READY-tty_port_default_receive_buf
-hci_uart_register_dev-tty_ldisc_receive_buf
-hci_uart_tty_receive
-test_bitHCI_UART_PROTO_READY
-h5_recv
-clear_bitHCI_UART_PROTO_READYwhile(){
-p->open(hu)->h5_close//free h5
-h5_rx_3wire_hdr
-h5_reset()//use-after-free
}It could use ioctl to set hci uart proto, but there is a use-after-free issue when
hci_uart_register_dev()fail inhci_uart_set_proto(), see stack above, fix this by settingHCI_UART_PROTO_READYbit only whenhci_uart_register_dev()return success.Quoted 5 lines
Reported-by [email protected]Signed-off-by Kefeng Wang <[email protected]>Reviewed-by Jeremy Cline <[email protected]>Signed-off-by Marcel Holtmann <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
Quoted 6 lines
I was just about to ask why this had not been merged into 4.9. Spent a while searching archives for any discussion to explain its absence, but couldn't find anything. Also watched your kernel-recipes talk...
BTW, this also seems to be missing from 4.4 branch, although it was merged for 3.16 (per https://lore.kernel.org/stable/?q=Postpone+HCI).
Odd that it was merged into 3.16, perhaps it was done there because some earlier patch added the problem? I say this as I do not think this is relevant for the 4.4.y kernel, do you? Have you tried to apply this patch there?
Quoted 4 lines
I gather that the usual rule is that a fix must be in newer versions before it can go into older ones. Or at least, some patches were rejected on that basis. If this is in fact the policy, perhaps it could be added to
stable-kernel-rules.rst?
No, that's not why this was rejected. I don't know why it didn't end up in 4.9.y earlier, but for 4.4.y, it was not added there as I do not think it actually is relevant (see above.)
thanks,
greg k-h
Re: [PATCH 4.9 02/31] Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto()
Quoted 6 lines · Greg Kroah-Hartman
Quoted 3 lines
BTW, this also seems to be missing from 4.4 branch, although it was merged for 3.16 (per https://lore.kernel.org/stable/?q=Postpone+HCI).
Odd that it was merged into 3.16, perhaps it was done there because some earlier patch added the problem?
This patch should really be viewed as a correction to an earlier commit:84cb3df02aea ("Bluetooth: hci_ldisc: Fix null pointer derefence in case of early data"). This was merged 2016-Apr-08 into v4.7, and therefore is included in 4.9 and higher.
Only very recently, on 2019-Sep-23, this was backported to 3.16, along with the correction. Both appeared in v3.16.74.
Quoted 3 lines
I say this as I do not think this is
relevant for the 4.4.y kernel, do you? Have you tried to apply this patch there?
The patch does not apply, but this is mainly due to the earlier commit missing. It seems to me like that earlier fix is desirable (and it was put into 3.16), along with the followup. So I would think we want it in 4.4 as well.
[Aside: I'm really only interested in 4.9 and 4.19, so the 4.4 stuff is just a diversion. But figured I might as well mention what I found...]
Regards,
-Ralph
Re: [PATCH 4.9 02/31] Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto()
Quoted 8 lines · Ralph Siemsen
Quoted 6 lines · Greg Kroah-Hartman
Quoted 3 lines
BTW, this also seems to be missing from 4.4 branch, although it was merged for 3.16 (per https://lore.kernel.org/stable/?q=Postpone+HCI).
Odd that it was merged into 3.16, perhaps it was done there because some earlier patch added the problem?
Quoted 7 lines
This patch should really be viewed as a correction to an earlier commit:
84cb3df02aea("Bluetooth:hci_ldisc: Fix null pointer derefence in case of early data"). This was merged 2016-Apr-08 into v4.7, and therefore is included in 4.9 and higher.Only very recently, on 2019-Sep-23, this was backported to 3.16, along with the correction. Both appeared in v3.16.74.
Ok, that makes more sense now. The "fix" didn't apply as it was not a fix for an old issue, but rather a new one.
Quoted 8 lines
Quoted 3 lines
I say this as I do not think this is
relevant for the 4.4.y kernel, do you? Have you tried to apply this patch there?The patch does not apply, but this is mainly due to the earlier commit missing. It seems to me like that earlier fix is desirable (and it was put into 3.16), along with the followup. So I would think we want it in 4.4 as well.
I've queued them both up now, thanks.
Quoted 2 lines
[Aside: I'm really only interested in 4.9 and 4.19, so the 4.4 stuff is just a diversion. But figured I might as well mention what I found...]
Other people at your company care about 4.4.y :)
thanks,
greg k-h
Greg Kroah-Hartman
maintainerPATCH 3/31 MIPS: BCM63XX: fix switch core reset on BCM6368
In reply to Greg Kroah-HartmanFrom: Jonas Gorski <[email protected]>
commit 8a38dacf87180738d42b058334c951eba15d2d47 upstream.
The Ethernet Switch core mask was set to 0, causing the switch core to be not reset on BCM6368 on boot. Provide the proper mask so the switch core gets reset to a known good state.
--- arch/mips/bcm63xx/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/bcm63xx/reset.c +1 -1
@@ -119,7 +119,7 @@#define BCM6368_RESET_DSL 0#define BCM6368_RESET_SAR SOFTRESET_6368_SAR_MASK#define BCM6368_RESET_EPHY SOFTRESET_6368_EPHY_MASK -#define BCM6368_RESET_ENETSW 0 +#define BCM6368_RESET_ENETSW SOFTRESET_6368_ENETSW_MASK#define BCM6368_RESET_PCM SOFTRESET_6368_PCM_MASK#define BCM6368_RESET_MPI SOFTRESET_6368_MPI_MASK#define BCM6368_RESET_PCIE 0
Greg Kroah-Hartman
maintainerPATCH 4/31 usb: gadget: core: unmap request from DMA only if previously mapped
In reply to Greg Kroah-HartmanFrom: Jack Pham <[email protected]>
commit 31fe084ffaaf8abece14f8ca28e5e3b4e2bf97b6 upstream.
In the SG case this is already handled since a non-zero request->num_mapped_sgs is a clear indicator that dma_map_sg() had been called. While it would be nice to do the same for the singly mapped case by simply checking for non-zero request->dma, it's conceivable that 0 is a valid dma_addr_t handle. Hence add a flag 'dma_mapped' to struct usb_request and use this to determine the need to call dma_unmap_single(). Otherwise, if a request is not DMA mapped then the result of calling usb_request_unmap_request() would safely be a no-op.
--- drivers/usb/gadget/udc/core.c | 5 ++++- include/linux/usb/gadget.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-)
drivers/usb/gadget/udc/core.c +4 -1
@@ -817,6 +817,8 @@ int usb_gadget_map_request_by_dev(structdev_err (dev,"failed to map buffer\n" );return -EFAULT ; } + + req->dma_mapped =1 ; }return 0 ;
@@ -841,9 +843,10 @@ void usb_gadget_unmap_request_by_dev(str is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->num_mapped_sgs =0 ; - }else { + }else if (req->dma_mapped) {dma_unmap_single (dev, req->dma, req->length, is_in ?DMA_TO_DEVICE :DMA_FROM_DEVICE ); + req->dma_mapped =0 ; } }EXPORT_SYMBOL_GPL (usb_gadget_unmap_request_by_dev);
include/linux/usb/gadget.h +2 -0
@@ -48,6 +48,7 @@ struct usb_ep;* by adding a zero length packet as needed; * @short_not_ok: When reading data, makes short packets be * treated as errors (queue stops advancing till cleanup). +* @dma_mapped: Indicates if request has been mapped to DMA (internal) * @complete: Function called when request completes, so this request and * its buffer may be re-used. The function will always be called with * interrupts disabled, and it must not sleep.
@@ -103,6 +104,7 @@ struct usb_request { unsigned no_interrupt:1; unsigned zero:1; unsigned short_not_ok:1; + unsigned dma_mapped:1;void (*complete)(struct usb_ep *ep,struct usb_request *req);
Greg Kroah-Hartman
maintainerPATCH 5/31 KVM: x86: use Intel speculation bugs and features as derived in generic x86 code
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 0c54914d0c52a15db9954a76ce80fee32cf318f4 upstream.
Similar to AMD bits, set the Intel bits from the vendor-independent feature and bug flags, because KVM_GET_SUPPORTED_CPUID does not care about the vendor and they should be set on AMD processors as well.
--- arch/x86/kvm/cpuid.c | 8 ++++++++ arch/x86/kvm/x86.c | 8 ++++++++ 2 files changed, 16 insertions(+)
arch/x86/kvm/cpuid.c +8 -0
@@ -466,8 +466,16 @@ static inline int __do_cpuid_ent(struct/* PKU is not yet implemented for shadow paging. */ if (!tdp_enabled || !boot_cpu_has (X86_FEATURE_OSPKE )) entry->ecx &= ~F (PKU ); + entry->edx &= kvm_cpuid_7_0_edx_x86_features;cpuid_mask (&entry->edx,CPUID_7_EDX ); +if (boot_cpu_has (X86_FEATURE_IBPB ) && +boot_cpu_has (X86_FEATURE_IBRS )) + entry->edx |=F (SPEC_CTRL ); +if (boot_cpu_has (X86_FEATURE_STIBP )) + entry->edx |=F (INTEL_STIBP ); +if (boot_cpu_has (X86_FEATURE_SSBD )) + entry->edx |=F (SPEC_CTRL_SSBD );/* * We emulate ARCH_CAPABILITIES in software even * if the host doesn't support it.
arch/x86/kvm/x86.c +8 -0
@@ -1043,8 +1043,16 @@ u64 kvm_get_arch_capabilities(void)if (l1tf_vmx_mitigation !=VMENTER_L1D_FLUSH_NEVER ) data |=ARCH_CAP_SKIP_VMENTRY_L1DFLUSH ; +if (!boot_cpu_has_bug (X86_BUG_CPU_MELTDOWN )) + data |=ARCH_CAP_RDCL_NO ; +if (!boot_cpu_has_bug (X86_BUG_SPEC_STORE_BYPASS )) + data |=ARCH_CAP_SSB_NO ; +if (!boot_cpu_has_bug (X86_BUG_MDS )) + data |=ARCH_CAP_MDS_NO ; +return data; } +EXPORT_SYMBOL_GPL (kvm_get_arch_capabilities);static int kvm_get_msr_feature (struct kvm_msr_entry *msr)
Greg Kroah-Hartman
maintainerPATCH 6/31 x86/msr: Add the IA32_TSX_CTRL MSR
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit c2955f270a84762343000f103e0640d29c7a96f3 upstream.
Transactional Synchronization Extensions (TSX) may be used on certain processors as part of a speculative side channel attack. A microcode update for existing processors that are vulnerable to this attack will add a new MSR - IA32_TSX_CTRL to allow the system administrator the option to disable TSX as one of the possible mitigations.
The CPUs which get this new MSR after a microcode upgrade are the ones which do not set MSR_IA32_ARCH_CAPABILITIES.MDS_NO (bit 5) because those CPUs have CPUID.MD_CLEAR, i.e., the VERW implementation which clears all CPU buffers takes care of the TAA case as well.
[ Note that future processors that are not vulnerable will also
support the IA32_TSX_CTRL MSR. ]
Add defines for the new IA32_TSX_CTRL MSR and its bits.
TSX has two sub-features:
1. Restricted Transactional Memory (RTM) is an explicitly-used feature where new instructions begin and end TSX transactions.
2. Hardware Lock Elision (HLE) is implicitly used when certain kinds of "old" style locks are used by software.
Bit 7 of the IA32_ARCH_CAPABILITIES indicates the presence of the IA32_TSX_CTRL MSR.
There are two control bits in IA32_TSX_CTRL MSR:
Bit 0: When set, it disables the Restricted Transactional Memory (RTM)
sub-feature of TSX (will force all transactions to abort on the XBEGIN instruction).
Bit 1: When set, it disables the enumeration of the RTM and HLE feature
(i.e. it will make CPUID(EAX=7).EBX{bit4} and
CPUID(EAX=7).EBX{bit11} read as 0).
The other TSX sub-feature, Hardware Lock Elision (HLE), is unconditionally disabled by the new microcode but still enumerated as present by CPUID(EAX=7).EBX{bit4}, unless disabled by IA32_TSX_CTRL_MSR[1] - TSX_CTRL_CPUID_CLEAR.
--- arch/x86/include/asm/msr-index.h | 5 +++++ 1 file changed, 5 insertions(+)
arch/x86/include/asm/msr-index.h +5 -0
@@ -77,6 +77,7 @@* Microarchitectural Data * Sampling (MDS) vulnerabilities. */ +#define ARCH_CAP_TSX_CTRL_MSR BIT(7)/* MSR for TSX control is available. */ #define MSR_IA32_FLUSH_CMD 0x0000010b#define L1D_FLUSH BIT(0)/*
@@ -87,6 +88,10 @@#define MSR_IA32_BBL_CR_CTL 0x00000119#define MSR_IA32_BBL_CR_CTL3 0x0000011e +#define MSR_IA32_TSX_CTRL 0x00000122 +#define TSX_CTRL_RTM_DISABLE BIT(0)/* Disable RTM feature */ +#define TSX_CTRL_CPUID_CLEAR BIT(1)/* Disable TSX enumeration */ +#define MSR_IA32_SYSENTER_CS 0x00000174#define MSR_IA32_SYSENTER_ESP 0x00000175#define MSR_IA32_SYSENTER_EIP 0x00000176
Greg Kroah-Hartman
maintainerPATCH 7/31 x86/cpu: Add a helper function x86_read_arch_cap_msr()
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit 286836a70433fb64131d2590f4bf512097c255e1 upstream.
Add a helper function to read the IA32_ARCH_CAPABILITIES MSR.
--- arch/x86/kernel/cpu/common.c | 15 +++++++++++---- arch/x86/kernel/cpu/cpu.h | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-)
arch/x86/kernel/cpu/common.c +11 -4
@@ -962,19 +962,26 @@ static bool __init cpu_matches(unsignedreturn m && !!(m->driver_data & which); } -static void __init cpu_set_bug_bits (struct cpuinfo_x86 *c) +u64 x86_read_arch_cap_msr (void ) {u64 ia32_cap =0 ; +if (boot_cpu_has (X86_FEATURE_ARCH_CAPABILITIES )) +rdmsrl (MSR_IA32_ARCH_CAPABILITIES , ia32_cap); + +return ia32_cap; +} + +static void __init cpu_set_bug_bits (struct cpuinfo_x86 *c) +{ +u64 ia32_cap =x86_read_arch_cap_msr (); +if (cpu_matches (NO_SPECULATION ))return ;setup_force_cpu_bug (X86_BUG_SPECTRE_V1 );setup_force_cpu_bug (X86_BUG_SPECTRE_V2 ); -if (cpu_has (c,X86_FEATURE_ARCH_CAPABILITIES )) -rdmsrl (MSR_IA32_ARCH_CAPABILITIES , ia32_cap); -if (!cpu_matches (NO_SSB ) && !(ia32_cap &ARCH_CAP_SSB_NO ) && !cpu_has (c,X86_FEATURE_AMD_SSB_NO ))setup_force_cpu_bug (X86_BUG_SPEC_STORE_BYPASS );
arch/x86/kernel/cpu/cpu.h +2 -0
@@ -51,4 +51,6 @@ extern int detect_ht_early(struct cpuinfextern void x86_spec_ctrl_setup_ap (void ); +extern u64 x86_read_arch_cap_msr (void ); +#endif /* ARCH_X86_CPU_H */
Greg Kroah-Hartman
maintainerPATCH 8/31 x86/cpu: Add a "tsx=" cmdline option with TSX disabled by default
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit 95c5824f75f3ba4c9e8e5a4b1a623c95390ac266 upstream.
Add a kernel cmdline parameter "tsx" to control the Transactional Synchronization Extensions (TSX) feature. On CPUs that support TSX control, use "tsx=on|off" to enable or disable TSX. Not specifying this option is equivalent to "tsx=off". This is because on certain processors TSX may be used as a part of a speculative side channel attack.
Carve out the TSX controlling functionality into a separate compilation unit because TSX is a CPU feature while the TSX async abort control machinery will go to cpu/bugs.c.
[ bp: - Massage, shorten and clear the arg buffer.
- Clarifications of the tsx= possible options - Josh.
- Expand on TSX_CTRL availability - Pawan. ]
--- Documentation/kernel-parameters.txt | 26 +++++++ arch/x86/kernel/cpu/Makefile | 2 arch/x86/kernel/cpu/common.c | 2 arch/x86/kernel/cpu/cpu.h | 16 ++++ arch/x86/kernel/cpu/intel.c | 5 + arch/x86/kernel/cpu/tsx.c | 125 ++++++++++++++++++++++++++++++++++++ 6 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 arch/x86/kernel/cpu/tsx.c
Documentation/kernel-parameters.txt +26 -0
@@ -4516,6 +4516,32 @@ bytes respectively. Such letter suffixes platforms where RDTSC is slow and this accounting can add overhead. + tsx= [X86] Control Transactional Synchronization + Extensions (TSX) feature in Intel processors that + support TSX control. + + This parameter controls the TSX feature. The options are: + + on - Enable TSX on the system. Although there are + mitigations for all known security vulnerabilities, + TSX has been known to be an accelerator for + several previous speculation-related CVEs, and + so there may be unknown security risks associated + with leaving it enabled. + + off - Disable TSX on the system. (Note that this + option takes effect only on newer CPUs which are + not vulnerable to MDS, i.e., have + MSR_IA32_ARCH_CAPABILITIES.MDS_NO=1 and which get + the new IA32_TSX_CTRL MSR through a microcode + update. This new MSR allows for the reliable + deactivation of the TSX functionality.) + + Not specifying this option is equivalent to tsx=off. + + See Documentation/hw-vuln/tsx_async_abort.rst + for more details. + turbografx.map[2|3]= [HW,JOY] TurboGraFX parallel port interface Format:
arch/x86/kernel/cpu/Makefile +1 -1
@@ -25,7 +25,7 @@ obj-y += bugs.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o -obj-$(CONFIG_CPU_SUP_INTEL) += intel.o +obj-$(CONFIG_CPU_SUP_INTEL) += intel.o tsx.o obj-$(CONFIG_CPU_SUP_AMD) += amd.o obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o
arch/x86/kernel/cpu/common.c +2 -0
@@ -1416,6 +1416,8 @@ void __init identify_boot_cpu(void)enable_sep_cpu ();#endif cpu_detect_tlb (&boot_cpu_data); + +tsx_init (); }void identify_secondary_cpu (struct cpuinfo_x86 *c)
arch/x86/kernel/cpu/cpu.h +16 -0
@@ -44,6 +44,22 @@ struct _tlb_table {extern const struct cpu_dev *const __x86_cpu_dev_start[], *const __x86_cpu_dev_end[]; +#ifdef CONFIG_CPU_SUP_INTEL +enum tsx_ctrl_states { +TSX_CTRL_ENABLE , +TSX_CTRL_DISABLE , +TSX_CTRL_NOT_SUPPORTED , +}; + +extern __ro_after_init enum tsx_ctrl_states tsx_ctrl_state; + +extern void __init tsx_init (void ); +extern void tsx_enable (void ); +extern void tsx_disable (void ); +#else +static inline void tsx_init (void ) { } +#endif /* CONFIG_CPU_SUP_INTEL */ +extern void get_cpu_cap (struct cpuinfo_x86 *c);extern void cpu_detect_cache_sizes (struct cpuinfo_x86 *c);extern int detect_extended_topology_early (struct cpuinfo_x86 *c);
arch/x86/kernel/cpu/intel.c +5 -0
@@ -642,6 +642,11 @@ static void init_intel(struct cpuinfo_x8detect_vmx_virtcap (c);init_intel_energy_perf (c); + +if (tsx_ctrl_state ==TSX_CTRL_ENABLE ) +tsx_enable (); +if (tsx_ctrl_state ==TSX_CTRL_DISABLE ) +tsx_disable (); }#ifdef CONFIG_X86_32
arch/x86/kernel/cpu/tsx.c new file +125 -0
125 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 9/31 x86/speculation/taa: Add mitigation for TSX Async Abort
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit 1b42f017415b46c317e71d41c34ec088417a1883 upstream.
TSX Async Abort (TAA) is a side channel vulnerability to the internal buffers in some Intel processors similar to Microachitectural Data Sampling (MDS). In this case, certain loads may speculatively pass invalid data to dependent operations when an asynchronous abort condition is pending in a TSX transaction.
This includes loads with no fault or assist condition. Such loads may speculatively expose stale data from the uarch data structures as in MDS. Scope of exposure is within the same-thread and cross-thread. This issue affects all current processors that support TSX, but do not have ARCH_CAP_TAA_NO (bit 8) set in MSR_IA32_ARCH_CAPABILITIES.
On CPUs which have their IA32_ARCH_CAPABILITIES MSR bit MDS_NO=0, CPUID.MD_CLEAR=1 and the MDS mitigation is clearing the CPU buffers using VERW or L1D_FLUSH, there is no additional mitigation needed for TAA. On affected CPUs with MDS_NO=1 this issue can be mitigated by disabling the Transactional Synchronization Extensions (TSX) feature.
A new MSR IA32_TSX_CTRL in future and current processors after a microcode update can be used to control the TSX feature. There are two bits in that MSR:
* TSX_CTRL_RTM_DISABLE disables the TSX sub-feature Restricted Transactional Memory (RTM).
* TSX_CTRL_CPUID_CLEAR clears the RTM enumeration in CPUID. The other TSX sub-feature, Hardware Lock Elision (HLE), is unconditionally disabled with updated microcode but still enumerated as present by CPUID(EAX=7).EBX{bit4}.
The second mitigation approach is similar to MDS which is clearing the affected CPU buffers on return to user space and when entering a guest. Relevant microcode update is required for the mitigation to work. More details on this approach can be found here:
https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html
The TSX feature can be controlled by the "tsx" command line parameter. If it is force-enabled then "Clear CPU buffers" (MDS mitigation) is deployed. The effective mitigation state can be read from sysfs.
[ bp:
- massage + comments cleanup
- s/TAA_MITIGATION_TSX_DISABLE/TAA_MITIGATION_TSX_DISABLED/g - Josh.
- remove partial TAA mitigation in update_mds_branch_idle() - Josh.
- s/tsx_async_abort_cmdline/tsx_async_abort_parse_cmdline/g
]
[bwh: Backported to 4.9:
- Add #include "cpu.h" in bugs.c
- Adjust context, indentation]
--- arch/x86/include/asm/cpufeatures.h | 1 arch/x86/include/asm/msr-index.h | 4 + arch/x86/include/asm/nospec-branch.h | 4 - arch/x86/include/asm/processor.h | 7 ++ arch/x86/kernel/cpu/bugs.c | 110 +++++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/common.c | 15 ++++ 6 files changed, 139 insertions(+), 2 deletions(-)
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -357,5 +357,6 @@#define X86_BUG_MDS X86_BUG(19)/* CPU is affected by Microarchitectural data sampling */ #define X86_BUG_MSBDS_ONLY X86_BUG(20)/* CPU is only affected by the MSDBS variant of BUG_MDS */ #define X86_BUG_SWAPGS X86_BUG(21)/* CPU is affected by speculation through SWAPGS */ +#define X86_BUG_TAA X86_BUG(22)/* CPU is affected by TSX Async Abort(TAA) */ #endif /* _ASM_X86_CPUFEATURES_H */
arch/x86/include/asm/msr-index.h +4 -0
@@ -78,6 +78,10 @@* Sampling (MDS) vulnerabilities. */ #define ARCH_CAP_TSX_CTRL_MSR BIT(7)/* MSR for TSX control is available. */ +#define ARCH_CAP_TAA_NO BIT(8)/* +* Not susceptible to +* TSX Async Abort (TAA) vulnerabilities. +*/ #define MSR_IA32_FLUSH_CMD 0x0000010b#define L1D_FLUSH BIT(0)/*
arch/x86/include/asm/nospec-branch.h +2 -2
@@ -314,7 +314,7 @@ DECLARE_STATIC_KEY_FALSE(mds_idle_clear)#include <asm/segment.h> /** -* mds_clear_cpu_buffers - Mitigation for MDS vulnerability +* mds_clear_cpu_buffers - Mitigation for MDS and TAA vulnerability * * This uses the otherwise unused and obsolete VERW instruction in * combination with microcode which triggers a CPU buffer flush when the
@@ -337,7 +337,7 @@ static inline void mds_clear_cpu_buffers }/** -* mds_user_clear_cpu_buffers - Mitigation for MDS vulnerability +* mds_user_clear_cpu_buffers - Mitigation for MDS and TAA vulnerability * * Clear CPU buffers if the corresponding static key is enabled */
arch/x86/include/asm/processor.h +7 -0
@@ -880,4 +880,11 @@ enum mds_mitigations { MDS_MITIGATION_VMWERV, }; +enum taa_mitigations { +TAA_MITIGATION_OFF , +TAA_MITIGATION_UCODE_NEEDED , +TAA_MITIGATION_VERW , +TAA_MITIGATION_TSX_DISABLED , +}; +#endif /* _ASM_X86_PROCESSOR_H */
arch/x86/kernel/cpu/bugs.c +110 -0
145 lines not on this page · raw message
arch/x86/kernel/cpu/common.c +15 -0
@@ -998,6 +998,21 @@ static void __init cpu_set_bug_bits(struif (!cpu_matches (NO_SWAPGS ))setup_force_cpu_bug (X86_BUG_SWAPGS ); +/* +* When the CPU is not mitigated for TAA (TAA_NO=0) set TAA bug when: +* - TSX is supported or +* - TSX_CTRL is present +* +* TSX_CTRL check is needed for cases when TSX could be disabled before +* the kernel boot e.g. kexec. +* TSX_CTRL check alone is not sufficient for cases when the microcode +* update is not present or running as guest that don't get TSX_CTRL. +*/ +if (!(ia32_cap &ARCH_CAP_TAA_NO ) && + (cpu_has (c,X86_FEATURE_RTM ) || + (ia32_cap &ARCH_CAP_TSX_CTRL_MSR ))) +setup_force_cpu_bug (X86_BUG_TAA ); +if (cpu_matches (NO_MELTDOWN ))return ;
Greg Kroah-Hartman
maintainerPATCH 10/31 x86/speculation/taa: Add sysfs reporting for TSX Async Abort
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit 6608b45ac5ecb56f9e171252229c39580cc85f0f upstream.
Add the sysfs reporting file for TSX Async Abort. It exposes the vulnerability and the mitigation state similar to the existing files for the other hardware vulnerabilities.
Sysfs file path is:/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
--- arch/x86/kernel/cpu/bugs.c | 23 +++++++++++++++++++++++ drivers/base/cpu.c | 9 +++++++++ include/linux/cpu.h | 3 +++ 3 files changed, 35 insertions(+)
arch/x86/kernel/cpu/bugs.c +23 -0
@@ -1418,6 +1418,21 @@ static ssize_t mds_show_state(char *buf) sched_smt_active() ? "vulnerable" : "disabled"); } +static ssize_t tsx_async_abort_show_state (char *buf) +{ +if ((taa_mitigation ==TAA_MITIGATION_TSX_DISABLED ) || + (taa_mitigation ==TAA_MITIGATION_OFF )) +return sprintf (buf,"%s\n" , taa_strings[taa_mitigation]); + +if (boot_cpu_has (X86_FEATURE_HYPERVISOR )) { +return sprintf (buf,"%s; SMT Host state unknown\n" , + taa_strings[taa_mitigation]); + } + +return sprintf (buf,"%s; SMT %s\n" , taa_strings[taa_mitigation], +sched_smt_active () ?"vulnerable" :"disabled" ); +} +static char *stibp_state (void ) {if (spectre_v2_enabled ==SPECTRE_V2_IBRS_ENHANCED )
@@ -1483,6 +1498,9 @@ static ssize_t cpu_show_common(struct decase X86_BUG_MDS :return mds_show_state (buf); +case X86_BUG_TAA : +return tsx_async_abort_show_state (buf); +default :break ; }
@@ -1519,4 +1537,9 @@ ssize_t cpu_show_mds(struct device *dev, {return cpu_show_common (dev, attr, buf,X86_BUG_MDS ); } + +ssize_t cpu_show_tsx_async_abort (struct device *dev,struct device_attribute *attr,char *buf) +{ +return cpu_show_common (dev, attr, buf,X86_BUG_TAA ); +}#endif
drivers/base/cpu.c +9 -0
@@ -537,12 +537,20 @@ ssize_t __weak cpu_show_mds(struct devicreturn sprintf (buf,"Not affected\n" ); } +ssize_t __weak cpu_show_tsx_async_abort (struct device *dev, +struct device_attribute *attr, +char *buf) +{ +return sprintf (buf,"Not affected\n" ); +} + static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); static DEVICE_ATTR(spec_store_bypass, 0444, cpu_show_spec_store_bypass, NULL); static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL); static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL); +static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr,
@@ -551,6 +559,7 @@ static struct attribute *cpu_root_vulner &dev_attr_spec_store_bypass.attr, &dev_attr_l1tf.attr, &dev_attr_mds.attr, + &dev_attr_tsx_async_abort.attr, NULL };
include/linux/cpu.h +3 -0
@@ -56,6 +56,9 @@ extern ssize_t cpu_show_l1tf(struct devi struct device_attribute *attr, char *buf);extern ssize_t cpu_show_mds (struct device *dev,struct device_attribute *attr,char *buf); +extern ssize_t cpu_show_tsx_async_abort (struct device *dev, +struct device_attribute *attr, +char *buf); extern __printf(4, 5) struct device *cpu_device_create(struct device *parent, void *drvdata,
Greg Kroah-Hartman
maintainerPATCH 11/31 kvm/x86: Export MDS_NO=0 to guests when TSX is enabled
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit e1d38b63acd843cfdd4222bf19a26700fd5c699e upstream.
Export the IA32_ARCH_CAPABILITIES MSR bit MDS_NO=0 to guests on TSX Async Abort(TAA) affected hosts that have TSX enabled and updated microcode. This is required so that the guests don't complain,
"Vulnerable: Clear CPU buffers attempted, no microcode"
when the host has the updated microcode to clear CPU buffers.
Microcode update also adds support for MSR_IA32_TSX_CTRL which is enumerated by the ARCH_CAP_TSX_CTRL bit in IA32_ARCH_CAPABILITIES MSR. Guests can't do this check themselves when the ARCH_CAP_TSX_CTRL bit is not exported to the guests.
In this case export MDS_NO=0 to the guests. When guests have CPUID.MD_CLEAR=1, they deploy MDS mitigation which also mitigates TAA.
--- arch/x86/kvm/x86.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
arch/x86/kvm/x86.c +19 -0
@@ -1050,6 +1050,25 @@ u64 kvm_get_arch_capabilities(void)if (!boot_cpu_has_bug (X86_BUG_MDS )) data |=ARCH_CAP_MDS_NO ; +/* +* On TAA affected systems, export MDS_NO=0 when: +* - TSX is enabled on the host, i.e. X86_FEATURE_RTM=1. +* - Updated microcode is present. This is detected by +* the presence of ARCH_CAP_TSX_CTRL_MSR and ensures +* that VERW clears CPU buffers. +* +* When MDS_NO=0 is exported, guests deploy clear CPU buffer +* mitigation and don't complain: +* +* "Vulnerable: Clear CPU buffers attempted, no microcode" +* +* If TSX is disabled on the system, guests are also mitigated against +* TAA and clear CPU buffer mitigation is not required for guests. +*/ +if (boot_cpu_has_bug (X86_BUG_TAA ) &&boot_cpu_has (X86_FEATURE_RTM ) && + (data &ARCH_CAP_TSX_CTRL_MSR )) + data &= ~ARCH_CAP_MDS_NO ; +return data; }
Greg Kroah-Hartman
maintainerPATCH 12/31 x86/tsx: Add "auto" option to the tsx= cmdline parameter
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit 7531a3596e3272d1f6841e0d601a614555dc6b65 upstream.
Platforms which are not affected by X86_BUG_TAA may want the TSX feature enabled. Add "auto" option to the TSX cmdline parameter. When tsx=auto disable TSX when X86_BUG_TAA is present, otherwise enable TSX.
More details on X86_BUG_TAA can be found here:
https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/tsx_async_abort.html
[ bp: Extend the arg buffer to accommodate "auto\0". ]
--- Documentation/kernel-parameters.txt | 3 +++ arch/x86/kernel/cpu/tsx.c | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-)
Documentation/kernel-parameters.txt +3 -0
@@ -4537,6 +4537,9 @@ bytes respectively. Such letter suffixes update. This new MSR allows for the reliable deactivation of the TSX functionality.) + auto - Disable TSX if X86_BUG_TAA is present, + otherwise enable TSX on the system. + Not specifying this option is equivalent to tsx=off. See Documentation/hw-vuln/tsx_async_abort.rst
arch/x86/kernel/cpu/tsx.c +6 -1
@@ -75,7 +75,7 @@ static bool __init tsx_ctrl_is_supportedvoid __init tsx_init (void ) { -char arg[4 ] = {}; +char arg[5 ] = {};int ret;if (!tsx_ctrl_is_supported ())
@@ -87,6 +87,11 @@ void __init tsx_init(void) tsx_ctrl_state =TSX_CTRL_ENABLE ; }else if (!strcmp (arg,"off" )) { tsx_ctrl_state =TSX_CTRL_DISABLE ; + }else if (!strcmp (arg,"auto" )) { +if (boot_cpu_has_bug (X86_BUG_TAA )) + tsx_ctrl_state =TSX_CTRL_DISABLE ; +else + tsx_ctrl_state =TSX_CTRL_ENABLE ; }else { tsx_ctrl_state =TSX_CTRL_DISABLE ;pr_err ("tsx: invalid option, defaulting to off\n" );
Greg Kroah-Hartman
maintainerPATCH 13/31 x86/speculation/taa: Add documentation for TSX Async Abort
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit a7a248c593e4fd7a67c50b5f5318fe42a0db335e upstream.
Add the documenation for TSX Async Abort. Include the description of the issue, how to check the mitigation state, control the mitigation, guidance for system administrators.
[ bp: Add proper SPDX tags, touch ups by Josh and me. ]
--- Documentation/ABI/testing/sysfs-devices-system-cpu | 1 Documentation/hw-vuln/index.rst | 1 Documentation/hw-vuln/tsx_async_abort.rst | 276 +++++++++++++++++++++ Documentation/kernel-parameters.txt | 38 ++ Documentation/x86/index.rst | 1 Documentation/x86/tsx_async_abort.rst | 117 ++++++++ 6 files changed, 434 insertions(+) create mode 100644 Documentation/hw-vuln/tsx_async_abort.rst create mode 100644 Documentation/x86/tsx_async_abort.rst
Documentation/ABI/testing/sysfs-devices-system-cpu +1 -0
@@ -358,6 +358,7 @@ What: /sys/devices/system/cpu/vulnerabi /sys/devices/system/cpu/vulnerabilities/spec_store_bypass /sys/devices/system/cpu/vulnerabilities/l1tf /sys/devices/system/cpu/vulnerabilities/mds + /sys/devices/system/cpu/vulnerabilities/tsx_async_abort Date: January 2018 Contact: Linux kernel mailing list <[email protected]> Description: Information about CPU vulnerabilities
Documentation/hw-vuln/index.rst +1 -0
@@ -11,3 +11,4 @@ are configurable at compile, boot or run l1tf mds + tsx_async_abort
Documentation/hw-vuln/tsx_async_abort.rst new file +276 -0
276 lines not on this page · raw message
Documentation/kernel-parameters.txt +38 -0
@@ -2490,6 +2490,7 @@ bytes respectively. Such letter suffixes spec_store_bypass_disable=off [X86] l1tf=off [X86] mds=off [X86] + tsx_async_abort=off [X86] auto (default) Mitigate all CPU vulnerabilities, but leave SMT
@@ -2505,6 +2506,7 @@ bytes respectively. Such letter suffixes be fully mitigated, even if it means losing SMT. Equivalent to: l1tf=flush,nosmt [X86] mds=full,nosmt [X86] + tsx_async_abort=full,nosmt [X86] mminit_loglevel= [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
@@ -4545,6 +4547,42 @@ bytes respectively. Such letter suffixes See Documentation/hw-vuln/tsx_async_abort.rst for more details. + tsx_async_abort= [X86,INTEL] Control mitigation for the TSX Async + Abort (TAA) vulnerability. + + Similar to Micro-architectural Data Sampling (MDS) + certain CPUs that support Transactional + Synchronization Extensions (TSX) are vulnerable to an + exploit against CPU internal buffers which can forward + information to a disclosure gadget under certain + conditions. + + In vulnerable processors, the speculatively forwarded + data can be used in a cache side channel attack, to + access data to which the attacker does not have direct + access. + + This parameter controls the TAA mitigation. The + options are: + + full - Enable TAA mitigation on vulnerable CPUs + if TSX is enabled. + + full,nosmt - Enable TAA mitigation and disable SMT on + vulnerable CPUs. If TSX is disabled, SMT + is not disabled because CPU is not + vulnerable to cross-thread TAA attacks. + off - Unconditionally disable TAA mitigation + + Not specifying this option is equivalent to + tsx_async_abort=full. On CPUs which are MDS affected + and deploy MDS mitigation, TAA mitigation is not + required and doesn't provide any additional + mitigation. + + For details see: + Documentation/hw-vuln/tsx_async_abort.rst + turbografx.map[2|3]= [HW,JOY] TurboGraFX parallel port interface Format:
Documentation/x86/index.rst +1 -0
@@ -6,3 +6,4 @@ x86 architecture specifics :maxdepth: 1 mds + tsx_async_abort
Documentation/x86/tsx_async_abort.rst new file +117 -0
117 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 14/31 x86/tsx: Add config options to set tsx=on|off|auto
In reply to Greg Kroah-HartmanFrom: Michal Hocko <[email protected]>
commit db616173d787395787ecc93eef075fa975227b10 upstream.
There is a general consensus that TSX usage is not largely spread while the history shows there is a non trivial space for side channel attacks possible. Therefore the tsx is disabled by default even on platforms that might have a safe implementation of TSX according to the current knowledge. This is a fair trade off to make.
There are, however, workloads that really do benefit from using TSX and updating to a newer kernel with TSX disabled might introduce a noticeable regressions. This would be especially a problem for Linux distributions which will provide TAA mitigations.
Introduce config options X86_INTEL_TSX_MODE_OFF, X86_INTEL_TSX_MODE_ON and X86_INTEL_TSX_MODE_AUTO to control the TSX feature. The config setting can be overridden by the tsx cmdline options.
[ bp: Text cleanups from Josh. ]
--- arch/x86/Kconfig | 45 +++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/tsx.c | 22 ++++++++++++++++------ 2 files changed, 61 insertions(+), 6 deletions(-)
arch/x86/Kconfig +45 -0
@@ -1755,6 +1755,51 @@ config X86_INTEL_MEMORY_PROTECTION_KEYS If unsure, say y. +choice + prompt "TSX enable mode" + depends on CPU_SUP_INTEL + default X86_INTEL_TSX_MODE_OFF + help + Intel's TSX (Transactional Synchronization Extensions) feature + allows to optimize locking protocols through lock elision which + can lead to a noticeable performance boost. + + On the other hand it has been shown that TSX can be exploited + to form side channel attacks (e.g. TAA) and chances are there + will be more of those attacks discovered in the future. + + Therefore TSX is not enabled by default (aka tsx=off). An admin + might override this decision by tsx=on the command line parameter. + Even with TSX enabled, the kernel will attempt to enable the best + possible TAA mitigation setting depending on the microcode available + for the particular machine. + + This option allows to set the default tsx mode between tsx=on, =off + and =auto. See Documentation/kernel-parameters.txt for more + details. + + Say off if not sure, auto if TSX is in use but it should be used on safe + platforms or on if TSX is in use and the security aspect of tsx is not + relevant. + +config X86_INTEL_TSX_MODE_OFF + bool "off" + help + TSX is disabled if possible - equals to tsx=off command line parameter. + +config X86_INTEL_TSX_MODE_ON + bool "on" + help + TSX is always enabled on TSX capable HW - equals the tsx=on command + line parameter. + +config X86_INTEL_TSX_MODE_AUTO + bool "auto" + help + TSX is enabled on TSX capable HW that is believed to be safe against + side channel attacks- equals the tsx=auto command line parameter. +endchoice + config EFI bool "EFI runtime service support" depends on ACPI
arch/x86/kernel/cpu/tsx.c +16 -6
@@ -73,6 +73,14 @@ static bool __init tsx_ctrl_is_supportedreturn !!(ia32_cap &ARCH_CAP_TSX_CTRL_MSR ); } +static enum tsx_ctrl_states x86_get_tsx_auto_mode (void ) +{ +if (boot_cpu_has_bug (X86_BUG_TAA )) +return TSX_CTRL_DISABLE ; + +return TSX_CTRL_ENABLE ; +} +void __init tsx_init (void ) {char arg[5 ] = {};
@@ -88,17 +96,19 @@ void __init tsx_init(void) }else if (!strcmp (arg,"off" )) { tsx_ctrl_state =TSX_CTRL_DISABLE ; }else if (!strcmp (arg,"auto" )) { -if (boot_cpu_has_bug (X86_BUG_TAA )) - tsx_ctrl_state =TSX_CTRL_DISABLE ; -else - tsx_ctrl_state =TSX_CTRL_ENABLE ; + tsx_ctrl_state =x86_get_tsx_auto_mode (); }else { tsx_ctrl_state =TSX_CTRL_DISABLE ;pr_err ("tsx: invalid option, defaulting to off\n" ); } }else { -/* tsx= not provided, defaulting to off */ - tsx_ctrl_state =TSX_CTRL_DISABLE ; +/* tsx= not provided */ +if (IS_ENABLED (CONFIG_X86_INTEL_TSX_MODE_AUTO )) + tsx_ctrl_state =x86_get_tsx_auto_mode (); +else if (IS_ENABLED (CONFIG_X86_INTEL_TSX_MODE_OFF )) + tsx_ctrl_state =TSX_CTRL_DISABLE ; +else + tsx_ctrl_state =TSX_CTRL_ENABLE ; }if (tsx_ctrl_state ==TSX_CTRL_DISABLE ) {
Greg Kroah-Hartman
maintainerPATCH 15/31 x86/speculation/taa: Fix printing of TAA_MSG_SMT on IBRS_ALL CPUs
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 012206a822a8b6ac09125bfaa210a95b9eb8f1c1 upstream.
For new IBRS_ALL CPUs, the Enhanced IBRS check at the beginning of cpu_bugs_smt_update() causes the function to return early, unintentionally skipping the MDS and TAA logic.
This is not a problem for MDS, because there appears to be no overlap between IBRS_ALL and MDS-affected CPUs. So the MDS mitigation would be disabled and nothing would need to be done in this function anyway.
But for TAA, the TAA_MSG_SMT string will never get printed on Cascade Lake and newer.
The check is superfluous anyway: when 'spectre_v2_enabled' is SPECTRE_V2_IBRS_ENHANCED, 'spectre_v2_user' is always SPECTRE_V2_USER_NONE, and so the 'spectre_v2_user' switch statement handles it appropriately by doing nothing. So just remove the check.
--- arch/x86/kernel/cpu/bugs.c | 4 ---- 1 file changed, 4 deletions(-)
arch/x86/kernel/cpu/bugs.c +0 -4
@@ -882,10 +882,6 @@ static void update_mds_branch_idle(void)void arch_smt_update (void ) { -/* Enhanced IBRS implies STIBP. No update required. */ -if (spectre_v2_enabled ==SPECTRE_V2_IBRS_ENHANCED ) -return ; -mutex_lock (&spec_ctrl_mutex);switch (spectre_v2_user) {
Greg Kroah-Hartman
maintainerPATCH 16/31 KVM: x86: simplify ept_misconfig
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit e08d26f0712532c79b5ba6200862eaf2036f8df6 upstream.
Calling handle_mmio_page_fault() has been unnecessary since commit e9ee956e311d ("KVM: x86: MMU: Move handle_mmio_page_fault() call to kvm_mmu_page_fault()", 2016-02-22).
handle_mmio_page_fault() can now be made static.
--- arch/x86/kvm/mmu.c | 19 ++++++++++++++++++- arch/x86/kvm/mmu.h | 17 ----------------- arch/x86/kvm/vmx.c | 13 +++---------- 3 files changed, 21 insertions(+), 28 deletions(-)
arch/x86/kvm/mmu.c +18 -1
@@ -3383,7 +3383,23 @@ exit:return reserved; } -int handle_mmio_page_fault (struct kvm_vcpu *vcpu,u64 addr,bool direct) +/* +* Return values of handle_mmio_page_fault: +* RET_MMIO_PF_EMULATE: it is a real mmio page fault, emulate the instruction +* directly. +* RET_MMIO_PF_INVALID: invalid spte is detected then let the real page +* fault path update the mmio spte. +* RET_MMIO_PF_RETRY: let CPU fault again on the address. +* RET_MMIO_PF_BUG: a bug was detected (and a WARN was printed). +*/ +enum { +RET_MMIO_PF_EMULATE =1 , +RET_MMIO_PF_INVALID =2 , +RET_MMIO_PF_RETRY =0 , +RET_MMIO_PF_BUG =-1 +}; + +static int handle_mmio_page_fault (struct kvm_vcpu *vcpu,u64 addr,bool direct) {u64 spte;bool reserved;
@@ -4520,6 +4536,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *return 1 ;if (r <0 )return r; +/* Must be RET_MMIO_PF_INVALID. */ } r = vcpu->arch.mmu.page_fault (vcpu, cr2, error_code, false);
arch/x86/kvm/mmu.h +0 -17
@@ -56,23 +56,6 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmiovoid reset_shadow_zero_bits_mask (struct kvm_vcpu *vcpu,struct kvm_mmu *context); -/* -* Return values of handle_mmio_page_fault: -* RET_MMIO_PF_EMULATE: it is a real mmio page fault, emulate the instruction -* directly. -* RET_MMIO_PF_INVALID: invalid spte is detected then let the real page -* fault path update the mmio spte. -* RET_MMIO_PF_RETRY: let CPU fault again on the address. -* RET_MMIO_PF_BUG: a bug was detected (and a WARN was printed). -*/ -enum { -RET_MMIO_PF_EMULATE =1 , -RET_MMIO_PF_INVALID =2 , -RET_MMIO_PF_RETRY =0 , -RET_MMIO_PF_BUG =-1 -}; - -int handle_mmio_page_fault (struct kvm_vcpu *vcpu,u64 addr,bool direct);void kvm_init_shadow_mmu (struct kvm_vcpu *vcpu);void kvm_init_shadow_ept_mmu (struct kvm_vcpu *vcpu,bool execonly);bool kvm_can_do_async_pf (struct kvm_vcpu *vcpu);
arch/x86/kvm/vmx.c +3 -10
@@ -6556,16 +6556,9 @@ static int handle_ept_misconfig(struct k NULL, 0) == EMULATE_DONE; } - ret =handle_mmio_page_fault (vcpu, gpa, true); -if (likely (ret ==RET_MMIO_PF_EMULATE )) -return x86_emulate_instruction (vcpu, gpa,0 ,NULL ,0 ) == -EMULATE_DONE ; - -if (unlikely (ret ==RET_MMIO_PF_INVALID )) -return kvm_mmu_page_fault (vcpu, gpa,0 ,NULL ,0 ); - -if (unlikely (ret ==RET_MMIO_PF_RETRY )) -return 1 ; + ret =kvm_mmu_page_fault (vcpu, gpa,PFERR_RSVD_MASK ,NULL ,0 ); +if (ret >=0 ) +return ret;/* It is the real ept misconfig */ WARN_ON (1 );
Greg Kroah-Hartman
maintainerPATCH 17/31 KVM: x86: extend usage of RET_MMIO_PF_* constants
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 9b8ebbdb74b5ad76b9dfd8b101af17839174b126 upstream.
The x86 MMU if full of code that returns 0 and 1 for retry/emulate. Use the existing RET_MMIO_PF_RETRY/RET_MMIO_PF_EMULATE enum, renaming it to drop the MMIO part.
--- arch/x86/kvm/mmu.c | 93 +++++++++++++++++++++------------------------ arch/x86/kvm/paging_tmpl.h | 18 ++++---- 2 files changed, 54 insertions(+), 57 deletions(-)
arch/x86/kvm/mmu.c +45 -48
@@ -142,6 +142,20 @@ module_param(dbg, bool, 0644);/* make pte_list_desc fit well in cache line */ #define PTE_LIST_EXT 3 +/* +* Return values of handle_mmio_page_fault and mmu.page_fault: +* RET_PF_RETRY: let CPU fault again on the address. +* RET_PF_EMULATE: mmio page fault, emulate the instruction directly. +* +* For handle_mmio_page_fault only: +* RET_PF_INVALID: the spte is invalid, let the real page fault path update it. +*/ +enum { +RET_PF_RETRY =0 , +RET_PF_EMULATE =1 , +RET_PF_INVALID =2 , +}; +struct pte_list_desc {u64 *sptes[PTE_LIST_EXT ];struct pte_list_desc *more;
@@ -2598,13 +2612,13 @@ done:return ret; } -static bool mmu_set_spte (struct kvm_vcpu *vcpu,u64 *sptep,unsigned pte_access, -int write_fault,int level,gfn_t gfn,kvm_pfn_t pfn, -bool speculative,bool host_writable) +static int mmu_set_spte (struct kvm_vcpu *vcpu,u64 *sptep,unsigned pte_access, +int write_fault,int level,gfn_t gfn,kvm_pfn_t pfn, +bool speculative,bool host_writable) {int was_rmapped =0 ;int rmap_count; -bool emulate = false; +int ret =RET_PF_RETRY ;pgprintk ("%s: spte %llx write_fault %d gfn %llx\n" , __func__, *sptep, write_fault, gfn);
@@ -2634,12 +2648,12 @@ static bool mmu_set_spte(struct kvm_vcpuif (set_spte (vcpu, sptep, pte_access, level, gfn, pfn, speculative, true, host_writable)) {if (write_fault) - emulate = true; + ret =RET_PF_EMULATE ;kvm_make_request (KVM_REQ_TLB_FLUSH , vcpu); }if (unlikely (is_mmio_spte (*sptep))) - emulate = true; + ret =RET_PF_EMULATE ;pgprintk ("%s: setting spte %llx\n" , __func__, *sptep); pgprintk("instantiating %s PTE (%s) at %llx (%llx) addr %p\n",
@@ -2659,7 +2673,7 @@ static bool mmu_set_spte(struct kvm_vcpukvm_release_pfn_clean (pfn); -return emulate; +return ret; } static kvm_pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn,
@@ -2798,14 +2812,13 @@ static int kvm_handle_bad_page(struct kv* Do not cache the mmio info caused by writing the readonly gfn * into the spte otherwise read access on readonly gfn also can * caused mmio page fault and treat it as mmio access. -* Return 1 to tell kvm to emulate it. */ if (pfn ==KVM_PFN_ERR_RO_FAULT ) -return 1 ; +return RET_PF_EMULATE ;if (pfn ==KVM_PFN_ERR_HWPOISON ) {kvm_send_hwpoison_signal (kvm_vcpu_gfn_to_hva (vcpu, gfn), current); -return 0 ; +return RET_PF_RETRY ; }return -EFAULT ;
@@ -3031,13 +3044,13 @@ static int nonpaging_map(struct kvm_vcpu }if (fast_page_fault (vcpu, v, level, error_code)) -return 0 ; +return RET_PF_RETRY ; mmu_seq = vcpu->kvm->mmu_notifier_seq;smp_rmb ();if (try_async_pf (vcpu, prefault, gfn, v, &pfn, write, &map_writable)) -return 0 ; +return RET_PF_RETRY ;if (handle_abnormal_pfn (vcpu, v, gfn, pfn,ACC_ALL , &r))return r;
@@ -3056,7 +3069,7 @@ static int nonpaging_map(struct kvm_vcpu out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);kvm_release_pfn_clean (pfn); -return 0 ; +return RET_PF_RETRY ; }
@@ -3383,54 +3396,38 @@ exit:return reserved; } -/* -* Return values of handle_mmio_page_fault: -* RET_MMIO_PF_EMULATE: it is a real mmio page fault, emulate the instruction -* directly. -* RET_MMIO_PF_INVALID: invalid spte is detected then let the real page -* fault path update the mmio spte. -* RET_MMIO_PF_RETRY: let CPU fault again on the address. -* RET_MMIO_PF_BUG: a bug was detected (and a WARN was printed). -*/ -enum { -RET_MMIO_PF_EMULATE =1 , -RET_MMIO_PF_INVALID =2 , -RET_MMIO_PF_RETRY =0 , -RET_MMIO_PF_BUG =-1 -}; -static int handle_mmio_page_fault (struct kvm_vcpu *vcpu,u64 addr,bool direct) {u64 spte;bool reserved;if (mmio_info_in_cache (vcpu, addr, direct)) -return RET_MMIO_PF_EMULATE ; +return RET_PF_EMULATE ; reserved =walk_shadow_page_get_mmio_spte (vcpu, addr, &spte);if (WARN_ON (reserved)) -return RET_MMIO_PF_BUG ; +return -EINVAL ;if (is_mmio_spte (spte)) {gfn_t gfn =get_mmio_spte_gfn (spte);unsigned access =get_mmio_spte_access (spte);if (!check_mmio_spte (vcpu, spte)) -return RET_MMIO_PF_INVALID ; +return RET_PF_INVALID ;if (direct) addr =0 ;trace_handle_mmio_page_fault (addr, gfn, access);vcpu_cache_mmio_info (vcpu, addr, gfn, access); -return RET_MMIO_PF_EMULATE ; +return RET_PF_EMULATE ; }/* * If the page table is zapped by other cpus, let CPU fault again on * the address. */ -return RET_MMIO_PF_RETRY ; +return RET_PF_RETRY ; }EXPORT_SYMBOL_GPL (handle_mmio_page_fault);
@@ -3480,7 +3477,7 @@ static int nonpaging_page_fault(struct kpgprintk ("%s: gva %lx error %x\n" , __func__, gva, error_code);if (page_fault_handle_page_track (vcpu, error_code, gfn)) -return 1 ; +return RET_PF_EMULATE ; r =mmu_topup_memory_caches (vcpu);if (r)
@@ -3568,7 +3565,7 @@ static int tdp_page_fault(struct kvm_vcpMMU_WARN_ON (!VALID_PAGE (vcpu->arch.mmu.root_hpa));if (page_fault_handle_page_track (vcpu, error_code, gfn)) -return 1 ; +return RET_PF_EMULATE ; r =mmu_topup_memory_caches (vcpu);if (r)
@@ -3585,13 +3582,13 @@ static int tdp_page_fault(struct kvm_vcp }if (fast_page_fault (vcpu, gpa, level, error_code)) -return 0 ; +return RET_PF_RETRY ; mmu_seq = vcpu->kvm->mmu_notifier_seq;smp_rmb ();if (try_async_pf (vcpu, prefault, gfn, gpa, &pfn, write, &map_writable)) -return 0 ; +return RET_PF_RETRY ;if (handle_abnormal_pfn (vcpu,0 , gfn, pfn,ACC_ALL , &r))return r;
@@ -3610,7 +3607,7 @@ static int tdp_page_fault(struct kvm_vcp out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);kvm_release_pfn_clean (pfn); -return 0 ; +return RET_PF_RETRY ; } static void nonpaging_init_context(struct kvm_vcpu *vcpu,
@@ -4526,24 +4523,24 @@ int kvm_mmu_page_fault(struct kvm_vcpu *enum emulation_result er;bool direct = vcpu->arch.mmu.direct_map ||mmu_is_nested (vcpu); + r =RET_PF_INVALID ;if (unlikely (error_code &PFERR_RSVD_MASK )) { r =handle_mmio_page_fault (vcpu, cr2, direct); -if (r ==RET_MMIO_PF_EMULATE ) { +if (r ==RET_PF_EMULATE ) { emulation_type =0 ; goto emulate; } -if (r ==RET_MMIO_PF_RETRY ) -return 1 ; -if (r <0 ) -return r; -/* Must be RET_MMIO_PF_INVALID. */ } - r = vcpu->arch.mmu.page_fault (vcpu, cr2, error_code, false); +if (r ==RET_PF_INVALID ) { + r = vcpu->arch.mmu.page_fault (vcpu, cr2, error_code, false); +WARN_ON (r ==RET_PF_INVALID ); + } + +if (r ==RET_PF_RETRY ) +return 1 ;if (r <0 )return r; -if (!r) -return 1 ;if (mmio_info_in_cache (vcpu, cr2, direct)) emulation_type =0 ;
arch/x86/kvm/paging_tmpl.h +9 -9
@@ -577,7 +577,7 @@ static int FNAME(fetch)(struct kvm_vcpustruct kvm_mmu_page *sp =NULL ;struct kvm_shadow_walk_iterator it;unsigned direct_access, access = gw->pt_access; -int top_level, emulate; +int top_level, ret; direct_access = gw->pte_access;
@@ -643,15 +643,15 @@ static int FNAME(fetch)(struct kvm_vcpu }clear_sp_write_flooding_count (it.sptep); - emulate =mmu_set_spte (vcpu, it.sptep, gw->pte_access, write_fault, - it.level, gw->gfn, pfn, prefault, map_writable); + ret =mmu_set_spte (vcpu, it.sptep, gw->pte_access, write_fault, + it.level, gw->gfn, pfn, prefault, map_writable);FNAME (pte_prefetch)(vcpu, gw, it.sptep); -return emulate; +return ret; out_gpte_changed:kvm_release_pfn_clean (pfn); -return 0 ; +return RET_PF_RETRY ; }/*
@@ -746,12 +746,12 @@ static int FNAME(page_fault)(struct kvm_if (!prefault)inject_page_fault (vcpu, &walker.fault); -return 0 ; +return RET_PF_RETRY ; }if (page_fault_handle_page_track (vcpu, error_code, walker.gfn)) {shadow_page_table_clear_flood (vcpu, addr); -return 1 ; +return RET_PF_EMULATE ; } vcpu->arch.write_fault_to_shadow_pgtable = false;
@@ -773,7 +773,7 @@ static int FNAME(page_fault)(struct kvm_if (try_async_pf (vcpu, prefault, walker.gfn, addr, &pfn, write_fault, &map_writable)) -return 0 ; +return RET_PF_RETRY ;if (handle_abnormal_pfn (vcpu,mmu_is_nested (vcpu) ?0 : addr, walker.gfn, pfn, walker.pte_access, &r))
@@ -818,7 +818,7 @@ static int FNAME(page_fault)(struct kvm_ out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);kvm_release_pfn_clean (pfn); -return 0 ; +return RET_PF_RETRY ; }static gpa_t FNAME (get_level1_sp_gpa )(struct kvm_mmu_page *sp)
Greg Kroah-Hartman
maintainerPATCH 18/31 kvm: Convert kvm_lock to a mutex
In reply to Greg Kroah-HartmanFrom: Junaid Shahid <[email protected]>
commit 0d9ce162cf46c99628cc5da9510b959c7976735b upstream.
It doesn't seem as if there is any particular need for kvm_lock to be a spinlock, so convert the lock to a mutex so that sleepable functions (in particular cond_resched()) can be called while holding it.
[bwh: Backported to 4.9:
- Drop changes in kvm_hyperv_tsc_notifier(), vm_stat_clear(), vcpu_stat_clear(), kvm_uevent_notify_change()
- Adjust context]
--- Documentation/virtual/kvm/locking.txt | 6 +++--- arch/s390/kvm/kvm-s390.c | 4 ++-- arch/x86/kvm/mmu.c | 4 ++-- arch/x86/kvm/x86.c | 10 +++++----- include/linux/kvm_host.h | 2 +- virt/kvm/kvm_main.c | 18 +++++++++--------- 6 files changed, 22 insertions(+), 22 deletions(-)
Documentation/virtual/kvm/locking.txt +3 -3
@@ -13,8 +13,8 @@ The acquisition orders for mutexes are a - kvm->slots_lock is taken outside kvm->irq_lock, though acquiring them together is quite rare. -For spinlocks, kvm_lock is taken outside kvm->mmu_lock. Everything -else is a leaf: no other lock is taken inside the critical sections. +Everything else is a leaf: no other lock is taken inside the critical +sections. 2: Exception ------------
@@ -142,7 +142,7 @@ See the comments in spte_has_volatile_bi ------------ Name: kvm_lock -Type: spinlock_t +Type: mutex Arch: any Protects: - vm_list
arch/s390/kvm/kvm-s390.c +2 -2
@@ -1422,13 +1422,13 @@ int kvm_arch_init_vm(struct kvm *kvm, un kvm->arch.sca = (struct bsca_block *)get_zeroed_page (alloc_flags);if (!kvm->arch.sca) goto out_err; -spin_lock (&kvm_lock); +mutex_lock (&kvm_lock); sca_offset +=16 ;if (sca_offset +sizeof (struct bsca_block ) >PAGE_SIZE ) sca_offset =0 ; kvm->arch.sca = (struct bsca_block *) ((char *) kvm->arch.sca + sca_offset); -spin_unlock (&kvm_lock); +mutex_unlock (&kvm_lock);sprintf (debug_name,"kvm-%u" , current->pid);
arch/x86/kvm/mmu.c +2 -2
@@ -4979,7 +4979,7 @@ mmu_shrink_scan(struct shrinker *shrink,int nr_to_scan = sc->nr_to_scan;unsigned long freed =0 ; -spin_lock (&kvm_lock); +mutex_lock (&kvm_lock);list_for_each_entry (kvm, &vm_list, vm_list) {int idx;
@@ -5029,7 +5029,7 @@ unlock:break ; } -spin_unlock (&kvm_lock); +mutex_unlock (&kvm_lock);return freed; }
arch/x86/kvm/x86.c +5 -5
@@ -5978,17 +5978,17 @@ static int kvmclock_cpufreq_notifier(strsmp_call_function_single (freq->cpu, tsc_khz_changed, freq,1 ); -spin_lock (&kvm_lock); +mutex_lock (&kvm_lock);list_for_each_entry (kvm, &vm_list, vm_list) {kvm_for_each_vcpu (i, vcpu, kvm) {if (vcpu->cpu != freq->cpu)continue ;kvm_make_request (KVM_REQ_CLOCK_UPDATE , vcpu); -if (vcpu->cpu !=smp_processor_id ()) +if (vcpu->cpu !=raw_smp_processor_id ()) send_ipi =1 ; } } -spin_unlock (&kvm_lock); +mutex_unlock (&kvm_lock);if (freq->old < freq->new && send_ipi) {/*
@@ -6126,12 +6126,12 @@ static void pvclock_gtod_update_fn(strucstruct kvm_vcpu *vcpu;int i; -spin_lock (&kvm_lock); +mutex_lock (&kvm_lock);list_for_each_entry (kvm, &vm_list, vm_list)kvm_for_each_vcpu (i, vcpu, kvm)kvm_make_request (KVM_REQ_MASTERCLOCK_UPDATE , vcpu);atomic_set (&kvm_guest_has_master_clock,0 ); -spin_unlock (&kvm_lock); +mutex_unlock (&kvm_lock); } static DECLARE_WORK(pvclock_gtod_work, pvclock_gtod_update_fn);
include/linux/kvm_host.h +1 -1
@@ -129,7 +129,7 @@ static inline bool is_error_page(structextern struct kmem_cache *kvm_vcpu_cache; -extern spinlock_t kvm_lock; +extern struct mutex kvm_lock;extern struct list_head vm_list;struct kvm_io_range {
virt/kvm/kvm_main.c +9 -9
@@ -87,7 +87,7 @@ module_param(halt_poll_ns_shrink, uint,* kvm->lock --> kvm->slots_lock --> kvm->irq_lock */ -DEFINE_SPINLOCK (kvm_lock); +DEFINE_MUTEX (kvm_lock);static DEFINE_RAW_SPINLOCK (kvm_count_lock);LIST_HEAD (vm_list);
@@ -666,9 +666,9 @@ static struct kvm *kvm_create_vm(unsigneif (r) goto out_err; -spin_lock (&kvm_lock); +mutex_lock (&kvm_lock);list_add (&kvm->vm_list, &vm_list); -spin_unlock (&kvm_lock); +mutex_unlock (&kvm_lock);preempt_notifier_inc ();
@@ -724,9 +724,9 @@ static void kvm_destroy_vm(struct kvm *kkvm_destroy_vm_debugfs (kvm);kvm_arch_sync_events (kvm); -spin_lock (&kvm_lock); +mutex_lock (&kvm_lock);list_del (&kvm->vm_list); -spin_unlock (&kvm_lock); +mutex_unlock (&kvm_lock);kvm_free_irq_routing (kvm);for (i =0 ; i <KVM_NR_BUSES ; i++) {if (kvm->buses[i])
@@ -3752,13 +3752,13 @@ static int vm_stat_get(void *_offset, u6u64 tmp_val; *val =0 ; -spin_lock (&kvm_lock); +mutex_lock (&kvm_lock);list_for_each_entry (kvm, &vm_list, vm_list) { stat_tmp.kvm = kvm;vm_stat_get_per_vm ((void *)&stat_tmp, &tmp_val); *val += tmp_val; } -spin_unlock (&kvm_lock); +mutex_unlock (&kvm_lock);return 0 ; }
@@ -3772,13 +3772,13 @@ static int vcpu_stat_get(void *_offset,u64 tmp_val; *val =0 ; -spin_lock (&kvm_lock); +mutex_lock (&kvm_lock);list_for_each_entry (kvm, &vm_list, vm_list) { stat_tmp.kvm = kvm;vcpu_stat_get_per_vm ((void *)&stat_tmp, &tmp_val); *val += tmp_val; } -spin_unlock (&kvm_lock); +mutex_unlock (&kvm_lock);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 19/31 kvm: x86: Do not release the page inside mmu_set_spte()
In reply to Greg Kroah-HartmanFrom: Junaid Shahid <[email protected]>
commit 43fdcda96e2550c6d1c46fb8a78801aa2f7276ed upstream.
Release the page at the call-site where it was originally acquired. This makes the exit code cleaner for most call sites, since they do not need to duplicate code between success and the failure label.
--- arch/x86/kvm/mmu.c | 18 +++++++----------- arch/x86/kvm/paging_tmpl.h | 8 +++----- 2 files changed, 10 insertions(+), 16 deletions(-)
arch/x86/kvm/mmu.c +7 -11
@@ -2671,8 +2671,6 @@ static int mmu_set_spte(struct kvm_vcpu } } -kvm_release_pfn_clean (pfn); -return ret; }
@@ -2707,9 +2705,11 @@ static int direct_pte_prefetch_many(struif (ret <=0 )return -1 ; -for (i =0 ; i < ret; i++, gfn++, start++) +for (i =0 ; i < ret; i++, gfn++, start++) {mmu_set_spte (vcpu, start, access,0 , sp->role.level, gfn,page_to_pfn (pages[i]), true, true); +put_page (pages[i]); + }return 0 ; }
@@ -3055,6 +3055,7 @@ static int nonpaging_map(struct kvm_vcpuif (handle_abnormal_pfn (vcpu, v, gfn, pfn,ACC_ALL , &r))return r; + r =RET_PF_RETRY ;spin_lock (&vcpu->kvm->mmu_lock);if (mmu_notifier_retry (vcpu->kvm, mmu_seq)) goto out_unlock;
@@ -3062,14 +3063,11 @@ static int nonpaging_map(struct kvm_vcpuif (likely (!force_pt_level))transparent_hugepage_adjust (vcpu, &gfn, &pfn, &level); r =__direct_map (vcpu, write, map_writable, level, gfn, pfn, prefault); -spin_unlock (&vcpu->kvm->mmu_lock); - -return r; out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);kvm_release_pfn_clean (pfn); -return RET_PF_RETRY ; +return r; }
@@ -3593,6 +3591,7 @@ static int tdp_page_fault(struct kvm_vcpif (handle_abnormal_pfn (vcpu,0 , gfn, pfn,ACC_ALL , &r))return r; + r =RET_PF_RETRY ;spin_lock (&vcpu->kvm->mmu_lock);if (mmu_notifier_retry (vcpu->kvm, mmu_seq)) goto out_unlock;
@@ -3600,14 +3599,11 @@ static int tdp_page_fault(struct kvm_vcpif (likely (!force_pt_level))transparent_hugepage_adjust (vcpu, &gfn, &pfn, &level); r =__direct_map (vcpu, write, map_writable, level, gfn, pfn, prefault); -spin_unlock (&vcpu->kvm->mmu_lock); - -return r; out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);kvm_release_pfn_clean (pfn); -return RET_PF_RETRY ; +return r; } static void nonpaging_init_context(struct kvm_vcpu *vcpu,
arch/x86/kvm/paging_tmpl.h +3 -5
@@ -499,6 +499,7 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcmmu_set_spte (vcpu, spte, pte_access,0 ,PT_PAGE_TABLE_LEVEL , gfn, pfn, true, true); +kvm_release_pfn_clean (pfn);return true; }
@@ -650,7 +651,6 @@ static int FNAME(fetch)(struct kvm_vcpureturn ret; out_gpte_changed: -kvm_release_pfn_clean (pfn);return RET_PF_RETRY ; }
@@ -799,6 +799,7 @@ static int FNAME(page_fault)(struct kvm_ walker.pte_access &= ~ACC_EXEC_MASK ; } + r =RET_PF_RETRY ;spin_lock (&vcpu->kvm->mmu_lock);if (mmu_notifier_retry (vcpu->kvm, mmu_seq)) goto out_unlock;
@@ -811,14 +812,11 @@ static int FNAME(page_fault)(struct kvm_ level, pfn, map_writable, prefault); ++vcpu->stat.pf_fixed;kvm_mmu_audit (vcpu,AUDIT_POST_PAGE_FAULT ); -spin_unlock (&vcpu->kvm->mmu_lock); - -return r; out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);kvm_release_pfn_clean (pfn); -return RET_PF_RETRY ; +return r; }static gpa_t FNAME (get_level1_sp_gpa )(struct kvm_mmu_page *sp)
Greg Kroah-Hartman
maintainerPATCH 20/31 KVM: x86: make FNAME(fetch) and __direct_map more similar
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 3fcf2d1bdeb6a513523cb2c77012a6b047aa859c upstream.
These two functions are basically doing the same thing through kvm_mmu_get_page, link_shadow_page and mmu_set_spte; yet, for historical reasons, their code looks very different. This patch tries to take the best of each and make them very similar, so that it is easy to understand changes that apply to both of them.
--- arch/x86/kvm/mmu.c | 53 +++++++++++++++++++++------------------------ arch/x86/kvm/paging_tmpl.h | 30 +++++++++++-------------- 2 files changed, 39 insertions(+), 44 deletions(-)
arch/x86/kvm/mmu.c +25 -28
@@ -2757,40 +2757,39 @@ static void direct_pte_prefetch(struct k__direct_pte_prefetch (vcpu, sp, sptep); } -static int __direct_map (struct kvm_vcpu *vcpu,int write,int map_writable, -int level,gfn_t gfn,kvm_pfn_t pfn,bool prefault) +static int __direct_map (struct kvm_vcpu *vcpu,gpa_t gpa,int write, +int map_writable,int level,kvm_pfn_t pfn, +bool prefault) { -struct kvm_shadow_walk_iterator iterator; +struct kvm_shadow_walk_iterator it;struct kvm_mmu_page *sp; -int emulate =0 ; -gfn_t pseudo_gfn; +int ret; +gfn_t gfn = gpa >>PAGE_SHIFT ; +gfn_t base_gfn = gfn;if (!VALID_PAGE (vcpu->arch.mmu.root_hpa)) -return 0 ; +return RET_PF_RETRY ; -for_each_shadow_entry (vcpu, (u64 )gfn <<PAGE_SHIFT , iterator) { -if (iterator.level == level) { - emulate =mmu_set_spte (vcpu, iterator.sptep,ACC_ALL , - write, level, gfn, pfn, prefault, - map_writable); -direct_pte_prefetch (vcpu, iterator.sptep); - ++vcpu->stat.pf_fixed; +for_each_shadow_entry (vcpu, gpa, it) { + base_gfn = gfn & ~(KVM_PAGES_PER_HPAGE (it.level) -1 ); +if (it.level == level)break ; - } -drop_large_spte (vcpu, iterator.sptep); -if (!is_shadow_present_pte (*iterator.sptep)) { -u64 base_addr = iterator.addr; - - base_addr &=PT64_LVL_ADDR_MASK (iterator.level); - pseudo_gfn = base_addr >>PAGE_SHIFT ; - sp =kvm_mmu_get_page (vcpu, pseudo_gfn, iterator.addr, - iterator.level -1 ,1 ,ACC_ALL ); +drop_large_spte (vcpu, it.sptep); +if (!is_shadow_present_pte (*it.sptep)) { + sp =kvm_mmu_get_page (vcpu, base_gfn, it.addr, + it.level -1 , true,ACC_ALL ); -link_shadow_page (vcpu, iterator.sptep, sp); +link_shadow_page (vcpu, it.sptep, sp); } } -return emulate; + + ret =mmu_set_spte (vcpu, it.sptep,ACC_ALL , + write, level, base_gfn, pfn, prefault, + map_writable); +direct_pte_prefetch (vcpu, it.sptep); + ++vcpu->stat.pf_fixed; +return ret; }static void kvm_send_hwpoison_signal (unsigned long address,struct task_struct *tsk)
@@ -3062,8 +3061,7 @@ static int nonpaging_map(struct kvm_vcpumake_mmu_pages_available (vcpu);if (likely (!force_pt_level))transparent_hugepage_adjust (vcpu, &gfn, &pfn, &level); - r =__direct_map (vcpu, write, map_writable, level, gfn, pfn, prefault); - + r =__direct_map (vcpu, v, write, map_writable, level, pfn, prefault); out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);kvm_release_pfn_clean (pfn);
@@ -3598,8 +3596,7 @@ static int tdp_page_fault(struct kvm_vcpmake_mmu_pages_available (vcpu);if (likely (!force_pt_level))transparent_hugepage_adjust (vcpu, &gfn, &pfn, &level); - r =__direct_map (vcpu, write, map_writable, level, gfn, pfn, prefault); - + r =__direct_map (vcpu, gpa, write, map_writable, level, pfn, prefault); out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);kvm_release_pfn_clean (pfn);
arch/x86/kvm/paging_tmpl.h +14 -16
@@ -579,6 +579,7 @@ static int FNAME(fetch)(struct kvm_vcpustruct kvm_shadow_walk_iterator it;unsigned direct_access, access = gw->pt_access;int top_level, ret; +gfn_t base_gfn; direct_access = gw->pte_access;
@@ -623,31 +624,29 @@ static int FNAME(fetch)(struct kvm_vcpulink_shadow_page (vcpu, it.sptep, sp); } -for (; -shadow_walk_okay (&it) && it.level > hlevel; -shadow_walk_next (&it)) { -gfn_t direct_gfn; + base_gfn = gw->gfn; +for (;shadow_walk_okay (&it);shadow_walk_next (&it)) {clear_sp_write_flooding_count (it.sptep); + base_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE (it.level) -1 ); +if (it.level == hlevel) +break ; +validate_direct_spte (vcpu, it.sptep, direct_access);drop_large_spte (vcpu, it.sptep); -if (is_shadow_present_pte (*it.sptep)) -continue ; - - direct_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE (it.level) -1 ); - - sp =kvm_mmu_get_page (vcpu, direct_gfn, addr, it.level-1 , - true, direct_access); -link_shadow_page (vcpu, it.sptep, sp); +if (!is_shadow_present_pte (*it.sptep)) { + sp =kvm_mmu_get_page (vcpu, base_gfn, addr, + it.level -1 , true, direct_access); +link_shadow_page (vcpu, it.sptep, sp); + } } -clear_sp_write_flooding_count (it.sptep); ret =mmu_set_spte (vcpu, it.sptep, gw->pte_access, write_fault, - it.level, gw->gfn, pfn, prefault, map_writable); + it.level, base_gfn, pfn, prefault, map_writable);FNAME (pte_prefetch)(vcpu, gw, it.sptep); - + ++vcpu->stat.pf_fixed;return ret; out_gpte_changed:
@@ -810,7 +809,6 @@ static int FNAME(page_fault)(struct kvm_transparent_hugepage_adjust (vcpu, &walker.gfn, &pfn, &level); r =FNAME (fetch)(vcpu, addr, &walker, write_fault, level, pfn, map_writable, prefault); - ++vcpu->stat.pf_fixed;kvm_mmu_audit (vcpu,AUDIT_POST_PAGE_FAULT ); out_unlock:
Greg Kroah-Hartman
maintainerPATCH 21/31 KVM: x86: remove now unneeded hugepage gfn adjustment
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit d679b32611c0102ce33b9e1a4e4b94854ed1812a upstream.
After the previous patch, the low bits of the gfn are masked in both FNAME(fetch) and __direct_map, so we do not need to clear them in transparent_hugepage_adjust.
--- arch/x86/kvm/mmu.c | 9 +++------ arch/x86/kvm/paging_tmpl.h | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-)
arch/x86/kvm/mmu.c +3 -6
@@ -2824,11 +2824,10 @@ static int kvm_handle_bad_page(struct kv }static void transparent_hugepage_adjust (struct kvm_vcpu *vcpu, -gfn_t *gfnp,kvm_pfn_t *pfnp, +gfn_t gfn,kvm_pfn_t *pfnp,int *levelp) {kvm_pfn_t pfn = *pfnp; -gfn_t gfn = *gfnp;int level = *levelp;/*
@@ -2855,8 +2854,6 @@ static void transparent_hugepage_adjust( mask =KVM_PAGES_PER_HPAGE (level) -1 ;VM_BUG_ON ((gfn & mask) != (pfn & mask));if (pfn & mask) { - gfn &= ~mask; - *gfnp = gfn;kvm_release_pfn_clean (pfn); pfn &= ~mask;kvm_get_pfn (pfn);
@@ -3060,7 +3057,7 @@ static int nonpaging_map(struct kvm_vcpu goto out_unlock;make_mmu_pages_available (vcpu);if (likely (!force_pt_level)) -transparent_hugepage_adjust (vcpu, &gfn, &pfn, &level); +transparent_hugepage_adjust (vcpu, gfn, &pfn, &level); r =__direct_map (vcpu, v, write, map_writable, level, pfn, prefault); out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);
@@ -3595,7 +3592,7 @@ static int tdp_page_fault(struct kvm_vcp goto out_unlock;make_mmu_pages_available (vcpu);if (likely (!force_pt_level)) -transparent_hugepage_adjust (vcpu, &gfn, &pfn, &level); +transparent_hugepage_adjust (vcpu, gfn, &pfn, &level); r =__direct_map (vcpu, gpa, write, map_writable, level, pfn, prefault); out_unlock:spin_unlock (&vcpu->kvm->mmu_lock);
arch/x86/kvm/paging_tmpl.h +1 -1
@@ -806,7 +806,7 @@ static int FNAME(page_fault)(struct kvm_kvm_mmu_audit (vcpu,AUDIT_PRE_PAGE_FAULT );make_mmu_pages_available (vcpu);if (!force_pt_level) -transparent_hugepage_adjust (vcpu, &walker.gfn, &pfn, &level); +transparent_hugepage_adjust (vcpu, walker.gfn, &pfn, &level); r =FNAME (fetch)(vcpu, addr, &walker, write_fault, level, pfn, map_writable, prefault);kvm_mmu_audit (vcpu,AUDIT_POST_PAGE_FAULT );
Greg Kroah-Hartman
maintainerPATCH 22/31 KVM: x86: change kvm_mmu_page_get_gfn BUG_ON to WARN_ON
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit e9f2a760b158551bfbef6db31d2cae45ab8072e5 upstream.
Note that in such a case it is quite likely that KVM will BUG_ON in __pte_list_remove when the VM is closed. However, there is no immediate risk of memory corruption in the host so a WARN_ON is enough and it lets you gather traces for debugging.
--- arch/x86/kvm/mmu.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
arch/x86/kvm/mmu.c +9 -3
@@ -781,10 +781,16 @@ static gfn_t kvm_mmu_page_get_gfn(structstatic void kvm_mmu_page_set_gfn (struct kvm_mmu_page *sp,int index,gfn_t gfn) { -if (sp->role.direct) -BUG_ON (gfn !=kvm_mmu_page_get_gfn (sp, index)); -else +if (!sp->role.direct) { sp->gfns[index] = gfn; +return ; + } + +if (WARN_ON (gfn !=kvm_mmu_page_get_gfn (sp, index))) +pr_err_ratelimited ("gfn mismatch under direct page %llx " +"(expected %llx, got %llx)\n" , + sp->gfn, +kvm_mmu_page_get_gfn (sp, index), gfn); }/*
Greg Kroah-Hartman
maintainerPATCH 23/31 KVM: x86: Add is_executable_pte()
In reply to Greg Kroah-HartmanFrom: Ben Hutchings <[email protected]>
Extracted from commit d3e328f2cb01 "kvm: x86: mmu: Verify that restored PTE has needed perms in fast page fault".
--- arch/x86/kvm/mmu.c | 5 +++++ 1 file changed, 5 insertions(+)
arch/x86/kvm/mmu.c +5 -0
@@ -338,6 +338,11 @@ static int is_last_spte(u64 pte, int levreturn 0 ; } +static bool is_executable_pte (u64 spte) +{ +return (spte & (shadow_x_mask | shadow_nx_mask)) == shadow_x_mask; +} +static kvm_pfn_t spte_to_pfn (u64 pte) {return (pte &PT64_BASE_ADDR_MASK ) >>PAGE_SHIFT ;
Greg Kroah-Hartman
maintainerPATCH 24/31 KVM: x86: add tracepoints around __direct_map and FNAME(fetch)
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 335e192a3fa415e1202c8b9ecdaaecd643f823cc upstream.
These are useful in debugging shadow paging.
[bwh: Backported to 4.9:
- Keep using PT_PRESENT_MASK to test page write permission
- Adjust context]
--- arch/x86/kvm/mmu.c | 13 ++++----- arch/x86/kvm/mmutrace.h | 59 +++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/paging_tmpl.h | 2 + 3 files changed, 67 insertions(+), 7 deletions(-)
arch/x86/kvm/mmu.c +6 -7
@@ -131,9 +131,6 @@ module_param(dbg, bool, 0644);#include <trace/events/kvm.h> -#define CREATE_TRACE_POINTS -#include "mmutrace.h" -#define SPTE_HOST_WRITEABLE (1ULL << PT_FIRST_AVAIL_BITS_SHIFT)#define SPTE_MMU_WRITEABLE (1ULL << (PT_FIRST_AVAIL_BITS_SHIFT + 1))
@@ -193,8 +190,12 @@ static u64 __read_mostly shadow_mmio_masstatic u64 __read_mostly shadow_present_mask;static void mmu_spte_set (u64 *sptep,u64 spte); +static bool is_executable_pte (u64 spte);static void mmu_free_roots (struct kvm_vcpu *vcpu); +#define CREATE_TRACE_POINTS +#include "mmutrace.h" +void kvm_mmu_set_mmio_spte_mask (u64 mmio_mask) { shadow_mmio_mask = mmio_mask;
@@ -2667,10 +2668,7 @@ static int mmu_set_spte(struct kvm_vcpu ret =RET_PF_EMULATE ;pgprintk ("%s: setting spte %llx\n" , __func__, *sptep); -pgprintk ("instantiating %s PTE (%s) at %llx (%llx) addr %p\n" , -is_large_pte (*sptep)?"2MB" :"4kB" , - *sptep &PT_PRESENT_MASK ?"RW" :"R" , gfn, - *sptep, sptep); +trace_kvm_mmu_set_spte (level, gfn, sptep);if (!was_rmapped &&is_large_pte (*sptep)) ++vcpu->kvm->stat.lpages;
@@ -2781,6 +2779,7 @@ static int __direct_map(struct kvm_vcpuif (!VALID_PAGE (vcpu->arch.mmu.root_hpa))return RET_PF_RETRY ; +trace_kvm_mmu_spte_requested (gpa, level, pfn);for_each_shadow_entry (vcpu, gpa, it) { base_gfn = gfn & ~(KVM_PAGES_PER_HPAGE (it.level) -1 );if (it.level == level)
arch/x86/kvm/mmutrace.h +59 -0
65 lines not on this page · raw message
arch/x86/kvm/paging_tmpl.h +2 -0
@@ -626,6 +626,8 @@ static int FNAME(fetch)(struct kvm_vcpu base_gfn = gw->gfn; +trace_kvm_mmu_spte_requested (addr, gw->level, pfn); +for (;shadow_walk_okay (&it);shadow_walk_next (&it)) {clear_sp_write_flooding_count (it.sptep); base_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE (it.level) -1 );
Greg Kroah-Hartman
maintainerPATCH 25/31 KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is active
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 9167ab79936206118cc60e47dcb926c3489f3bd5 upstream.
VMX already does so if the host has SMEP, in order to support the combination of CR0.WP=1 and CR4.SMEP=1. However, it is perfectly safe to always do so, and in fact VMX already ends up running with EFER.NXE=1 on old processors that lack the "load EFER" controls, because it may help avoiding a slow MSR write. Removing all the conditionals simplifies the code.
SVM does not have similar code, but it should since recent AMD processors do support SMEP. So this patch also makes the code for the two vendors more similar while fixing NPT=0, CR0.WP=1 and CR4.SMEP=1 on AMD processors.
--- arch/x86/kvm/svm.c | 10 ++++++++-- arch/x86/kvm/vmx.c | 14 +++----------- 2 files changed, 11 insertions(+), 13 deletions(-)
arch/x86/kvm/svm.c +8 -2
@@ -590,8 +590,14 @@ static int get_npt_level(void)static void svm_set_efer (struct kvm_vcpu *vcpu,u64 efer) { vcpu->arch.efer = efer; -if (!npt_enabled && !(efer &EFER_LMA )) - efer &= ~EFER_LME ; + +if (!npt_enabled) { +/* Shadow paging assumes NX to be available. */ + efer |=EFER_NX ; + +if (!(efer &EFER_LMA )) + efer &= ~EFER_LME ; + }to_svm (vcpu)->vmcb->save.efer = efer |EFER_SVME ;mark_dirty (to_svm (vcpu)->vmcb,VMCB_CR );
arch/x86/kvm/vmx.c +3 -11
@@ -2219,17 +2219,9 @@ static bool update_transition_efer(strucu64 guest_efer = vmx->vcpu.arch.efer;u64 ignore_bits =0 ; -if (!enable_ept) { -/* -* NX is needed to handle CR0.WP=1, CR4.SMEP=1. Testing -* host CPUID is more efficient than testing guest CPUID -* or CR4. Host SMEP is anyway a requirement for guest SMEP. -*/ -if (boot_cpu_has (X86_FEATURE_SMEP )) - guest_efer |=EFER_NX ; -else if (!(guest_efer &EFER_NX )) - ignore_bits |=EFER_NX ; - } +/* Shadow paging assumes NX to be available. */ +if (!enable_ept) + guest_efer |=EFER_NX ;/* * LMA and LME handled by hardware; SCE meaningless outside long mode.
Greg Kroah-Hartman
maintainerPATCH 26/31 x86/bugs: Add ITLB_MULTIHIT bug infrastructure
In reply to Greg Kroah-HartmanFrom: Vineela Tummalapalli <[email protected]>
commit db4d30fbb71b47e4ecb11c4efa5d8aad4b03dfae upstream.
Some processors may incur a machine check error possibly resulting in an unrecoverable CPU lockup when an instruction fetch encounters a TLB multi-hit in the instruction TLB. This can occur when the page size is changed along with either the physical address or cache type. The relevant erratum can be found here:
https://bugzilla.kernel.org/show_bug.cgi?id=205195
There are other processors affected for which the erratum does not fully disclose the impact.
This issue affects both bare-metal x86 page tables and EPT.
It can be mitigated by either eliminating the use of large pages or by using careful TLB invalidations when changing the page size in the page tables.
Just like Spectre, Meltdown, L1TF and MDS, a new bit has been allocated in MSR_IA32_ARCH_CAPABILITIES (PSCHANGE_MC_NO) and will be set on CPUs which are mitigated against this issue.
[bwh: Backported to 4.9:
- No support for X86_VENDOR_HYGON, ATOM_AIRMONT_NP
- Adjust context, indentation]
--- Documentation/ABI/testing/sysfs-devices-system-cpu | 1 arch/x86/include/asm/cpufeatures.h | 1 arch/x86/include/asm/msr-index.h | 7 ++ arch/x86/kernel/cpu/bugs.c | 13 ++++ arch/x86/kernel/cpu/common.c | 61 +++++++++++---------- drivers/base/cpu.c | 8 ++ include/linux/cpu.h | 2 7 files changed, 65 insertions(+), 28 deletions(-)
Documentation/ABI/testing/sysfs-devices-system-cpu +1 -0
@@ -359,6 +359,7 @@ What: /sys/devices/system/cpu/vulnerabi /sys/devices/system/cpu/vulnerabilities/l1tf /sys/devices/system/cpu/vulnerabilities/mds /sys/devices/system/cpu/vulnerabilities/tsx_async_abort + /sys/devices/system/cpu/vulnerabilities/itlb_multihit Date: January 2018 Contact: Linux kernel mailing list <[email protected]> Description: Information about CPU vulnerabilities
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -358,5 +358,6 @@#define X86_BUG_MSBDS_ONLY X86_BUG(20)/* CPU is only affected by the MSDBS variant of BUG_MDS */ #define X86_BUG_SWAPGS X86_BUG(21)/* CPU is affected by speculation through SWAPGS */ #define X86_BUG_TAA X86_BUG(22)/* CPU is affected by TSX Async Abort(TAA) */ +#define X86_BUG_ITLB_MULTIHIT X86_BUG(23)/* CPU may incur MCE during certain page attribute changes */ #endif /* _ASM_X86_CPUFEATURES_H */
arch/x86/include/asm/msr-index.h +7 -0
@@ -77,6 +77,13 @@* Microarchitectural Data * Sampling (MDS) vulnerabilities. */ +#define ARCH_CAP_PSCHANGE_MC_NO BIT(6)/* +* The processor is not susceptible to a +* machine check error due to modifying the +* code page size along with either the +* physical address or cache type +* without TLB invalidation. +*/ #define ARCH_CAP_TSX_CTRL_MSR BIT(7)/* MSR for TSX control is available. */ #define ARCH_CAP_TAA_NO BIT(8)/* * Not susceptible to
arch/x86/kernel/cpu/bugs.c +13 -0
@@ -1395,6 +1395,11 @@ static ssize_t l1tf_show_state(char *buf }#endif +static ssize_t itlb_multihit_show_state (char *buf) +{ +return sprintf (buf,"Processor vulnerable\n" ); +} +static ssize_t mds_show_state (char *buf) {#ifdef CONFIG_HYPERVISOR_GUEST
@@ -1497,6 +1502,9 @@ static ssize_t cpu_show_common(struct decase X86_BUG_TAA :return tsx_async_abort_show_state (buf); +case X86_BUG_ITLB_MULTIHIT : +return itlb_multihit_show_state (buf); +default :break ; }
@@ -1538,4 +1546,9 @@ ssize_t cpu_show_tsx_async_abort(struct {return cpu_show_common (dev, attr, buf,X86_BUG_TAA ); } + +ssize_t cpu_show_itlb_multihit (struct device *dev,struct device_attribute *attr,char *buf) +{ +return cpu_show_common (dev, attr, buf,X86_BUG_ITLB_MULTIHIT ); +}#endif
arch/x86/kernel/cpu/common.c +33 -28
91 lines not on this page · raw message
drivers/base/cpu.c +8 -0
@@ -544,6 +544,12 @@ ssize_t __weak cpu_show_tsx_async_abort(return sprintf (buf,"Not affected\n" ); } +ssize_t __weak cpu_show_itlb_multihit (struct device *dev, +struct device_attribute *attr,char *buf) +{ +return sprintf (buf,"Not affected\n" ); +} + static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
@@ -551,6 +557,7 @@ static DEVICE_ATTR(spec_store_bypass, 04 static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL); static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL); static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL); +static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr,
@@ -560,6 +567,7 @@ static struct attribute *cpu_root_vulner &dev_attr_l1tf.attr, &dev_attr_mds.attr, &dev_attr_tsx_async_abort.attr, + &dev_attr_itlb_multihit.attr, NULL };
include/linux/cpu.h +2 -0
@@ -59,6 +59,8 @@ extern ssize_t cpu_show_mds(struct devicextern ssize_t cpu_show_tsx_async_abort (struct device *dev,struct device_attribute *attr,char *buf); +extern ssize_t cpu_show_itlb_multihit (struct device *dev, +struct device_attribute *attr,char *buf); extern __printf(4, 5) struct device *cpu_device_create(struct device *parent, void *drvdata,
Greg Kroah-Hartman
maintainerPATCH 27/31 cpu/speculation: Uninline and export CPU mitigations helpers
In reply to Greg Kroah-HartmanFrom: Tyler Hicks <[email protected]>
commit 731dc9df975a5da21237a18c3384f811a7a41cc6 upstream.
A kernel module may need to check the value of the "mitigations=" kernel command line parameter as part of its setup when the module needs to perform software mitigations for a CPU flaw.
Uninline and export the helper functions surrounding the cpu_mitigations enum to allow for their usage from a module.
Lastly, privatize the enum and cpu_mitigations variable since the value of cpu_mitigations can be checked with the exported helper functions.
--- include/linux/cpu.h | 25 ++----------------------- kernel/cpu.c | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 24 deletions(-)
include/linux/cpu.h +2 -23
@@ -287,28 +287,7 @@ static inline int cpuhp_smt_enable(void)static inline int cpuhp_smt_disable (enum cpuhp_smt_control ctrlval) {return 0 ; }#endif -/* -* These are used for a global "mitigations=" cmdline option for toggling -* optional CPU mitigations. -*/ -enum cpu_mitigations { -CPU_MITIGATIONS_OFF , -CPU_MITIGATIONS_AUTO , -CPU_MITIGATIONS_AUTO_NOSMT , -}; - -extern enum cpu_mitigations cpu_mitigations; - -/* mitigations=off */ -static inline bool cpu_mitigations_off (void ) -{ -return cpu_mitigations ==CPU_MITIGATIONS_OFF ; -} - -/* mitigations=auto,nosmt */ -static inline bool cpu_mitigations_auto_nosmt (void ) -{ -return cpu_mitigations ==CPU_MITIGATIONS_AUTO_NOSMT ; -} +extern bool cpu_mitigations_off (void ); +extern bool cpu_mitigations_auto_nosmt (void );#endif /* _LINUX_CPU_H_ */
kernel/cpu.c +26 -1
@@ -2235,7 +2235,18 @@ void __init boot_cpu_hotplug_init(void)this_cpu_write (cpuhp_state.state,CPUHP_ONLINE ); } -enum cpu_mitigations cpu_mitigations__ro_after_init =CPU_MITIGATIONS_AUTO ; +/* +* These are used for a global "mitigations=" cmdline option for toggling +* optional CPU mitigations. +*/ +enum cpu_mitigations { +CPU_MITIGATIONS_OFF , +CPU_MITIGATIONS_AUTO , +CPU_MITIGATIONS_AUTO_NOSMT , +}; + +static enum cpu_mitigations cpu_mitigations__ro_after_init = +CPU_MITIGATIONS_AUTO ;static int __init mitigations_parse_cmdline (char *arg) {
@@ -2252,3 +2263,17 @@ static int __init mitigations_parse_cmdlreturn 0 ; }early_param ("mitigations" , mitigations_parse_cmdline); + +/* mitigations=off */ +bool cpu_mitigations_off (void ) +{ +return cpu_mitigations ==CPU_MITIGATIONS_OFF ; +} +EXPORT_SYMBOL_GPL (cpu_mitigations_off); + +/* mitigations=auto,nosmt */ +bool cpu_mitigations_auto_nosmt (void ) +{ +return cpu_mitigations ==CPU_MITIGATIONS_AUTO_NOSMT ; +} +EXPORT_SYMBOL_GPL (cpu_mitigations_auto_nosmt);
Greg Kroah-Hartman
maintainerPATCH 28/31 kvm: mmu: ITLB_MULTIHIT mitigation
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit b8e8c8303ff28c61046a4d0f6ea99aea609a7dc0 upstream.
With some Intel processors, putting the same virtual address in the TLB as both a 4 KiB and 2 MiB page can confuse the instruction fetch unit and cause the processor to issue a machine check resulting in a CPU lockup.
Unfortunately when EPT page tables use huge pages, it is possible for a malicious guest to cause this situation.
Add a knob to mark huge pages as non-executable. When the nx_huge_pages parameter is enabled (and we are using EPT), all huge pages are marked as NX. If the guest attempts to execute in one of those pages, the page is broken down into 4K pages, which are then marked executable.
This is not an issue for shadow paging (except nested EPT), because then the host is in control of TLB flushes and the problematic situation cannot happen. With nested EPT, again the nested guest can cause problems shadow and direct EPT is treated in the same way.
[ tglx: Fixup default to auto and massage wording a bit ]
[bwh: Backported to 4.9:
- Use kvm_mmu_invalidate_zap_all_pages() instead of kvm_mmu_zap_all_fast()
- Don't provide mode for nx_largepages_splitted as all stats are read-only
- Adjust filename, context]
--- Documentation/kernel-parameters.txt | 19 ++++ arch/x86/include/asm/kvm_host.h | 2 arch/x86/kernel/cpu/bugs.c | 13 +++ arch/x86/kvm/mmu.c | 141 ++++++++++++++++++++++++++++++++++-- arch/x86/kvm/paging_tmpl.h | 29 +++++-- arch/x86/kvm/x86.c | 9 ++ 6 files changed, 200 insertions(+), 13 deletions(-)
Documentation/kernel-parameters.txt +19 -0
@@ -1975,6 +1975,19 @@ bytes respectively. Such letter suffixes KVM MMU at runtime. Default is 0 (off) + kvm.nx_huge_pages= + [KVM] Controls the software workaround for the + X86_BUG_ITLB_MULTIHIT bug. + force : Always deploy workaround. + off : Never deploy workaround. + auto : Deploy workaround based on the presence of + X86_BUG_ITLB_MULTIHIT. + + Default is 'auto'. + + If the software workaround is enabled for the host, + guests do need not to enable it for nested guests. + kvm-amd.nested= [KVM,AMD] Allow nested virtualization in KVM/SVM. Default is 1 (enabled)
@@ -2491,6 +2504,12 @@ bytes respectively. Such letter suffixes l1tf=off [X86] mds=off [X86] tsx_async_abort=off [X86] + kvm.nx_huge_pages=off [X86] + + Exceptions: + This does not have any effect on + kvm.nx_huge_pages when + kvm.nx_huge_pages=force. auto (default) Mitigate all CPU vulnerabilities, but leave SMT
arch/x86/include/asm/kvm_host.h +2 -0
@@ -273,6 +273,7 @@ struct kvm_mmu_page {/* hold the gfn of each spte inside spt */ gfn_t *gfns;bool unsync; +bool lpage_disallowed;/* Can't be replaced by an equiv large page */ int root_count;/* Currently serving as active root */ unsigned int unsync_children;struct kvm_rmap_head parent_ptes;/* rmap pointers to parent sptes */
@@ -811,6 +812,7 @@ struct kvm_vm_stat {ulong mmu_unsync;ulong remote_tlb_flush;ulong lpages; +ulong nx_lpage_splits; };struct kvm_vcpu_stat {
arch/x86/kernel/cpu/bugs.c +12 -1
@@ -1233,6 +1233,9 @@ void x86_spec_ctrl_setup_ap(void)x86_amd_ssb_disable (); } +bool itlb_multihit_kvm_mitigation; +EXPORT_SYMBOL_GPL (itlb_multihit_kvm_mitigation); +#undef pr_fmt#define pr_fmt (fmt) "L1TF: " fmt
@@ -1388,17 +1391,25 @@ static ssize_t l1tf_show_state(char *buf l1tf_vmx_states[l1tf_vmx_mitigation], sched_smt_active() ? "vulnerable" : "disabled"); } + +static ssize_t itlb_multihit_show_state (char *buf) +{ +if (itlb_multihit_kvm_mitigation) +return sprintf (buf,"KVM: Mitigation: Split huge pages\n" ); +else +return sprintf (buf,"KVM: Vulnerable\n" ); +}#else static ssize_t l1tf_show_state (char *buf) {return sprintf (buf,"%s\n" ,L1TF_DEFAULT_MSG ); } -#endif static ssize_t itlb_multihit_show_state (char *buf) {return sprintf (buf,"Processor vulnerable\n" ); } +#endif static ssize_t mds_show_state (char *buf) {
arch/x86/kvm/mmu.c +135 -6
239 lines not on this page · raw message
arch/x86/kvm/paging_tmpl.h +23 -6
@@ -573,13 +573,14 @@ static void FNAME(pte_prefetch)(struct kstatic int FNAME (fetch )(struct kvm_vcpu *vcpu,gva_t addr,struct guest_walker *gw,int write_fault,int hlevel, -kvm_pfn_t pfn,bool map_writable,bool prefault) +kvm_pfn_t pfn,bool map_writable,bool prefault, +bool lpage_disallowed) {struct kvm_mmu_page *sp =NULL ;struct kvm_shadow_walk_iterator it;unsigned direct_access, access = gw->pt_access;int top_level, ret; -gfn_t base_gfn; +gfn_t gfn, base_gfn; direct_access = gw->pte_access;
@@ -624,13 +625,25 @@ static int FNAME(fetch)(struct kvm_vcpulink_shadow_page (vcpu, it.sptep, sp); } - base_gfn = gw->gfn; +/* +* FNAME(page_fault) might have clobbered the bottom bits of +* gw->gfn, restore them from the virtual address. +*/ + gfn = gw->gfn | ((addr &PT_LVL_OFFSET_MASK (gw->level)) >>PAGE_SHIFT ); + base_gfn = gfn;trace_kvm_mmu_spte_requested (addr, gw->level, pfn);for (;shadow_walk_okay (&it);shadow_walk_next (&it)) {clear_sp_write_flooding_count (it.sptep); - base_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE (it.level) -1 ); + +/* +* We cannot overwrite existing page tables with an NX +* large page, as the leaf could be executable. +*/ +disallowed_hugepage_adjust (it, gfn, &pfn, &hlevel); + + base_gfn = gfn & ~(KVM_PAGES_PER_HPAGE (it.level) -1 );if (it.level == hlevel)break ;
@@ -642,6 +655,8 @@ static int FNAME(fetch)(struct kvm_vcpu sp =kvm_mmu_get_page (vcpu, base_gfn, addr, it.level -1 , true, direct_access);link_shadow_page (vcpu, it.sptep, sp); +if (lpage_disallowed) +account_huge_nx_page (vcpu->kvm, sp); } }
@@ -718,9 +733,11 @@ static int FNAME(page_fault)(struct kvm_int r;kvm_pfn_t pfn;int level =PT_PAGE_TABLE_LEVEL ; -bool force_pt_level = false;unsigned long mmu_seq;bool map_writable, is_self_change_mapping; +bool lpage_disallowed = (error_code &PFERR_FETCH_MASK ) && +is_nx_huge_page_enabled (); +bool force_pt_level = lpage_disallowed;pgprintk ("%s: addr %lx err %x\n" , __func__, addr, error_code);
@@ -810,7 +827,7 @@ static int FNAME(page_fault)(struct kvm_if (!force_pt_level)transparent_hugepage_adjust (vcpu, walker.gfn, &pfn, &level); r =FNAME (fetch)(vcpu, addr, &walker, write_fault, - level, pfn, map_writable, prefault); + level, pfn, map_writable, prefault, lpage_disallowed);kvm_mmu_audit (vcpu,AUDIT_POST_PAGE_FAULT ); out_unlock:
arch/x86/kvm/x86.c +9 -0
@@ -191,6 +191,7 @@ struct kvm_stats_debugfs_item debugfs_en { "mmu_unsync", VM_STAT(mmu_unsync) }, { "remote_tlb_flush", VM_STAT(remote_tlb_flush) }, { "largepages", VM_STAT(lpages) }, + { "nx_largepages_splitted", VM_STAT(nx_lpage_splits) }, { NULL } };
@@ -1032,6 +1033,14 @@ u64 kvm_get_arch_capabilities(void)rdmsrl_safe (MSR_IA32_ARCH_CAPABILITIES , &data);/* +* If nx_huge_pages is enabled, KVM's shadow paging will ensure that +* the nested hypervisor runs with NX huge pages. If it is not, +* L1 is anyway vulnerable to ITLB_MULTIHIT explots from other +* L1 guests, so it need not worry about its own (L2) guests. +*/ + data |=ARCH_CAP_PSCHANGE_MC_NO ; + +/* * If we're doing cache flushes (either "always" or "cond") * we will do one whenever the guest does a vmlaunch/vmresume. * If an outer hypervisor is doing the cache flush for us
Greg Kroah-Hartman
maintainerPATCH 29/31 kvm: Add helper function for creating VM worker threads
In reply to Greg Kroah-HartmanFrom: Junaid Shahid <[email protected]>
commit c57c80467f90e5504c8df9ad3555d2c78800bf94 upstream.
Add a function to create a kernel thread associated with a given VM. In particular, it ensures that the worker thread inherits the priority and cgroups of the calling thread.
--- include/linux/kvm_host.h | 6 +++ virt/kvm/kvm_main.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+)
include/linux/kvm_host.h +6 -0
@@ -1208,4 +1208,10 @@ static inline bool vcpu_valid_wakeup(str }#endif /* CONFIG_HAVE_KVM_INVALID_WAKEUPS */ +typedef int (*kvm_vm_thread_fn_t )(struct kvm *kvm,uintptr_t data); + +int kvm_vm_create_worker_thread (struct kvm *kvm,kvm_vm_thread_fn_t thread_fn, +uintptr_t data,const char *name, +struct task_struct **thread_ptr); +#endif
virt/kvm/kvm_main.c +84 -0
93 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 30/31 kvm: x86: mmu: Recovery of shattered NX large pages
In reply to Greg Kroah-HartmanFrom: Junaid Shahid <[email protected]>
commit 1aa9b9572b10529c2e64e2b8f44025d86e124308 upstream.
The page table pages corresponding to broken down large pages are zapped in FIFO order, so that the large page can potentially be recovered, if it is not longer being used for execution. This removes the performance penalty for walking deeper EPT page tables.
By default, one large page will last about one hour once the guest reaches a steady state.
[bwh: Backported to 4.9:
- Update another error path in kvm_create_vm() to use out_err_no_mmu_notifier
- Adjust filename, context]
--- Documentation/kernel-parameters.txt | 6 + arch/x86/include/asm/kvm_host.h | 4 + arch/x86/kvm/mmu.c | 129 ++++++++++++++++++++++++++++++++++++ arch/x86/kvm/mmu.h | 4 + arch/x86/kvm/x86.c | 11 +++ virt/kvm/kvm_main.c | 30 ++++++++ 6 files changed, 183 insertions(+), 1 deletion(-)
Documentation/kernel-parameters.txt +6 -0
@@ -1988,6 +1988,12 @@ bytes respectively. Such letter suffixes If the software workaround is enabled for the host, guests do need not to enable it for nested guests. + kvm.nx_huge_pages_recovery_ratio= + [KVM] Controls how many 4KiB pages are periodically zapped + back to huge pages. 0 disables the recovery, otherwise if + the value is N KVM will zap 1/Nth of the 4KiB pages every + minute. The default is 60. + kvm-amd.nested= [KVM,AMD] Allow nested virtualization in KVM/SVM. Default is 1 (enabled)
arch/x86/include/asm/kvm_host.h +4 -0
@@ -261,6 +261,7 @@ struct kvm_rmap_head {struct kvm_mmu_page {struct list_head link;struct hlist_node hash_link; +struct list_head lpage_disallowed_link;/* * The following two entries are used to key the shadow page in the
@@ -725,6 +726,7 @@ struct kvm_arch {*/ struct list_head active_mmu_pages;struct list_head zapped_obsolete_pages; +struct list_head lpage_disallowed_mmu_pages;struct kvm_page_track_notifier_node mmu_sp_tracker;struct kvm_page_track_notifier_head track_notifier_head;
@@ -799,6 +801,8 @@ struct kvm_arch {bool x2apic_format;bool x2apic_broadcast_quirk_disabled; + +struct task_struct *nx_lpage_recovery_thread; };struct kvm_vm_stat {
arch/x86/kvm/mmu.c +129 -0
172 lines not on this page · raw message
arch/x86/kvm/mmu.h +4 -0
@@ -185,4 +185,8 @@ void kvm_mmu_gfn_disallow_lpage(struct kvoid kvm_mmu_gfn_allow_lpage (struct kvm_memory_slot *slot,gfn_t gfn);bool kvm_mmu_slot_gfn_write_protect (struct kvm *kvm,struct kvm_memory_slot *slot,u64 gfn); + +int kvm_mmu_post_init_vm (struct kvm *kvm); +void kvm_mmu_pre_destroy_vm (struct kvm *kvm); +#endif
arch/x86/kvm/x86.c +11 -0
@@ -8108,6 +8108,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unINIT_HLIST_HEAD (&kvm->arch.mask_notifier_list);INIT_LIST_HEAD (&kvm->arch.active_mmu_pages);INIT_LIST_HEAD (&kvm->arch.zapped_obsolete_pages); +INIT_LIST_HEAD (&kvm->arch.lpage_disallowed_mmu_pages);INIT_LIST_HEAD (&kvm->arch.assigned_dev_head);atomic_set (&kvm->arch.noncoherent_dma_count,0 );
@@ -8136,6 +8137,11 @@ int kvm_arch_init_vm(struct kvm *kvm, unreturn 0 ; } +int kvm_arch_post_init_vm (struct kvm *kvm) +{ +return kvm_mmu_post_init_vm (kvm); +} +static void kvm_unload_vcpu_mmu (struct kvm_vcpu *vcpu) {int r;
@@ -8242,6 +8248,11 @@ int x86_set_memory_region(struct kvm *kv }EXPORT_SYMBOL_GPL (x86_set_memory_region); +void kvm_arch_pre_destroy_vm (struct kvm *kvm) +{ +kvm_mmu_pre_destroy_vm (kvm); +} +void kvm_arch_destroy_vm (struct kvm *kvm) {if (current->mm == kvm->mm) {
virt/kvm/kvm_main.c +29 -1
@@ -613,6 +613,23 @@ static int kvm_create_vm_debugfs(structreturn 0 ; } +/* +* Called after the VM is otherwise initialized, but just before adding it to +* the vm_list. +*/ +int __weak kvm_arch_post_init_vm (struct kvm *kvm) +{ +return 0 ; +} + +/* +* Called just after removing the VM from the vm_list, but before doing any +* other destruction. +*/ +void __weak kvm_arch_pre_destroy_vm (struct kvm *kvm) +{ +} +static struct kvm *kvm_create_vm (unsigned long type) {int r, i;
@@ -660,11 +677,15 @@ static struct kvm *kvm_create_vm(unsigne kvm->buses[i] =kzalloc (sizeof (struct kvm_io_bus ),GFP_KERNEL );if (!kvm->buses[i]) - goto out_err; + goto out_err_no_mmu_notifier; } r =kvm_init_mmu_notifier (kvm);if (r) + goto out_err_no_mmu_notifier; + + r =kvm_arch_post_init_vm (kvm); +if (r) goto out_err;mutex_lock (&kvm_lock);
@@ -676,6 +697,11 @@ static struct kvm *kvm_create_vm(unsignereturn kvm; out_err: +#if defined(CONFIG_MMU_NOTIFIER ) && defined(KVM_ARCH_WANT_MMU_NOTIFIER ) +if (kvm->mmu_notifier.ops) +mmu_notifier_unregister (&kvm->mmu_notifier, current->mm); +#endif +out_err_no_mmu_notifier:cleanup_srcu_struct (&kvm->irq_srcu); out_err_no_irq_srcu:cleanup_srcu_struct (&kvm->srcu);
@@ -728,6 +754,8 @@ static void kvm_destroy_vm(struct kvm *kmutex_lock (&kvm_lock);list_del (&kvm->vm_list);mutex_unlock (&kvm_lock); +kvm_arch_pre_destroy_vm (kvm); +kvm_free_irq_routing (kvm);for (i =0 ; i <KVM_NR_BUSES ; i++) {if (kvm->buses[i])
Greg Kroah-Hartman
maintainerPATCH 31/31 Documentation: Add ITLB_MULTIHIT documentation
In reply to Greg Kroah-HartmanFrom: "Gomez Iglesias, Antonio" <[email protected]>
commit 7f00cc8d4a51074eb0ad4c3f16c15757b1ddfb7d upstream.
Add the initial ITLB_MULTIHIT documentation.
[ tglx: Add it to the index so it gets actually built. ]
--- Documentation/hw-vuln/index.rst | 1 Documentation/hw-vuln/multihit.rst | 163 +++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 Documentation/hw-vuln/multihit.rst
Documentation/hw-vuln/index.rst +1 -0
@@ -12,3 +12,4 @@ are configurable at compile, boot or run l1tf mds tsx_async_abort + multihit.rst
Documentation/hw-vuln/multihit.rst new file +163 -0
163 lines not on this page · raw message
stable-rc/linux-4.9.y boot: 93 boots: 0 failed, 89 passed with 3 offline, 1 conflict (v4.9.201-32-gd7f83e4f45e8)
stable-rc/linux-4.9.y boot: 93 boots: 0 failed, 89 passed with 3 offline, 1 conflict (v4.9.201-32-gd7f83e4f45e8)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-4.9.y/kernel/v4.9.201-32-gd7f83e4f45e8/
Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.9.y/kernel/v4.9.201-32-gd7f83e4f45e8/
Tree: stable-rc
Branch: linux-4.9.y
Git Describe: v4.9.201-32-gd7f83e4f45e8
Git Commit: d7f83e4f45e886d919bc985bd225b8355ddd9284
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
Tested: 49 unique boards, 19 SoC families, 14 builds out of 197
Offline Platforms:
arm:
sunxi_defconfig:
gcc-8
sun7i-a20-bananapi: 1 offline lab
multi_v7_defconfig:
gcc-8
bcm4708-smartrg-sr400ac: 1 offline lab
sun7i-a20-bananapi: 1 offline labConflicting Boot Failure Detected: (These likely are not failures as other labs are reporting PASS. Needs review.)
x86_64:
x86_64_defconfig:
qemu_x86_64:
lab-collabora: FAIL (gcc-8)
lab-baylibre: PASS (gcc-8)
---
For more info write to <[email protected]>
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.202 release. There are 31 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 17 Nov 2019 06:18:35 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.202-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.9.y
and the diffstat can be found below.thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.9:
8 builds: 8 pass, 0 fail
16 boots: 16 pass, 0 fail
24 tests: 24 pass, 0 failLinux version: 4.9.202-rc1-gd7f83e4f45e8
Boards tested: tegra124-jetson-tk1, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04
Cheers
Jon
Signature · 1 line
nvpublic
Greg Kroah-Hartman
maintainerQuoted 22 lines · Jon Hunter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.202 release. There are 31 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 17 Nov 2019 06:18:35 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.202-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.9.y
and the diffstat can be found below.thanks,
greg k-h
All tests are passing for Tegra ...
Quoted 8 lines
Test results for stable-v4.9:
8 builds: 8 pass, 0 fail 16 boots: 16 pass, 0 fail 24 tests: 24 pass, 0 failLinux version: 4.9.202-rc1-gd7f83e4f45e8
Boards tested: tegra124-jetson-tk1, tegra20-ventana,tegra210-p2371-2180, tegra30-cardhu-a04
Thanks for testing both of these and letting me know.
greg k-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.202 release. There are 31 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 17 Nov 2019 06:18:35 +0000. Anything received after that time might be too late.
Build results:
total: 172 pass: 172 fail: 0 Qemu test results: total: 356 pass: 356 fail: 0
Guenter
Greg Kroah-Hartman
maintainerQuoted 6 lines · Guenter Roeck
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.202 release. There are 31 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 7 lines
Quoted 3 lines
Responses should be made by Sun, 17 Nov 2019 06:18:35 +0000. Anything received after that time might be too late.
Build results:
total: 172 pass: 172 fail: 0 Qemu test results: total: 356 pass: 356 fail: 0
Great, thanks for testing both of these and letting me know.
greg k-h
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.202 release. There are 31 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 17 Nov 2019 06:18:35 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.202-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.9.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 4.9.202-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.9.y
git commit: d7f83e4f45e886d919bc985bd225b8355ddd9284
git describe: v4.9.201-32-gd7f83e4f45e8
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.9-oe/build/v4.9.201-32-gd7f83e4f45e8
No regressions (compared to build v4.9.201)
No fixes (compared to build v4.9.201)
Ran 23552 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c - arm64
- hi6220-hikey - arm64
- i386
- juno-r2 - arm64
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15 - arm
- x86_64
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* kselftest
* libhugetlbfs
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-cpuhotplug-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* perf
* spectre-meltdown-checker-test
* v4l2-compliance
* network-basic-tests
* ltp-open-posix-tests
* kvm-unit-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
* prep-tmp-disk
* ssuite
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 17 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.202 release. There are 31 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 17 Nov 2019 06:18:35 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.202-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.9.y
and the diffstat can be found below.
Quoted 6 lines
Quoted 3 lines
thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm,x86_64, and i386.
THanks for testing both of these and letting me know.
greg k-h