mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
This is the 4.14.21 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlqO1toACgkQONu9yGCS aT49JhAAjKxDe1PA6lq51uyWHlR73vJ93SvtDCHuM8s6aj/rb880vjeZumWcEAdR nl2Yj/T0z9yZkBrw8Om/3BX4PfsF6hqq1TAufxYeKs08nVQ60v3/a4Mz9CYu8e0A mXdK6DvSEQRS6S0vc83W2+fj5e05Vfvv23FlsngtH6IxaOL7mnRTxNmP5/PMP3QX xtOKRBB7ghqqfV8U+yAJ0fbTKu0a+ztPLxCe2Lk+7U7yFpqLudzBfTV06QpcqwSF fXdRWv8319c24585qubm2N1zDJ8PsxlcFWmvgbcZgO+lk1Zf4XuzxjsElg6PpYvT m+8L1/Qo4k+L3eXJJiwLPqd6LP9VtspvRItZKMFMPZJNWLdk9tnjcLuA/HpTUvo9 EO/fXBP3YrX48TrjGIu9K4ToZvLFWGcDno5Vges0fb2MkixWF5b2naEdeS+B7SF2 ckYAWuoZPErmmNo6bhIkdizube6k8t+Ch7JxkxWgZh+Jw80drqSBzfdWKTLMl3k0 Nvo8RdbuSrDSg40NHT/d46tBguMp9n/J8eu6f/poN1VZRdqZkgqZ7xHjl7vgRRkg nfcVndDTw099hhC0OuWVHJMpk62wVz+tRPNOR/yCucDPH1//HuEZ62sQzcjpPQ9l ML2MD4zrTORK9VuztJFET8feWQ4KrqoSdE8HMD+TtMhhShcZcJA= =vnDS -----END PGP SIGNATURE----- Merge 4.14.21 into android-4.14 Changes in 4.14.21 tracing: Prevent PROFILE_ALL_BRANCHES when FORTIFY_SOURCE=y scsi: smartpqi: allow static build ("built-in") IB/umad: Fix use of unprotected device pointer IB/qib: Fix comparison error with qperf compare/swap test IB/mlx4: Fix incorrectly releasing steerable UD QPs when have only ETH ports IB/core: Fix two kernel warnings triggered by rxe registration IB/core: Fix ib_wc structure size to remain in 64 bytes boundary IB/core: Avoid a potential OOPs for an unused optional parameter selftests: seccomp: fix compile error seccomp_bpf kselftest: fix OOM in memory compaction test RDMA/rxe: Fix a race condition related to the QP error state RDMA/rxe: Fix a race condition in rxe_requester() RDMA/rxe: Fix rxe_qp_cleanup() cpufreq: powernv: Dont assume distinct pstate values for nominal and pmin swiotlb: suppress warning when __GFP_NOWARN is set PM / devfreq: Propagate error from devfreq_add_device() mwifiex: resolve reset vs. remove()/shutdown() deadlocks ocfs2: try a blocking lock before return AOP_TRUNCATED_PAGE powerpc/radix: Remove trace_tlbie call from radix__flush_tlb_all powerpc/numa: Invalidate numa_cpu_lookup_table on cpu remove powerpc/mm: Flush radix process translations when setting MMU type powerpc/xive: Use hw CPU ids when configuring the CPU queues powerpc: Fix DABR match on hash based systems dma-buf: fix reservation_object_wait_timeout_rcu once more v2 s390: fix handling of -1 in set{,fs}[gu]id16 syscalls arm64: dts: msm8916: Correct ipc references for smsm ARM: lpc3250: fix uda1380 gpio numbers ARM: dts: STi: Add gpio polarity for "hdmi,hpd-gpio" property ARM: dts: nomadik: add interrupt-parent for clcd arm: dts: mt7623: fix card detection issue on bananapi-r2 arm: spear600: Add missing interrupt-parent of rtc arm: spear13xx: Fix dmas cells arm: spear13xx: Fix spics gpio controller's warning drm/i915: add GT number to intel_device_info drm/i915/kbl: Change a KBL pci id to GT2 from GT1.5 x86/gpu: add CFL to early quirks x86/kexec: Make kexec (mostly) work in 5-level paging mode x86/xen: init %gs very early to avoid page faults with stack protector x86: PM: Make APM idle driver initialize polling state x86/entry/64: Clear extra registers beyond syscall arguments, to reduce speculation attack surface x86/entry/64/compat: Clear registers for compat syscalls, to reduce speculation attack surface compiler-gcc.h: Introduce __optimize function attribute compiler-gcc.h: __nostackprotector needs gcc-4.4 and up crypto: sun4i_ss_prng - fix return value of sun4i_ss_prng_generate crypto: sun4i_ss_prng - convert lock to _bh in sun4i_ss_prng_generate powerpc/mm/radix: Split linear mapping on hot-unplug x86/mm/pti: Fix PTI comment in entry_SYSCALL_64() x86/speculation: Update Speculation Control microcode blacklist x86/speculation: Correct Speculation Control microcode blacklist again Revert "x86/speculation: Simplify indirect_branch_prediction_barrier()" KVM/x86: Reduce retpoline performance impact in slot_handle_level_range(), by always inlining iterator helper methods X86/nVMX: Properly set spec_ctrl and pred_cmd before merging MSRs KVM/nVMX: Set the CPU_BASED_USE_MSR_BITMAPS if we have a valid L02 MSR bitmap x86/speculation: Clean up various Spectre related details PM / runtime: Update links_count also if !CONFIG_SRCU PM: cpuidle: Fix cpuidle_poll_state_init() prototype x86/entry/64: Clear registers for exceptions/interrupts, to reduce speculation attack surface x86/entry/64: Merge SAVE_C_REGS and SAVE_EXTRA_REGS, remove unused extensions x86/entry/64: Merge the POP_C_REGS and POP_EXTRA_REGS macros into a single POP_REGS macro x86/entry/64: Interleave XOR register clearing with PUSH instructions x86/entry/64: Introduce the PUSH_AND_CLEAN_REGS macro x86/entry/64: Use PUSH_AND_CLEAN_REGS in more cases x86/entry/64: Get rid of the ALLOC_PT_GPREGS_ON_STACK and SAVE_AND_CLEAR_REGS macros x86/entry/64: Indent PUSH_AND_CLEAR_REGS and POP_REGS properly x86/entry/64: Fix paranoid_entry() frame pointer warning x86/entry/64: Remove the unused 'icebp' macro selftests/x86: Fix vDSO selftest segfault for vsyscall=none selftests/x86: Clean up and document sscanf() usage selftests/x86/pkeys: Remove unused functions selftests/x86: Do not rely on "int $0x80" in test_mremap_vdso.c selftests/x86: Do not rely on "int $0x80" in single_step_syscall.c selftests/x86: Disable tests requiring 32-bit support on pure 64-bit systems objtool: Fix segfault in ignore_unreachable_insn() x86/debug, objtool: Annotate WARN()-related UD2 as reachable x86/debug: Use UD2 for WARN() x86/speculation: Fix up array_index_nospec_mask() asm constraint nospec: Move array_index_nospec() parameter checking into separate macro x86/speculation: Add <asm/msr-index.h> dependency kmemcheck: remove annotations kmemcheck: stop using GFP_NOTRACK and SLAB_NOTRACK kmemcheck: remove whats left of NOTRACK flags kmemcheck: rip it out kmemcheck: rip it out for real x86/mm: Rename flush_tlb_single() and flush_tlb_one() to __flush_tlb_one_[user|kernel]() selftests/x86/mpx: Fix incorrect bounds with old _sigfault x86/cpu: Rename cpu_data.x86_mask to cpu_data.x86_stepping x86/spectre: Fix an error message x86/cpu: Change type of x86_cache_size variable to unsigned int x86/entry/64: Fix CR3 restore in paranoid_exit() drm/ttm: Don't add swapped BOs to swap-LRU list drm/ttm: Fix 'buf' pointer update in ttm_bo_vm_access_kmap() (v2) drm/qxl: unref cursor bo when finished with it drm/amd/powerplay: Fix smu_table_entry.handle type drm/ast: Load lut in crtc_commit arm64: Add missing Falkor part number for branch predictor hardening drm/radeon: Add dpm quirk for Jet PRO (v2) drm/radeon: adjust tested variable rtc-opal: Fix handling of firmware error codes, prevent busy loops mbcache: initialize entry->e_referenced in mb_cache_entry_create() mmc: sdhci: Implement an SDHCI-specific bounce buffer mmc: bcm2835: Don't overwrite max frequency unconditionally Revert "mmc: meson-gx: include tx phase in the tuning process" mlx5: fix mlx5_get_vector_affinity to start from completion vector 0 Revert "apple-gmux: lock iGP IO to protect from vgaarb changes" jbd2: fix sphinx kernel-doc build warnings ext4: fix a race in the ext4 shutdown path ext4: save error to disk in __ext4_grp_locked_error() ext4: correct documentation for grpid mount option mm: hide a #warning for COMPILE_TEST mm: Fix memory size alignment in devm_memremap_pages_release() MIPS: Fix typo BIG_ENDIAN to CPU_BIG_ENDIAN MIPS: Fix incorrect mem=X@Y handling PCI: Disable MSI for HiSilicon Hip06/Hip07 only in Root Port mode PCI: iproc: Fix NULL pointer dereference for BCMA PCI: keystone: Fix interrupt-controller-node lookup video: fbdev: atmel_lcdfb: fix display-timings lookup console/dummy: leave .con_font_get set to NULL rbd: whitelist RBD_FEATURE_OPERATIONS feature bit xen: Fix {set,clear}_foreign_p2m_mapping on autotranslating guests xenbus: track caller request id seq_file: fix incomplete reset on read from zero offset tracing: Fix parsing of globs with a wildcard at the beginning mpls, nospec: Sanitize array index in mpls_label_ok() rtlwifi: rtl8821ae: Fix connection lost problem correctly arm64: proc: Set PTE_NG for table entries to avoid traversing them twice qxl: alloc & use shadow for dumb buffers drm/qxl: reapply cursor after resetting primary xprtrdma: Fix calculation of ri_max_send_sges xprtrdma: Fix BUG after a device removal blk-wbt: account flush requests correctly target/iscsi: avoid NULL dereference in CHAP auth error path iscsi-target: make sure to wake up sleeping login worker dm: correctly handle chained bios in dec_pending() Btrfs: fix deadlock in run_delalloc_nocow Btrfs: fix crash due to not cleaning up tree log block's dirty bits Btrfs: fix extent state leak from tree log Btrfs: fix btrfs_evict_inode to handle abnormal inodes correctly Btrfs: fix use-after-free on root->orphan_block_rsv Btrfs: fix unexpected -EEXIST when creating new inode 9p/trans_virtio: discard zero-length reply mtd: nand: vf610: set correct ooblayout ALSA: hda - Fix headset mic detection problem for two Dell machines ALSA: usb-audio: Fix UAC2 get_ctl request with a RANGE attribute ALSA: hda/realtek - Add headset mode support for Dell laptop ALSA: hda/realtek - Enable Thinkpad Dock device for ALC298 platform ALSA: hda/realtek: PCI quirk for Fujitsu U7x7 ALSA: usb-audio: add implicit fb quirk for Behringer UFX1204 ALSA: usb: add more device quirks for USB DSD devices ALSA: seq: Fix racy pool initializations mvpp2: fix multicast address filter usb: Move USB_UHCI_BIG_ENDIAN_* out of USB_SUPPORT x86/mm, mm/hwpoison: Don't unconditionally unmap kernel 1:1 pages scsi: core: check for device state in __scsi_remove_target() Bluetooth: BT_HCIUART now depends on SERIAL_DEV_BUS ARM: dts: exynos: fix RTC interrupt for exynos5410 ARM: pxa/tosa-bt: add MODULE_LICENSE tag arm64: dts: msm8916: Add missing #phy-cells ARM: dts: s5pv210: add interrupt-parent for ohci arm: dts: mt7623: Update ethsys binding arm: dts: mt2701: Add reset-cells ARM: dts: Delete bogus reference to the charlcd media: r820t: fix r820t_write_reg for KASAN mmc: sdhci-of-esdhc: disable SD clock for clock value 0 mmc: sdhci-of-esdhc: fix eMMC couldn't work after kexec mmc: sdhci-of-esdhc: fix the mmc error after sleep on ls1046ardb ASoC: acpi: fix machine driver selection based on quirk ovl: hash directory inodes for fsnotify Linux 4.14.21 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
474d3c467b
@ -1844,13 +1844,6 @@
|
||||
Built with CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y,
|
||||
the default is off.
|
||||
|
||||
kmemcheck= [X86] Boot-time kmemcheck enable/disable/one-shot mode
|
||||
Valid arguments: 0, 1, 2
|
||||
kmemcheck=0 (disabled)
|
||||
kmemcheck=1 (enabled)
|
||||
kmemcheck=2 (one-shot mode)
|
||||
Default: 2 (one-shot mode)
|
||||
|
||||
kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs.
|
||||
Default is 0 (don't ignore, but inject #GP)
|
||||
|
||||
|
@ -21,7 +21,6 @@ whole; patches welcome!
|
||||
kasan
|
||||
ubsan
|
||||
kmemleak
|
||||
kmemcheck
|
||||
gdb-kernel-debugging
|
||||
kgdb
|
||||
kselftest
|
||||
|
@ -1,733 +0,0 @@
|
||||
Getting started with kmemcheck
|
||||
==============================
|
||||
|
||||
Vegard Nossum <vegardno@ifi.uio.no>
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
kmemcheck is a debugging feature for the Linux Kernel. More specifically, it
|
||||
is a dynamic checker that detects and warns about some uses of uninitialized
|
||||
memory.
|
||||
|
||||
Userspace programmers might be familiar with Valgrind's memcheck. The main
|
||||
difference between memcheck and kmemcheck is that memcheck works for userspace
|
||||
programs only, and kmemcheck works for the kernel only. The implementations
|
||||
are of course vastly different. Because of this, kmemcheck is not as accurate
|
||||
as memcheck, but it turns out to be good enough in practice to discover real
|
||||
programmer errors that the compiler is not able to find through static
|
||||
analysis.
|
||||
|
||||
Enabling kmemcheck on a kernel will probably slow it down to the extent that
|
||||
the machine will not be usable for normal workloads such as e.g. an
|
||||
interactive desktop. kmemcheck will also cause the kernel to use about twice
|
||||
as much memory as normal. For this reason, kmemcheck is strictly a debugging
|
||||
feature.
|
||||
|
||||
|
||||
Downloading
|
||||
-----------
|
||||
|
||||
As of version 2.6.31-rc1, kmemcheck is included in the mainline kernel.
|
||||
|
||||
|
||||
Configuring and compiling
|
||||
-------------------------
|
||||
|
||||
kmemcheck only works for the x86 (both 32- and 64-bit) platform. A number of
|
||||
configuration variables must have specific settings in order for the kmemcheck
|
||||
menu to even appear in "menuconfig". These are:
|
||||
|
||||
- ``CONFIG_CC_OPTIMIZE_FOR_SIZE=n``
|
||||
This option is located under "General setup" / "Optimize for size".
|
||||
|
||||
Without this, gcc will use certain optimizations that usually lead to
|
||||
false positive warnings from kmemcheck. An example of this is a 16-bit
|
||||
field in a struct, where gcc may load 32 bits, then discard the upper
|
||||
16 bits. kmemcheck sees only the 32-bit load, and may trigger a
|
||||
warning for the upper 16 bits (if they're uninitialized).
|
||||
|
||||
- ``CONFIG_SLAB=y`` or ``CONFIG_SLUB=y``
|
||||
This option is located under "General setup" / "Choose SLAB
|
||||
allocator".
|
||||
|
||||
- ``CONFIG_FUNCTION_TRACER=n``
|
||||
This option is located under "Kernel hacking" / "Tracers" / "Kernel
|
||||
Function Tracer"
|
||||
|
||||
When function tracing is compiled in, gcc emits a call to another
|
||||
function at the beginning of every function. This means that when the
|
||||
page fault handler is called, the ftrace framework will be called
|
||||
before kmemcheck has had a chance to handle the fault. If ftrace then
|
||||
modifies memory that was tracked by kmemcheck, the result is an
|
||||
endless recursive page fault.
|
||||
|
||||
- ``CONFIG_DEBUG_PAGEALLOC=n``
|
||||
This option is located under "Kernel hacking" / "Memory Debugging"
|
||||
/ "Debug page memory allocations".
|
||||
|
||||
In addition, I highly recommend turning on ``CONFIG_DEBUG_INFO=y``. This is also
|
||||
located under "Kernel hacking". With this, you will be able to get line number
|
||||
information from the kmemcheck warnings, which is extremely valuable in
|
||||
debugging a problem. This option is not mandatory, however, because it slows
|
||||
down the compilation process and produces a much bigger kernel image.
|
||||
|
||||
Now the kmemcheck menu should be visible (under "Kernel hacking" / "Memory
|
||||
Debugging" / "kmemcheck: trap use of uninitialized memory"). Here follows
|
||||
a description of the kmemcheck configuration variables:
|
||||
|
||||
- ``CONFIG_KMEMCHECK``
|
||||
This must be enabled in order to use kmemcheck at all...
|
||||
|
||||
- ``CONFIG_KMEMCHECK_``[``DISABLED`` | ``ENABLED`` | ``ONESHOT``]``_BY_DEFAULT``
|
||||
This option controls the status of kmemcheck at boot-time. "Enabled"
|
||||
will enable kmemcheck right from the start, "disabled" will boot the
|
||||
kernel as normal (but with the kmemcheck code compiled in, so it can
|
||||
be enabled at run-time after the kernel has booted), and "one-shot" is
|
||||
a special mode which will turn kmemcheck off automatically after
|
||||
detecting the first use of uninitialized memory.
|
||||
|
||||
If you are using kmemcheck to actively debug a problem, then you
|
||||
probably want to choose "enabled" here.
|
||||
|
||||
The one-shot mode is mostly useful in automated test setups because it
|
||||
can prevent floods of warnings and increase the chances of the machine
|
||||
surviving in case something is really wrong. In other cases, the one-
|
||||
shot mode could actually be counter-productive because it would turn
|
||||
itself off at the very first error -- in the case of a false positive
|
||||
too -- and this would come in the way of debugging the specific
|
||||
problem you were interested in.
|
||||
|
||||
If you would like to use your kernel as normal, but with a chance to
|
||||
enable kmemcheck in case of some problem, it might be a good idea to
|
||||
choose "disabled" here. When kmemcheck is disabled, most of the run-
|
||||
time overhead is not incurred, and the kernel will be almost as fast
|
||||
as normal.
|
||||
|
||||
- ``CONFIG_KMEMCHECK_QUEUE_SIZE``
|
||||
Select the maximum number of error reports to store in an internal
|
||||
(fixed-size) buffer. Since errors can occur virtually anywhere and in
|
||||
any context, we need a temporary storage area which is guaranteed not
|
||||
to generate any other page faults when accessed. The queue will be
|
||||
emptied as soon as a tasklet may be scheduled. If the queue is full,
|
||||
new error reports will be lost.
|
||||
|
||||
The default value of 64 is probably fine. If some code produces more
|
||||
than 64 errors within an irqs-off section, then the code is likely to
|
||||
produce many, many more, too, and these additional reports seldom give
|
||||
any more information (the first report is usually the most valuable
|
||||
anyway).
|
||||
|
||||
This number might have to be adjusted if you are not using serial
|
||||
console or similar to capture the kernel log. If you are using the
|
||||
"dmesg" command to save the log, then getting a lot of kmemcheck
|
||||
warnings might overflow the kernel log itself, and the earlier reports
|
||||
will get lost in that way instead. Try setting this to 10 or so on
|
||||
such a setup.
|
||||
|
||||
- ``CONFIG_KMEMCHECK_SHADOW_COPY_SHIFT``
|
||||
Select the number of shadow bytes to save along with each entry of the
|
||||
error-report queue. These bytes indicate what parts of an allocation
|
||||
are initialized, uninitialized, etc. and will be displayed when an
|
||||
error is detected to help the debugging of a particular problem.
|
||||
|
||||
The number entered here is actually the logarithm of the number of
|
||||
bytes that will be saved. So if you pick for example 5 here, kmemcheck
|
||||
will save 2^5 = 32 bytes.
|
||||
|
||||
The default value should be fine for debugging most problems. It also
|
||||
fits nicely within 80 columns.
|
||||
|
||||
- ``CONFIG_KMEMCHECK_PARTIAL_OK``
|
||||
This option (when enabled) works around certain GCC optimizations that
|
||||
produce 32-bit reads from 16-bit variables where the upper 16 bits are
|
||||
thrown away afterwards.
|
||||
|
||||
The default value (enabled) is recommended. This may of course hide
|
||||
some real errors, but disabling it would probably produce a lot of
|
||||
false positives.
|
||||
|
||||
- ``CONFIG_KMEMCHECK_BITOPS_OK``
|
||||
This option silences warnings that would be generated for bit-field
|
||||
accesses where not all the bits are initialized at the same time. This
|
||||
may also hide some real bugs.
|
||||
|
||||
This option is probably obsolete, or it should be replaced with
|
||||
the kmemcheck-/bitfield-annotations for the code in question. The
|
||||
default value is therefore fine.
|
||||
|
||||
Now compile the kernel as usual.
|
||||
|
||||
|
||||
How to use
|
||||
----------
|
||||
|
||||
Booting
|
||||
~~~~~~~
|
||||
|
||||
First some information about the command-line options. There is only one
|
||||
option specific to kmemcheck, and this is called "kmemcheck". It can be used
|
||||
to override the default mode as chosen by the ``CONFIG_KMEMCHECK_*_BY_DEFAULT``
|
||||
option. Its possible settings are:
|
||||
|
||||
- ``kmemcheck=0`` (disabled)
|
||||
- ``kmemcheck=1`` (enabled)
|
||||
- ``kmemcheck=2`` (one-shot mode)
|
||||
|
||||
If SLUB debugging has been enabled in the kernel, it may take precedence over
|
||||
kmemcheck in such a way that the slab caches which are under SLUB debugging
|
||||
will not be tracked by kmemcheck. In order to ensure that this doesn't happen
|
||||
(even though it shouldn't by default), use SLUB's boot option ``slub_debug``,
|
||||
like this: ``slub_debug=-``
|
||||
|
||||
In fact, this option may also be used for fine-grained control over SLUB vs.
|
||||
kmemcheck. For example, if the command line includes
|
||||
``kmemcheck=1 slub_debug=,dentry``, then SLUB debugging will be used only
|
||||
for the "dentry" slab cache, and with kmemcheck tracking all the other
|
||||
caches. This is advanced usage, however, and is not generally recommended.
|
||||
|
||||
|
||||
Run-time enable/disable
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the kernel has booted, it is possible to enable or disable kmemcheck at
|
||||
run-time. WARNING: This feature is still experimental and may cause false
|
||||
positive warnings to appear. Therefore, try not to use this. If you find that
|
||||
it doesn't work properly (e.g. you see an unreasonable amount of warnings), I
|
||||
will be happy to take bug reports.
|
||||
|
||||
Use the file ``/proc/sys/kernel/kmemcheck`` for this purpose, e.g.::
|
||||
|
||||
$ echo 0 > /proc/sys/kernel/kmemcheck # disables kmemcheck
|
||||
|
||||
The numbers are the same as for the ``kmemcheck=`` command-line option.
|
||||
|
||||
|
||||
Debugging
|
||||
~~~~~~~~~
|
||||
|
||||
A typical report will look something like this::
|
||||
|
||||
WARNING: kmemcheck: Caught 32-bit read from uninitialized memory (ffff88003e4a2024)
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
^
|
||||
|
||||
Pid: 1856, comm: ntpdate Not tainted 2.6.29-rc5 #264 945P-A
|
||||
RIP: 0010:[<ffffffff8104ede8>] [<ffffffff8104ede8>] __dequeue_signal+0xc8/0x190
|
||||
RSP: 0018:ffff88003cdf7d98 EFLAGS: 00210002
|
||||
RAX: 0000000000000030 RBX: ffff88003d4ea968 RCX: 0000000000000009
|
||||
RDX: ffff88003e5d6018 RSI: ffff88003e5d6024 RDI: ffff88003cdf7e84
|
||||
RBP: ffff88003cdf7db8 R08: ffff88003e5d6000 R09: 0000000000000000
|
||||
R10: 0000000000000080 R11: 0000000000000000 R12: 000000000000000e
|
||||
R13: ffff88003cdf7e78 R14: ffff88003d530710 R15: ffff88003d5a98c8
|
||||
FS: 0000000000000000(0000) GS:ffff880001982000(0063) knlGS:00000
|
||||
CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033
|
||||
CR2: ffff88003f806ea0 CR3: 000000003c036000 CR4: 00000000000006a0
|
||||
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||
DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
|
||||
[<ffffffff8104f04e>] dequeue_signal+0x8e/0x170
|
||||
[<ffffffff81050bd8>] get_signal_to_deliver+0x98/0x390
|
||||
[<ffffffff8100b87d>] do_notify_resume+0xad/0x7d0
|
||||
[<ffffffff8100c7b5>] int_signal+0x12/0x17
|
||||
[<ffffffffffffffff>] 0xffffffffffffffff
|
||||
|
||||
The single most valuable information in this report is the RIP (or EIP on 32-
|
||||
bit) value. This will help us pinpoint exactly which instruction that caused
|
||||
the warning.
|
||||
|
||||
If your kernel was compiled with ``CONFIG_DEBUG_INFO=y``, then all we have to do
|
||||
is give this address to the addr2line program, like this::
|
||||
|
||||
$ addr2line -e vmlinux -i ffffffff8104ede8
|
||||
arch/x86/include/asm/string_64.h:12
|
||||
include/asm-generic/siginfo.h:287
|
||||
kernel/signal.c:380
|
||||
kernel/signal.c:410
|
||||
|
||||
The "``-e vmlinux``" tells addr2line which file to look in. **IMPORTANT:**
|
||||
This must be the vmlinux of the kernel that produced the warning in the
|
||||
first place! If not, the line number information will almost certainly be
|
||||
wrong.
|
||||
|
||||
The "``-i``" tells addr2line to also print the line numbers of inlined
|
||||
functions. In this case, the flag was very important, because otherwise,
|
||||
it would only have printed the first line, which is just a call to
|
||||
``memcpy()``, which could be called from a thousand places in the kernel, and
|
||||
is therefore not very useful. These inlined functions would not show up in
|
||||
the stack trace above, simply because the kernel doesn't load the extra
|
||||
debugging information. This technique can of course be used with ordinary
|
||||
kernel oopses as well.
|
||||
|
||||
In this case, it's the caller of ``memcpy()`` that is interesting, and it can be
|
||||
found in ``include/asm-generic/siginfo.h``, line 287::
|
||||
|
||||
281 static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
|
||||
282 {
|
||||
283 if (from->si_code < 0)
|
||||
284 memcpy(to, from, sizeof(*to));
|
||||
285 else
|
||||
286 /* _sigchld is currently the largest know union member */
|
||||
287 memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
|
||||
288 }
|
||||
|
||||
Since this was a read (kmemcheck usually warns about reads only, though it can
|
||||
warn about writes to unallocated or freed memory as well), it was probably the
|
||||
"from" argument which contained some uninitialized bytes. Following the chain
|
||||
of calls, we move upwards to see where "from" was allocated or initialized,
|
||||
``kernel/signal.c``, line 380::
|
||||
|
||||
359 static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
|
||||
360 {
|
||||
...
|
||||
367 list_for_each_entry(q, &list->list, list) {
|
||||
368 if (q->info.si_signo == sig) {
|
||||
369 if (first)
|
||||
370 goto still_pending;
|
||||
371 first = q;
|
||||
...
|
||||
377 if (first) {
|
||||
378 still_pending:
|
||||
379 list_del_init(&first->list);
|
||||
380 copy_siginfo(info, &first->info);
|
||||
381 __sigqueue_free(first);
|
||||
...
|
||||
392 }
|
||||
393 }
|
||||
|
||||
Here, it is ``&first->info`` that is being passed on to ``copy_siginfo()``. The
|
||||
variable ``first`` was found on a list -- passed in as the second argument to
|
||||
``collect_signal()``. We continue our journey through the stack, to figure out
|
||||
where the item on "list" was allocated or initialized. We move to line 410::
|
||||
|
||||
395 static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
|
||||
396 siginfo_t *info)
|
||||
397 {
|
||||
...
|
||||
410 collect_signal(sig, pending, info);
|
||||
...
|
||||
414 }
|
||||
|
||||
Now we need to follow the ``pending`` pointer, since that is being passed on to
|
||||
``collect_signal()`` as ``list``. At this point, we've run out of lines from the
|
||||
"addr2line" output. Not to worry, we just paste the next addresses from the
|
||||
kmemcheck stack dump, i.e.::
|
||||
|
||||
[<ffffffff8104f04e>] dequeue_signal+0x8e/0x170
|
||||
[<ffffffff81050bd8>] get_signal_to_deliver+0x98/0x390
|
||||
[<ffffffff8100b87d>] do_notify_resume+0xad/0x7d0
|
||||
[<ffffffff8100c7b5>] int_signal+0x12/0x17
|
||||
|
||||
$ addr2line -e vmlinux -i ffffffff8104f04e ffffffff81050bd8 \
|
||||
ffffffff8100b87d ffffffff8100c7b5
|
||||
kernel/signal.c:446
|
||||
kernel/signal.c:1806
|
||||
arch/x86/kernel/signal.c:805
|
||||
arch/x86/kernel/signal.c:871
|
||||
arch/x86/kernel/entry_64.S:694
|
||||
|
||||
Remember that since these addresses were found on the stack and not as the
|
||||
RIP value, they actually point to the _next_ instruction (they are return
|
||||
addresses). This becomes obvious when we look at the code for line 446::
|
||||
|
||||
422 int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
|
||||
423 {
|
||||
...
|
||||
431 signr = __dequeue_signal(&tsk->signal->shared_pending,
|
||||
432 mask, info);
|
||||
433 /*
|
||||
434 * itimer signal ?
|
||||
435 *
|
||||
436 * itimers are process shared and we restart periodic
|
||||
437 * itimers in the signal delivery path to prevent DoS
|
||||
438 * attacks in the high resolution timer case. This is
|
||||
439 * compliant with the old way of self restarting
|
||||
440 * itimers, as the SIGALRM is a legacy signal and only
|
||||
441 * queued once. Changing the restart behaviour to
|
||||
442 * restart the timer in the signal dequeue path is
|
||||
443 * reducing the timer noise on heavy loaded !highres
|
||||
444 * systems too.
|
||||
445 */
|
||||
446 if (unlikely(signr == SIGALRM)) {
|
||||
...
|
||||
489 }
|
||||
|
||||
So instead of looking at 446, we should be looking at 431, which is the line
|
||||
that executes just before 446. Here we see that what we are looking for is
|
||||
``&tsk->signal->shared_pending``.
|
||||
|
||||
Our next task is now to figure out which function that puts items on this
|
||||
``shared_pending`` list. A crude, but efficient tool, is ``git grep``::
|
||||
|
||||
$ git grep -n 'shared_pending' kernel/
|
||||
...
|
||||
kernel/signal.c:828: pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
kernel/signal.c:1339: pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
|
||||
There were more results, but none of them were related to list operations,
|
||||
and these were the only assignments. We inspect the line numbers more closely
|
||||
and find that this is indeed where items are being added to the list::
|
||||
|
||||
816 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
|
||||
817 int group)
|
||||
818 {
|
||||
...
|
||||
828 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
851 q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
|
||||
852 (is_si_special(info) ||
|
||||
853 info->si_code >= 0)));
|
||||
854 if (q) {
|
||||
855 list_add_tail(&q->list, &pending->list);
|
||||
...
|
||||
890 }
|
||||
|
||||
and::
|
||||
|
||||
1309 int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
|
||||
1310 {
|
||||
....
|
||||
1339 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
1340 list_add_tail(&q->list, &pending->list);
|
||||
....
|
||||
1347 }
|
||||
|
||||
In the first case, the list element we are looking for, ``q``, is being
|
||||
returned from the function ``__sigqueue_alloc()``, which looks like an
|
||||
allocation function. Let's take a look at it::
|
||||
|
||||
187 static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
|
||||
188 int override_rlimit)
|
||||
189 {
|
||||
190 struct sigqueue *q = NULL;
|
||||
191 struct user_struct *user;
|
||||
192
|
||||
193 /*
|
||||
194 * We won't get problems with the target's UID changing under us
|
||||
195 * because changing it requires RCU be used, and if t != current, the
|
||||
196 * caller must be holding the RCU readlock (by way of a spinlock) and
|
||||
197 * we use RCU protection here
|
||||
198 */
|
||||
199 user = get_uid(__task_cred(t)->user);
|
||||
200 atomic_inc(&user->sigpending);
|
||||
201 if (override_rlimit ||
|
||||
202 atomic_read(&user->sigpending) <=
|
||||
203 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
|
||||
204 q = kmem_cache_alloc(sigqueue_cachep, flags);
|
||||
205 if (unlikely(q == NULL)) {
|
||||
206 atomic_dec(&user->sigpending);
|
||||
207 free_uid(user);
|
||||
208 } else {
|
||||
209 INIT_LIST_HEAD(&q->list);
|
||||
210 q->flags = 0;
|
||||
211 q->user = user;
|
||||
212 }
|
||||
213
|
||||
214 return q;
|
||||
215 }
|
||||
|
||||
We see that this function initializes ``q->list``, ``q->flags``, and
|
||||
``q->user``. It seems that now is the time to look at the definition of
|
||||
``struct sigqueue``, e.g.::
|
||||
|
||||
14 struct sigqueue {
|
||||
15 struct list_head list;
|
||||
16 int flags;
|
||||
17 siginfo_t info;
|
||||
18 struct user_struct *user;
|
||||
19 };
|
||||
|
||||
And, you might remember, it was a ``memcpy()`` on ``&first->info`` that
|
||||
caused the warning, so this makes perfect sense. It also seems reasonable
|
||||
to assume that it is the caller of ``__sigqueue_alloc()`` that has the
|
||||
responsibility of filling out (initializing) this member.
|
||||
|
||||
But just which fields of the struct were uninitialized? Let's look at
|
||||
kmemcheck's report again::
|
||||
|
||||
WARNING: kmemcheck: Caught 32-bit read from uninitialized memory (ffff88003e4a2024)
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
^
|
||||
|
||||
These first two lines are the memory dump of the memory object itself, and
|
||||
the shadow bytemap, respectively. The memory object itself is in this case
|
||||
``&first->info``. Just beware that the start of this dump is NOT the start
|
||||
of the object itself! The position of the caret (^) corresponds with the
|
||||
address of the read (ffff88003e4a2024).
|
||||
|
||||
The shadow bytemap dump legend is as follows:
|
||||
|
||||
- i: initialized
|
||||
- u: uninitialized
|
||||
- a: unallocated (memory has been allocated by the slab layer, but has not
|
||||
yet been handed off to anybody)
|
||||
- f: freed (memory has been allocated by the slab layer, but has been freed
|
||||
by the previous owner)
|
||||
|
||||
In order to figure out where (relative to the start of the object) the
|
||||
uninitialized memory was located, we have to look at the disassembly. For
|
||||
that, we'll need the RIP address again::
|
||||
|
||||
RIP: 0010:[<ffffffff8104ede8>] [<ffffffff8104ede8>] __dequeue_signal+0xc8/0x190
|
||||
|
||||
$ objdump -d --no-show-raw-insn vmlinux | grep -C 8 ffffffff8104ede8:
|
||||
ffffffff8104edc8: mov %r8,0x8(%r8)
|
||||
ffffffff8104edcc: test %r10d,%r10d
|
||||
ffffffff8104edcf: js ffffffff8104ee88 <__dequeue_signal+0x168>
|
||||
ffffffff8104edd5: mov %rax,%rdx
|
||||
ffffffff8104edd8: mov $0xc,%ecx
|
||||
ffffffff8104eddd: mov %r13,%rdi
|
||||
ffffffff8104ede0: mov $0x30,%eax
|
||||
ffffffff8104ede5: mov %rdx,%rsi
|
||||
ffffffff8104ede8: rep movsl %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edea: test $0x2,%al
|
||||
ffffffff8104edec: je ffffffff8104edf0 <__dequeue_signal+0xd0>
|
||||
ffffffff8104edee: movsw %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edf0: test $0x1,%al
|
||||
ffffffff8104edf2: je ffffffff8104edf5 <__dequeue_signal+0xd5>
|
||||
ffffffff8104edf4: movsb %ds:(%rsi),%es:(%rdi)
|
||||
ffffffff8104edf5: mov %r8,%rdi
|
||||
ffffffff8104edf8: callq ffffffff8104de60 <__sigqueue_free>
|
||||
|
||||
As expected, it's the "``rep movsl``" instruction from the ``memcpy()``
|
||||
that causes the warning. We know about ``REP MOVSL`` that it uses the register
|
||||
``RCX`` to count the number of remaining iterations. By taking a look at the
|
||||
register dump again (from the kmemcheck report), we can figure out how many
|
||||
bytes were left to copy::
|
||||
|
||||
RAX: 0000000000000030 RBX: ffff88003d4ea968 RCX: 0000000000000009
|
||||
|
||||
By looking at the disassembly, we also see that ``%ecx`` is being loaded
|
||||
with the value ``$0xc`` just before (ffffffff8104edd8), so we are very
|
||||
lucky. Keep in mind that this is the number of iterations, not bytes. And
|
||||
since this is a "long" operation, we need to multiply by 4 to get the
|
||||
number of bytes. So this means that the uninitialized value was encountered
|
||||
at 4 * (0xc - 0x9) = 12 bytes from the start of the object.
|
||||
|
||||
We can now try to figure out which field of the "``struct siginfo``" that
|
||||
was not initialized. This is the beginning of the struct::
|
||||
|
||||
40 typedef struct siginfo {
|
||||
41 int si_signo;
|
||||
42 int si_errno;
|
||||
43 int si_code;
|
||||
44
|
||||
45 union {
|
||||
..
|
||||
92 } _sifields;
|
||||
93 } siginfo_t;
|
||||
|
||||
On 64-bit, the int is 4 bytes long, so it must the union member that has
|
||||
not been initialized. We can verify this using gdb::
|
||||
|
||||
$ gdb vmlinux
|
||||
...
|
||||
(gdb) p &((struct siginfo *) 0)->_sifields
|
||||
$1 = (union {...} *) 0x10
|
||||
|
||||
Actually, it seems that the union member is located at offset 0x10 -- which
|
||||
means that gcc has inserted 4 bytes of padding between the members ``si_code``
|
||||
and ``_sifields``. We can now get a fuller picture of the memory dump::
|
||||
|
||||
_----------------------------=> si_code
|
||||
/ _--------------------=> (padding)
|
||||
| / _------------=> _sifields(._kill._pid)
|
||||
| | / _----=> _sifields(._kill._uid)
|
||||
| | | /
|
||||
-------|-------|-------|-------|
|
||||
80000000000000000000000000000000000000000088ffff0000000000000000
|
||||
i i i i u u u u i i i i i i i i u u u u u u u u u u u u u u u u
|
||||
|
||||
This allows us to realize another important fact: ``si_code`` contains the
|
||||
value 0x80. Remember that x86 is little endian, so the first 4 bytes
|
||||
"80000000" are really the number 0x00000080. With a bit of research, we
|
||||
find that this is actually the constant ``SI_KERNEL`` defined in
|
||||
``include/asm-generic/siginfo.h``::
|
||||
|
||||
144 #define SI_KERNEL 0x80 /* sent by the kernel from somewhere */
|
||||
|
||||
This macro is used in exactly one place in the x86 kernel: In ``send_signal()``
|
||||
in ``kernel/signal.c``::
|
||||
|
||||
816 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
|
||||
817 int group)
|
||||
818 {
|
||||
...
|
||||
828 pending = group ? &t->signal->shared_pending : &t->pending;
|
||||
...
|
||||
851 q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
|
||||
852 (is_si_special(info) ||
|
||||
853 info->si_code >= 0)));
|
||||
854 if (q) {
|
||||
855 list_add_tail(&q->list, &pending->list);
|
||||
856 switch ((unsigned long) info) {
|
||||
...
|
||||
865 case (unsigned long) SEND_SIG_PRIV:
|
||||
866 q->info.si_signo = sig;
|
||||
867 q->info.si_errno = 0;
|
||||
868 q->info.si_code = SI_KERNEL;
|
||||
869 q->info.si_pid = 0;
|
||||
870 q->info.si_uid = 0;
|
||||
871 break;
|
||||
...
|
||||
890 }
|
||||
|
||||
Not only does this match with the ``.si_code`` member, it also matches the place
|
||||
we found earlier when looking for where siginfo_t objects are enqueued on the
|
||||
``shared_pending`` list.
|
||||
|
||||
So to sum up: It seems that it is the padding introduced by the compiler
|
||||
between two struct fields that is uninitialized, and this gets reported when
|
||||
we do a ``memcpy()`` on the struct. This means that we have identified a false
|
||||
positive warning.
|
||||
|
||||
Normally, kmemcheck will not report uninitialized accesses in ``memcpy()`` calls
|
||||
when both the source and destination addresses are tracked. (Instead, we copy
|
||||
the shadow bytemap as well). In this case, the destination address clearly
|
||||
was not tracked. We can dig a little deeper into the stack trace from above::
|
||||
|
||||
arch/x86/kernel/signal.c:805
|
||||
arch/x86/kernel/signal.c:871
|
||||
arch/x86/kernel/entry_64.S:694
|
||||
|
||||
And we clearly see that the destination siginfo object is located on the
|
||||
stack::
|
||||
|
||||
782 static void do_signal(struct pt_regs *regs)
|
||||
783 {
|
||||
784 struct k_sigaction ka;
|
||||
785 siginfo_t info;
|
||||
...
|
||||
804 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
||||
...
|
||||
854 }
|
||||
|
||||
And this ``&info`` is what eventually gets passed to ``copy_siginfo()`` as the
|
||||
destination argument.
|
||||
|
||||
Now, even though we didn't find an actual error here, the example is still a
|
||||
good one, because it shows how one would go about to find out what the report
|
||||
was all about.
|
||||
|
||||
|
||||
Annotating false positives
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are a few different ways to make annotations in the source code that
|
||||
will keep kmemcheck from checking and reporting certain allocations. Here
|
||||
they are:
|
||||
|
||||
- ``__GFP_NOTRACK_FALSE_POSITIVE``
|
||||
This flag can be passed to ``kmalloc()`` or ``kmem_cache_alloc()``
|
||||
(therefore also to other functions that end up calling one of
|
||||
these) to indicate that the allocation should not be tracked
|
||||
because it would lead to a false positive report. This is a "big
|
||||
hammer" way of silencing kmemcheck; after all, even if the false
|
||||
positive pertains to particular field in a struct, for example, we
|
||||
will now lose the ability to find (real) errors in other parts of
|
||||
the same struct.
|
||||
|
||||
Example::
|
||||
|
||||
/* No warnings will ever trigger on accessing any part of x */
|
||||
x = kmalloc(sizeof *x, GFP_KERNEL | __GFP_NOTRACK_FALSE_POSITIVE);
|
||||
|
||||
- ``kmemcheck_bitfield_begin(name)``/``kmemcheck_bitfield_end(name)`` and
|
||||
``kmemcheck_annotate_bitfield(ptr, name)``
|
||||
The first two of these three macros can be used inside struct
|
||||
definitions to signal, respectively, the beginning and end of a
|
||||
bitfield. Additionally, this will assign the bitfield a name, which
|
||||
is given as an argument to the macros.
|
||||
|
||||
Having used these markers, one can later use
|
||||
kmemcheck_annotate_bitfield() at the point of allocation, to indicate
|
||||
which parts of the allocation is part of a bitfield.
|
||||
|
||||
Example::
|
||||
|
||||
struct foo {
|
||||
int x;
|
||||
|
||||
kmemcheck_bitfield_begin(flags);
|
||||
int flag_a:1;
|
||||
int flag_b:1;
|
||||
kmemcheck_bitfield_end(flags);
|
||||
|
||||
int y;
|
||||
};
|
||||
|
||||
struct foo *x = kmalloc(sizeof *x);
|
||||
|
||||
/* No warnings will trigger on accessing the bitfield of x */
|
||||
kmemcheck_annotate_bitfield(x, flags);
|
||||
|
||||
Note that ``kmemcheck_annotate_bitfield()`` can be used even before the
|
||||
return value of ``kmalloc()`` is checked -- in other words, passing NULL
|
||||
as the first argument is legal (and will do nothing).
|
||||
|
||||
|
||||
Reporting errors
|
||||
----------------
|
||||
|
||||
As we have seen, kmemcheck will produce false positive reports. Therefore, it
|
||||
is not very wise to blindly post kmemcheck warnings to mailing lists and
|
||||
maintainers. Instead, I encourage maintainers and developers to find errors
|
||||
in their own code. If you get a warning, you can try to work around it, try
|
||||
to figure out if it's a real error or not, or simply ignore it. Most
|
||||
developers know their own code and will quickly and efficiently determine the
|
||||
root cause of a kmemcheck report. This is therefore also the most efficient
|
||||
way to work with kmemcheck.
|
||||
|
||||
That said, we (the kmemcheck maintainers) will always be on the lookout for
|
||||
false positives that we can annotate and silence. So whatever you find,
|
||||
please drop us a note privately! Kernel configs and steps to reproduce (if
|
||||
available) are of course a great help too.
|
||||
|
||||
Happy hacking!
|
||||
|
||||
|
||||
Technical description
|
||||
---------------------
|
||||
|
||||
kmemcheck works by marking memory pages non-present. This means that whenever
|
||||
somebody attempts to access the page, a page fault is generated. The page
|
||||
fault handler notices that the page was in fact only hidden, and so it calls
|
||||
on the kmemcheck code to make further investigations.
|
||||
|
||||
When the investigations are completed, kmemcheck "shows" the page by marking
|
||||
it present (as it would be under normal circumstances). This way, the
|
||||
interrupted code can continue as usual.
|
||||
|
||||
But after the instruction has been executed, we should hide the page again, so
|
||||
that we can catch the next access too! Now kmemcheck makes use of a debugging
|
||||
feature of the processor, namely single-stepping. When the processor has
|
||||
finished the one instruction that generated the memory access, a debug
|
||||
exception is raised. From here, we simply hide the page again and continue
|
||||
execution, this time with the single-stepping feature turned off.
|
||||
|
||||
kmemcheck requires some assistance from the memory allocator in order to work.
|
||||
The memory allocator needs to
|
||||
|
||||
1. Tell kmemcheck about newly allocated pages and pages that are about to
|
||||
be freed. This allows kmemcheck to set up and tear down the shadow memory
|
||||
for the pages in question. The shadow memory stores the status of each
|
||||
byte in the allocation proper, e.g. whether it is initialized or
|
||||
uninitialized.
|
||||
|
||||
2. Tell kmemcheck which parts of memory should be marked uninitialized.
|
||||
There are actually a few more states, such as "not yet allocated" and
|
||||
"recently freed".
|
||||
|
||||
If a slab cache is set up using the SLAB_NOTRACK flag, it will never return
|
||||
memory that can take page faults because of kmemcheck.
|
||||
|
||||
If a slab cache is NOT set up using the SLAB_NOTRACK flag, callers can still
|
||||
request memory with the __GFP_NOTRACK or __GFP_NOTRACK_FALSE_POSITIVE flags.
|
||||
This does not prevent the page faults from occurring, however, but marks the
|
||||
object in question as being initialized so that no warnings will ever be
|
||||
produced for this object.
|
||||
|
||||
Currently, the SLAB and SLUB allocators are supported by kmemcheck.
|
@ -64,6 +64,6 @@ Example:
|
||||
reg = <0xe0000000 0x1000>;
|
||||
interrupts = <0 35 0x4>;
|
||||
dmas = <&dmahost 12 0 1>,
|
||||
<&dmahost 13 0 1 0>;
|
||||
<&dmahost 13 1 0>;
|
||||
dma-names = "rx", "rx";
|
||||
};
|
||||
|
@ -233,7 +233,7 @@ data_err=ignore(*) Just print an error message if an error occurs
|
||||
data_err=abort Abort the journal if an error occurs in a file
|
||||
data buffer in ordered mode.
|
||||
|
||||
grpid Give objects the same group ID as their creator.
|
||||
grpid New objects have the group ID of their parent.
|
||||
bsdgroups
|
||||
|
||||
nogrpid (*) New objects have the group ID of their creator.
|
||||
|
10
MAINTAINERS
10
MAINTAINERS
@ -7670,16 +7670,6 @@ F: include/linux/kdb.h
|
||||
F: include/linux/kgdb.h
|
||||
F: kernel/debug/
|
||||
|
||||
KMEMCHECK
|
||||
M: Vegard Nossum <vegardno@ifi.uio.no>
|
||||
M: Pekka Enberg <penberg@kernel.org>
|
||||
S: Maintained
|
||||
F: Documentation/dev-tools/kmemcheck.rst
|
||||
F: arch/x86/include/asm/kmemcheck.h
|
||||
F: arch/x86/mm/kmemcheck/
|
||||
F: include/linux/kmemcheck.h
|
||||
F: mm/kmemcheck.c
|
||||
|
||||
KMEMLEAK
|
||||
M: Catalin Marinas <catalin.marinas@arm.com>
|
||||
S: Maintained
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 20
|
||||
SUBLEVEL = 21
|
||||
EXTRAVERSION =
|
||||
NAME = Petit Gorille
|
||||
|
||||
|
@ -150,11 +150,6 @@
|
||||
interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
&charlcd {
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
&serial0 {
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
@ -333,7 +333,6 @@
|
||||
&rtc {
|
||||
clocks = <&clock CLK_RTC>;
|
||||
clock-names = "rtc";
|
||||
interrupt-parent = <&pmu_system_controller>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -156,8 +156,8 @@
|
||||
uda1380: uda1380@18 {
|
||||
compatible = "nxp,uda1380";
|
||||
reg = <0x18>;
|
||||
power-gpio = <&gpio 0x59 0>;
|
||||
reset-gpio = <&gpio 0x51 0>;
|
||||
power-gpio = <&gpio 3 10 0>;
|
||||
reset-gpio = <&gpio 3 2 0>;
|
||||
dac-clk = "wspll";
|
||||
};
|
||||
|
||||
|
@ -81,8 +81,8 @@
|
||||
uda1380: uda1380@18 {
|
||||
compatible = "nxp,uda1380";
|
||||
reg = <0x18>;
|
||||
power-gpio = <&gpio 0x59 0>;
|
||||
reset-gpio = <&gpio 0x51 0>;
|
||||
power-gpio = <&gpio 3 10 0>;
|
||||
reset-gpio = <&gpio 3 2 0>;
|
||||
dac-clk = "wspll";
|
||||
};
|
||||
|
||||
|
@ -593,6 +593,7 @@
|
||||
compatible = "mediatek,mt2701-hifsys", "syscon";
|
||||
reg = <0 0x1a000000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
usb0: usb@1a1c0000 {
|
||||
@ -677,6 +678,7 @@
|
||||
compatible = "mediatek,mt2701-ethsys", "syscon";
|
||||
reg = <0 0x1b000000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
eth: ethernet@1b100000 {
|
||||
|
@ -753,6 +753,7 @@
|
||||
"syscon";
|
||||
reg = <0 0x1b000000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
eth: ethernet@1b100000 {
|
||||
|
@ -204,7 +204,7 @@
|
||||
bus-width = <4>;
|
||||
max-frequency = <50000000>;
|
||||
cap-sd-highspeed;
|
||||
cd-gpios = <&pio 261 0>;
|
||||
cd-gpios = <&pio 261 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <&mt6323_vmch_reg>;
|
||||
vqmmc-supply = <&mt6323_vio18_reg>;
|
||||
};
|
||||
|
@ -463,6 +463,7 @@
|
||||
compatible = "samsung,exynos4210-ohci";
|
||||
reg = <0xec300000 0x100>;
|
||||
interrupts = <23>;
|
||||
interrupt-parent = <&vic1>;
|
||||
clocks = <&clocks CLK_USB_HOST>;
|
||||
clock-names = "usbhost";
|
||||
#address-cells = <1>;
|
||||
|
@ -349,7 +349,7 @@
|
||||
spi0: spi@e0100000 {
|
||||
status = "okay";
|
||||
num-cs = <3>;
|
||||
cs-gpios = <&gpio1 7 0>, <&spics 0>, <&spics 1>;
|
||||
cs-gpios = <&gpio1 7 0>, <&spics 0 0>, <&spics 1 0>;
|
||||
|
||||
stmpe610@0 {
|
||||
compatible = "st,stmpe610";
|
||||
|
@ -142,8 +142,8 @@
|
||||
reg = <0xb4100000 0x1000>;
|
||||
interrupts = <0 105 0x4>;
|
||||
status = "disabled";
|
||||
dmas = <&dwdma0 0x600 0 0 1>, /* 0xC << 11 */
|
||||
<&dwdma0 0x680 0 1 0>; /* 0xD << 7 */
|
||||
dmas = <&dwdma0 12 0 1>,
|
||||
<&dwdma0 13 1 0>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
||||
|
||||
|
@ -100,7 +100,7 @@
|
||||
reg = <0xb2800000 0x1000>;
|
||||
interrupts = <0 29 0x4>;
|
||||
status = "disabled";
|
||||
dmas = <&dwdma0 0 0 0 0>;
|
||||
dmas = <&dwdma0 0 0 0>;
|
||||
dma-names = "data";
|
||||
};
|
||||
|
||||
@ -290,8 +290,8 @@
|
||||
#size-cells = <0>;
|
||||
interrupts = <0 31 0x4>;
|
||||
status = "disabled";
|
||||
dmas = <&dwdma0 0x2000 0 0 0>, /* 0x4 << 11 */
|
||||
<&dwdma0 0x0280 0 0 0>; /* 0x5 << 7 */
|
||||
dmas = <&dwdma0 4 0 0>,
|
||||
<&dwdma0 5 0 0>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
||||
|
||||
|
@ -194,6 +194,7 @@
|
||||
rtc: rtc@fc900000 {
|
||||
compatible = "st,spear600-rtc";
|
||||
reg = <0xfc900000 0x1000>;
|
||||
interrupt-parent = <&vic0>;
|
||||
interrupts = <10>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -750,6 +750,7 @@
|
||||
reg = <0x10120000 0x1000>;
|
||||
interrupt-names = "combined";
|
||||
interrupts = <14>;
|
||||
interrupt-parent = <&vica>;
|
||||
clocks = <&clcdclk>, <&hclkclcd>;
|
||||
clock-names = "clcdclk", "apb_pclk";
|
||||
status = "disabled";
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
#include "stih407-clock.dtsi"
|
||||
#include "stih407-family.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
/ {
|
||||
soc {
|
||||
sti-display-subsystem {
|
||||
@ -122,7 +123,7 @@
|
||||
<&clk_s_d2_quadfs 0>,
|
||||
<&clk_s_d2_quadfs 1>;
|
||||
|
||||
hdmi,hpd-gpio = <&pio5 3>;
|
||||
hdmi,hpd-gpio = <&pio5 3 GPIO_ACTIVE_LOW>;
|
||||
reset-names = "hdmi";
|
||||
resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
|
||||
ddc = <&hdmiddc>;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "stih410-clock.dtsi"
|
||||
#include "stih407-family.dtsi"
|
||||
#include "stih410-pinctrl.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
/ {
|
||||
aliases {
|
||||
bdisp0 = &bdisp0;
|
||||
@ -213,7 +214,7 @@
|
||||
<&clk_s_d2_quadfs 0>,
|
||||
<&clk_s_d2_quadfs 1>;
|
||||
|
||||
hdmi,hpd-gpio = <&pio5 3>;
|
||||
hdmi,hpd-gpio = <&pio5 3 GPIO_ACTIVE_LOW>;
|
||||
reset-names = "hdmi";
|
||||
resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
|
||||
ddc = <&hdmiddc>;
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <linux/mm_types.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/dma-debug.h>
|
||||
#include <linux/kmemcheck.h>
|
||||
#include <linux/kref.h>
|
||||
|
||||
#define ARM_MAPPING_ERROR (~(dma_addr_t)0x0)
|
||||
|
@ -57,7 +57,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
|
||||
extern pgd_t *pgd_alloc(struct mm_struct *mm);
|
||||
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
|
||||
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_ZERO)
|
||||
|
||||
static inline void clean_pte_table(pte_t *pte)
|
||||
{
|
||||
|
@ -132,3 +132,7 @@ static struct platform_driver tosa_bt_driver = {
|
||||
},
|
||||
};
|
||||
module_platform_driver(tosa_bt_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Dmitry Baryshkov");
|
||||
MODULE_DESCRIPTION("Bluetooth built-in chip control");
|
||||
|
@ -901,6 +901,7 @@
|
||||
"dsi_phy_regulator";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&gcc GCC_MDSS_AHB_CLK>;
|
||||
clock-names = "iface_clk";
|
||||
@ -1430,8 +1431,8 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
qcom,ipc-1 = <&apcs 0 13>;
|
||||
qcom,ipc-6 = <&apcs 0 19>;
|
||||
qcom,ipc-1 = <&apcs 8 13>;
|
||||
qcom,ipc-3 = <&apcs 8 19>;
|
||||
|
||||
apps_smsm: apps@0 {
|
||||
reg = <0>;
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_ZERO)
|
||||
#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS > 2
|
||||
|
@ -406,6 +406,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
.capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
|
||||
MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
|
||||
},
|
||||
{
|
||||
.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
|
||||
MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR),
|
||||
.enable = qcom_enable_link_stack_sanitization,
|
||||
},
|
||||
{
|
||||
.capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
|
||||
MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR),
|
||||
},
|
||||
{
|
||||
.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
|
||||
MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
|
||||
|
@ -371,8 +371,10 @@ again:
|
||||
u32 midr = read_cpuid_id();
|
||||
|
||||
/* Apply BTAC predictors mitigation to all Falkor chips */
|
||||
if ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)
|
||||
if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) ||
|
||||
((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) {
|
||||
__qcom_hyp_sanitize_btac_predictors();
|
||||
}
|
||||
}
|
||||
|
||||
fp_enabled = __fpsimd_enabled();
|
||||
|
@ -190,7 +190,8 @@ ENDPROC(idmap_cpu_replace_ttbr1)
|
||||
dc cvac, cur_\()\type\()p // Ensure any existing dirty
|
||||
dmb sy // lines are written back before
|
||||
ldr \type, [cur_\()\type\()p] // loading the entry
|
||||
tbz \type, #0, next_\()\type // Skip invalid entries
|
||||
tbz \type, #0, skip_\()\type // Skip invalid and
|
||||
tbnz \type, #11, skip_\()\type // non-global entries
|
||||
.endm
|
||||
|
||||
.macro __idmap_kpti_put_pgtable_ent_ng, type
|
||||
@ -249,8 +250,9 @@ ENTRY(idmap_kpti_install_ng_mappings)
|
||||
add end_pgdp, cur_pgdp, #(PTRS_PER_PGD * 8)
|
||||
do_pgd: __idmap_kpti_get_pgtable_ent pgd
|
||||
tbnz pgd, #1, walk_puds
|
||||
__idmap_kpti_put_pgtable_ent_ng pgd
|
||||
next_pgd:
|
||||
__idmap_kpti_put_pgtable_ent_ng pgd
|
||||
skip_pgd:
|
||||
add cur_pgdp, cur_pgdp, #8
|
||||
cmp cur_pgdp, end_pgdp
|
||||
b.ne do_pgd
|
||||
@ -278,8 +280,9 @@ walk_puds:
|
||||
add end_pudp, cur_pudp, #(PTRS_PER_PUD * 8)
|
||||
do_pud: __idmap_kpti_get_pgtable_ent pud
|
||||
tbnz pud, #1, walk_pmds
|
||||
__idmap_kpti_put_pgtable_ent_ng pud
|
||||
next_pud:
|
||||
__idmap_kpti_put_pgtable_ent_ng pud
|
||||
skip_pud:
|
||||
add cur_pudp, cur_pudp, 8
|
||||
cmp cur_pudp, end_pudp
|
||||
b.ne do_pud
|
||||
@ -298,8 +301,9 @@ walk_pmds:
|
||||
add end_pmdp, cur_pmdp, #(PTRS_PER_PMD * 8)
|
||||
do_pmd: __idmap_kpti_get_pgtable_ent pmd
|
||||
tbnz pmd, #1, walk_ptes
|
||||
__idmap_kpti_put_pgtable_ent_ng pmd
|
||||
next_pmd:
|
||||
__idmap_kpti_put_pgtable_ent_ng pmd
|
||||
skip_pmd:
|
||||
add cur_pmdp, cur_pmdp, #8
|
||||
cmp cur_pmdp, end_pmdp
|
||||
b.ne do_pmd
|
||||
@ -317,7 +321,7 @@ walk_ptes:
|
||||
add end_ptep, cur_ptep, #(PTRS_PER_PTE * 8)
|
||||
do_pte: __idmap_kpti_get_pgtable_ent pte
|
||||
__idmap_kpti_put_pgtable_ent_ng pte
|
||||
next_pte:
|
||||
skip_pte:
|
||||
add cur_ptep, cur_ptep, #8
|
||||
cmp cur_ptep, end_ptep
|
||||
b.ne do_pte
|
||||
|
@ -119,12 +119,12 @@ config MIPS_GENERIC
|
||||
select SYS_SUPPORTS_MULTITHREADING
|
||||
select SYS_SUPPORTS_RELOCATABLE
|
||||
select SYS_SUPPORTS_SMARTMIPS
|
||||
select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
|
||||
select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
|
||||
select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
|
||||
select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
|
||||
select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
|
||||
select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
|
||||
select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||
select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||
select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||
select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||
select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||
select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||
select USE_OF
|
||||
help
|
||||
Select this to build a kernel which aims to support multiple boards,
|
||||
|
@ -374,6 +374,7 @@ static void __init bootmem_init(void)
|
||||
unsigned long reserved_end;
|
||||
unsigned long mapstart = ~0UL;
|
||||
unsigned long bootmap_size;
|
||||
phys_addr_t ramstart = (phys_addr_t)ULLONG_MAX;
|
||||
bool bootmap_valid = false;
|
||||
int i;
|
||||
|
||||
@ -394,7 +395,8 @@ static void __init bootmem_init(void)
|
||||
max_low_pfn = 0;
|
||||
|
||||
/*
|
||||
* Find the highest page frame number we have available.
|
||||
* Find the highest page frame number we have available
|
||||
* and the lowest used RAM address
|
||||
*/
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
unsigned long start, end;
|
||||
@ -406,6 +408,8 @@ static void __init bootmem_init(void)
|
||||
end = PFN_DOWN(boot_mem_map.map[i].addr
|
||||
+ boot_mem_map.map[i].size);
|
||||
|
||||
ramstart = min(ramstart, boot_mem_map.map[i].addr);
|
||||
|
||||
#ifndef CONFIG_HIGHMEM
|
||||
/*
|
||||
* Skip highmem here so we get an accurate max_low_pfn if low
|
||||
@ -435,6 +439,13 @@ static void __init bootmem_init(void)
|
||||
mapstart = max(reserved_end, start);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserve any memory between the start of RAM and PHYS_OFFSET
|
||||
*/
|
||||
if (ramstart > PHYS_OFFSET)
|
||||
add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
|
||||
BOOT_MEM_RESERVED);
|
||||
|
||||
if (min_low_pfn >= max_low_pfn)
|
||||
panic("Incorrect memory mapping !!!");
|
||||
if (min_low_pfn > ARCH_PFN_OFFSET) {
|
||||
@ -663,9 +674,6 @@ static int __init early_parse_mem(char *p)
|
||||
|
||||
add_memory_region(start, size, BOOT_MEM_RAM);
|
||||
|
||||
if (start && start > PHYS_OFFSET)
|
||||
add_memory_region(PHYS_OFFSET, start - PHYS_OFFSET,
|
||||
BOOT_MEM_RESERVED);
|
||||
return 0;
|
||||
}
|
||||
early_param("mem", early_parse_mem);
|
||||
|
@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/dma-debug.h>
|
||||
#include <linux/kmemcheck.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
extern const struct dma_map_ops or1k_dma_map_ops;
|
||||
|
@ -18,7 +18,7 @@ static inline gfp_t pgtable_gfp_flags(struct mm_struct *mm, gfp_t gfp)
|
||||
}
|
||||
#endif /* MODULE */
|
||||
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_ZERO)
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S
|
||||
#include <asm/book3s/pgalloc.h>
|
||||
|
@ -44,6 +44,11 @@ extern int sysfs_add_device_to_node(struct device *dev, int nid);
|
||||
extern void sysfs_remove_device_from_node(struct device *dev, int nid);
|
||||
extern int numa_update_cpu_topology(bool cpus_locked);
|
||||
|
||||
static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node)
|
||||
{
|
||||
numa_cpu_lookup_table[cpu] = node;
|
||||
}
|
||||
|
||||
static inline int early_cpu_to_node(int cpu)
|
||||
{
|
||||
int nid;
|
||||
|
@ -1617,7 +1617,7 @@ USE_TEXT_SECTION()
|
||||
.balign IFETCH_ALIGN_BYTES
|
||||
do_hash_page:
|
||||
#ifdef CONFIG_PPC_STD_MMU_64
|
||||
lis r0,DSISR_BAD_FAULT_64S@h
|
||||
lis r0,(DSISR_BAD_FAULT_64S|DSISR_DABRMATCH)@h
|
||||
ori r0,r0,DSISR_BAD_FAULT_64S@l
|
||||
and. r0,r4,r0 /* weird error? */
|
||||
bne- handle_page_fault /* if not, try to insert a HPTE */
|
||||
|
@ -388,7 +388,7 @@ DataAccess:
|
||||
EXCEPTION_PROLOG
|
||||
mfspr r10,SPRN_DSISR
|
||||
stw r10,_DSISR(r11)
|
||||
andis. r0,r10,DSISR_BAD_FAULT_32S@h
|
||||
andis. r0,r10,(DSISR_BAD_FAULT_32S|DSISR_DABRMATCH)@h
|
||||
bne 1f /* if not, try to put a PTE */
|
||||
mfspr r4,SPRN_DAR /* into the hash table */
|
||||
rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */
|
||||
|
@ -142,11 +142,6 @@ static void reset_numa_cpu_lookup_table(void)
|
||||
numa_cpu_lookup_table[cpu] = -1;
|
||||
}
|
||||
|
||||
static void update_numa_cpu_lookup_table(unsigned int cpu, int node)
|
||||
{
|
||||
numa_cpu_lookup_table[cpu] = node;
|
||||
}
|
||||
|
||||
static void map_cpu_to_node(int cpu, int node)
|
||||
{
|
||||
update_numa_cpu_lookup_table(cpu, node);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/string_helpers.h>
|
||||
#include <linux/stop_machine.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
@ -671,6 +672,30 @@ static void free_pmd_table(pmd_t *pmd_start, pud_t *pud)
|
||||
pud_clear(pud);
|
||||
}
|
||||
|
||||
struct change_mapping_params {
|
||||
pte_t *pte;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
unsigned long aligned_start;
|
||||
unsigned long aligned_end;
|
||||
};
|
||||
|
||||
static int stop_machine_change_mapping(void *data)
|
||||
{
|
||||
struct change_mapping_params *params =
|
||||
(struct change_mapping_params *)data;
|
||||
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
spin_unlock(&init_mm.page_table_lock);
|
||||
pte_clear(&init_mm, params->aligned_start, params->pte);
|
||||
create_physical_mapping(params->aligned_start, params->start);
|
||||
create_physical_mapping(params->end, params->aligned_end);
|
||||
spin_lock(&init_mm.page_table_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void remove_pte_table(pte_t *pte_start, unsigned long addr,
|
||||
unsigned long end)
|
||||
{
|
||||
@ -699,6 +724,52 @@ static void remove_pte_table(pte_t *pte_start, unsigned long addr,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* clear the pte and potentially split the mapping helper
|
||||
*/
|
||||
static void split_kernel_mapping(unsigned long addr, unsigned long end,
|
||||
unsigned long size, pte_t *pte)
|
||||
{
|
||||
unsigned long mask = ~(size - 1);
|
||||
unsigned long aligned_start = addr & mask;
|
||||
unsigned long aligned_end = addr + size;
|
||||
struct change_mapping_params params;
|
||||
bool split_region = false;
|
||||
|
||||
if ((end - addr) < size) {
|
||||
/*
|
||||
* We're going to clear the PTE, but not flushed
|
||||
* the mapping, time to remap and flush. The
|
||||
* effects if visible outside the processor or
|
||||
* if we are running in code close to the
|
||||
* mapping we cleared, we are in trouble.
|
||||
*/
|
||||
if (overlaps_kernel_text(aligned_start, addr) ||
|
||||
overlaps_kernel_text(end, aligned_end)) {
|
||||
/*
|
||||
* Hack, just return, don't pte_clear
|
||||
*/
|
||||
WARN_ONCE(1, "Linear mapping %lx->%lx overlaps kernel "
|
||||
"text, not splitting\n", addr, end);
|
||||
return;
|
||||
}
|
||||
split_region = true;
|
||||
}
|
||||
|
||||
if (split_region) {
|
||||
params.pte = pte;
|
||||
params.start = addr;
|
||||
params.end = end;
|
||||
params.aligned_start = addr & ~(size - 1);
|
||||
params.aligned_end = min_t(unsigned long, aligned_end,
|
||||
(unsigned long)__va(memblock_end_of_DRAM()));
|
||||
stop_machine(stop_machine_change_mapping, ¶ms, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
pte_clear(&init_mm, addr, pte);
|
||||
}
|
||||
|
||||
static void remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
|
||||
unsigned long end)
|
||||
{
|
||||
@ -714,13 +785,7 @@ static void remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
|
||||
continue;
|
||||
|
||||
if (pmd_huge(*pmd)) {
|
||||
if (!IS_ALIGNED(addr, PMD_SIZE) ||
|
||||
!IS_ALIGNED(next, PMD_SIZE)) {
|
||||
WARN_ONCE(1, "%s: unaligned range\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
pte_clear(&init_mm, addr, (pte_t *)pmd);
|
||||
split_kernel_mapping(addr, end, PMD_SIZE, (pte_t *)pmd);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -745,13 +810,7 @@ static void remove_pud_table(pud_t *pud_start, unsigned long addr,
|
||||
continue;
|
||||
|
||||
if (pud_huge(*pud)) {
|
||||
if (!IS_ALIGNED(addr, PUD_SIZE) ||
|
||||
!IS_ALIGNED(next, PUD_SIZE)) {
|
||||
WARN_ONCE(1, "%s: unaligned range\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
pte_clear(&init_mm, addr, (pte_t *)pud);
|
||||
split_kernel_mapping(addr, end, PUD_SIZE, (pte_t *)pud);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -777,13 +836,7 @@ static void remove_pagetable(unsigned long start, unsigned long end)
|
||||
continue;
|
||||
|
||||
if (pgd_huge(*pgd)) {
|
||||
if (!IS_ALIGNED(addr, PGDIR_SIZE) ||
|
||||
!IS_ALIGNED(next, PGDIR_SIZE)) {
|
||||
WARN_ONCE(1, "%s: unaligned range\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
pte_clear(&init_mm, addr, (pte_t *)pgd);
|
||||
split_kernel_mapping(addr, end, PGDIR_SIZE, (pte_t *)pgd);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -483,6 +483,8 @@ void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
|
||||
if (old & PATB_HR) {
|
||||
asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
|
||||
"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
|
||||
asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
|
||||
"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
|
||||
trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
|
||||
} else {
|
||||
asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
|
||||
|
@ -453,14 +453,12 @@ void radix__flush_tlb_all(void)
|
||||
*/
|
||||
asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
|
||||
: : "r"(rb), "i"(r), "i"(1), "i"(ric), "r"(rs) : "memory");
|
||||
trace_tlbie(0, 0, rb, rs, ric, prs, r);
|
||||
/*
|
||||
* now flush host entires by passing PRS = 0 and LPID == 0
|
||||
*/
|
||||
asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
|
||||
: : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(0) : "memory");
|
||||
asm volatile("eieio; tlbsync; ptesync": : :"memory");
|
||||
trace_tlbie(0, 0, rb, 0, ric, prs, r);
|
||||
}
|
||||
|
||||
void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm,
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <asm/xics.h>
|
||||
#include <asm/xive.h>
|
||||
#include <asm/plpar_wrappers.h>
|
||||
#include <asm/topology.h>
|
||||
|
||||
#include "pseries.h"
|
||||
#include "offline_states.h"
|
||||
@ -331,6 +332,7 @@ static void pseries_remove_processor(struct device_node *np)
|
||||
BUG_ON(cpu_online(cpu));
|
||||
set_cpu_present(cpu, false);
|
||||
set_hard_smp_processor_id(cpu, -1);
|
||||
update_numa_cpu_lookup_table(cpu, -1);
|
||||
break;
|
||||
}
|
||||
if (cpu >= nr_cpu_ids)
|
||||
|
@ -356,7 +356,8 @@ static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio,
|
||||
|
||||
rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size);
|
||||
if (rc) {
|
||||
pr_err("Error %lld getting queue info prio %d\n", rc, prio);
|
||||
pr_err("Error %lld getting queue info CPU %d prio %d\n", rc,
|
||||
target, prio);
|
||||
rc = -EIO;
|
||||
goto fail;
|
||||
}
|
||||
@ -370,7 +371,8 @@ static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio,
|
||||
/* Configure and enable the queue in HW */
|
||||
rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order);
|
||||
if (rc) {
|
||||
pr_err("Error %lld setting queue for prio %d\n", rc, prio);
|
||||
pr_err("Error %lld setting queue for CPU %d prio %d\n", rc,
|
||||
target, prio);
|
||||
rc = -EIO;
|
||||
} else {
|
||||
q->qpage = qpage;
|
||||
@ -389,8 +391,8 @@ static int xive_spapr_setup_queue(unsigned int cpu, struct xive_cpu *xc,
|
||||
if (IS_ERR(qpage))
|
||||
return PTR_ERR(qpage);
|
||||
|
||||
return xive_spapr_configure_queue(cpu, q, prio, qpage,
|
||||
xive_queue_shift);
|
||||
return xive_spapr_configure_queue(get_hard_smp_processor_id(cpu),
|
||||
q, prio, qpage, xive_queue_shift);
|
||||
}
|
||||
|
||||
static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc,
|
||||
@ -399,10 +401,12 @@ static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc,
|
||||
struct xive_q *q = &xc->queue[prio];
|
||||
unsigned int alloc_order;
|
||||
long rc;
|
||||
int hw_cpu = get_hard_smp_processor_id(cpu);
|
||||
|
||||
rc = plpar_int_set_queue_config(0, cpu, prio, 0, 0);
|
||||
rc = plpar_int_set_queue_config(0, hw_cpu, prio, 0, 0);
|
||||
if (rc)
|
||||
pr_err("Error %ld setting queue for prio %d\n", rc, prio);
|
||||
pr_err("Error %ld setting queue for CPU %d prio %d\n", rc,
|
||||
hw_cpu, prio);
|
||||
|
||||
alloc_order = xive_alloc_order(xive_queue_shift);
|
||||
free_pages((unsigned long)q->qpage, alloc_order);
|
||||
|
@ -110,7 +110,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid)
|
||||
|
||||
COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid)
|
||||
{
|
||||
return sys_setgid((gid_t)gid);
|
||||
return sys_setgid(low2highgid(gid));
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid)
|
||||
@ -120,7 +120,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid)
|
||||
|
||||
COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid)
|
||||
{
|
||||
return sys_setuid((uid_t)uid);
|
||||
return sys_setuid(low2highuid(uid));
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid)
|
||||
@ -173,12 +173,12 @@ COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp,
|
||||
|
||||
COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid)
|
||||
{
|
||||
return sys_setfsuid((uid_t)uid);
|
||||
return sys_setfsuid(low2highuid(uid));
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid)
|
||||
{
|
||||
return sys_setfsgid((gid_t)gid);
|
||||
return sys_setfsgid(low2highgid(gid));
|
||||
}
|
||||
|
||||
static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
|
||||
|
@ -1172,11 +1172,11 @@ static int __init dwarf_unwinder_init(void)
|
||||
|
||||
dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
|
||||
sizeof(struct dwarf_frame), 0,
|
||||
SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
|
||||
SLAB_PANIC | SLAB_HWCACHE_ALIGN, NULL);
|
||||
|
||||
dwarf_reg_cachep = kmem_cache_create("dwarf_regs",
|
||||
sizeof(struct dwarf_reg), 0,
|
||||
SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
|
||||
SLAB_PANIC | SLAB_HWCACHE_ALIGN, NULL);
|
||||
|
||||
dwarf_frame_pool = mempool_create_slab_pool(DWARF_FRAME_MIN_REQ,
|
||||
dwarf_frame_cachep);
|
||||
|
@ -59,7 +59,7 @@ void arch_task_cache_init(void)
|
||||
|
||||
task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size,
|
||||
__alignof__(union thread_xstate),
|
||||
SLAB_PANIC | SLAB_NOTRACK, NULL);
|
||||
SLAB_PANIC, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SH_FPU_EMU
|
||||
|
@ -2934,7 +2934,7 @@ void __flush_tlb_all(void)
|
||||
pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
|
||||
unsigned long address)
|
||||
{
|
||||
struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
|
||||
struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
pte_t *pte = NULL;
|
||||
|
||||
if (page)
|
||||
@ -2946,7 +2946,7 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
|
||||
pgtable_t pte_alloc_one(struct mm_struct *mm,
|
||||
unsigned long address)
|
||||
{
|
||||
struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
|
||||
struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (!page)
|
||||
return NULL;
|
||||
if (!pgtable_page_ctor(page)) {
|
||||
|
@ -28,7 +28,7 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
|
||||
#define pgd_alloc(mm) get_pgd_slow(mm)
|
||||
#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
|
||||
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_ZERO)
|
||||
|
||||
/*
|
||||
* Allocate one PTE table.
|
||||
|
@ -111,7 +111,6 @@ config X86
|
||||
select HAVE_ARCH_JUMP_LABEL
|
||||
select HAVE_ARCH_KASAN if X86_64
|
||||
select HAVE_ARCH_KGDB
|
||||
select HAVE_ARCH_KMEMCHECK
|
||||
select HAVE_ARCH_MMAP_RND_BITS if MMU
|
||||
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT
|
||||
select HAVE_ARCH_COMPAT_MMAP_BASES if MMU && COMPAT
|
||||
@ -1443,7 +1442,7 @@ config ARCH_DMA_ADDR_T_64BIT
|
||||
|
||||
config X86_DIRECT_GBPAGES
|
||||
def_bool y
|
||||
depends on X86_64 && !DEBUG_PAGEALLOC && !KMEMCHECK
|
||||
depends on X86_64 && !DEBUG_PAGEALLOC
|
||||
---help---
|
||||
Certain kernel features effectively disable kernel
|
||||
linear 1 GB mappings (even if the CPU otherwise
|
||||
|
@ -160,11 +160,6 @@ ifdef CONFIG_X86_X32
|
||||
endif
|
||||
export CONFIG_X86_X32_ABI
|
||||
|
||||
# Don't unroll struct assignments with kmemcheck enabled
|
||||
ifeq ($(CONFIG_KMEMCHECK),y)
|
||||
KBUILD_CFLAGS += $(call cc-option,-fno-builtin-memcpy)
|
||||
endif
|
||||
|
||||
#
|
||||
# If the function graph tracer is used with mcount instead of fentry,
|
||||
# '-maccumulate-outgoing-args' is needed to prevent a GCC bug
|
||||
|
@ -97,80 +97,69 @@ For 32-bit we have the following conventions - kernel is built with
|
||||
|
||||
#define SIZEOF_PTREGS 21*8
|
||||
|
||||
.macro ALLOC_PT_GPREGS_ON_STACK
|
||||
addq $-(15*8), %rsp
|
||||
.endm
|
||||
.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax
|
||||
/*
|
||||
* Push registers and sanitize registers of values that a
|
||||
* speculation attack might otherwise want to exploit. The
|
||||
* lower registers are likely clobbered well before they
|
||||
* could be put to use in a speculative execution gadget.
|
||||
* Interleave XOR with PUSH for better uop scheduling:
|
||||
*/
|
||||
pushq %rdi /* pt_regs->di */
|
||||
pushq %rsi /* pt_regs->si */
|
||||
pushq \rdx /* pt_regs->dx */
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq \rax /* pt_regs->ax */
|
||||
pushq %r8 /* pt_regs->r8 */
|
||||
xorq %r8, %r8 /* nospec r8 */
|
||||
pushq %r9 /* pt_regs->r9 */
|
||||
xorq %r9, %r9 /* nospec r9 */
|
||||
pushq %r10 /* pt_regs->r10 */
|
||||
xorq %r10, %r10 /* nospec r10 */
|
||||
pushq %r11 /* pt_regs->r11 */
|
||||
xorq %r11, %r11 /* nospec r11*/
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
xorl %ebx, %ebx /* nospec rbx*/
|
||||
pushq %rbp /* pt_regs->rbp */
|
||||
xorl %ebp, %ebp /* nospec rbp*/
|
||||
pushq %r12 /* pt_regs->r12 */
|
||||
xorq %r12, %r12 /* nospec r12*/
|
||||
pushq %r13 /* pt_regs->r13 */
|
||||
xorq %r13, %r13 /* nospec r13*/
|
||||
pushq %r14 /* pt_regs->r14 */
|
||||
xorq %r14, %r14 /* nospec r14*/
|
||||
pushq %r15 /* pt_regs->r15 */
|
||||
xorq %r15, %r15 /* nospec r15*/
|
||||
UNWIND_HINT_REGS
|
||||
.endm
|
||||
|
||||
.macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8910=1 r11=1
|
||||
.if \r11
|
||||
movq %r11, 6*8+\offset(%rsp)
|
||||
.endif
|
||||
.if \r8910
|
||||
movq %r10, 7*8+\offset(%rsp)
|
||||
movq %r9, 8*8+\offset(%rsp)
|
||||
movq %r8, 9*8+\offset(%rsp)
|
||||
.endif
|
||||
.if \rax
|
||||
movq %rax, 10*8+\offset(%rsp)
|
||||
.endif
|
||||
.if \rcx
|
||||
movq %rcx, 11*8+\offset(%rsp)
|
||||
.endif
|
||||
movq %rdx, 12*8+\offset(%rsp)
|
||||
movq %rsi, 13*8+\offset(%rsp)
|
||||
movq %rdi, 14*8+\offset(%rsp)
|
||||
UNWIND_HINT_REGS offset=\offset extra=0
|
||||
.endm
|
||||
.macro SAVE_C_REGS offset=0
|
||||
SAVE_C_REGS_HELPER \offset, 1, 1, 1, 1
|
||||
.endm
|
||||
.macro SAVE_C_REGS_EXCEPT_RAX_RCX offset=0
|
||||
SAVE_C_REGS_HELPER \offset, 0, 0, 1, 1
|
||||
.endm
|
||||
.macro SAVE_C_REGS_EXCEPT_R891011
|
||||
SAVE_C_REGS_HELPER 0, 1, 1, 0, 0
|
||||
.endm
|
||||
.macro SAVE_C_REGS_EXCEPT_RCX_R891011
|
||||
SAVE_C_REGS_HELPER 0, 1, 0, 0, 0
|
||||
.endm
|
||||
.macro SAVE_C_REGS_EXCEPT_RAX_RCX_R11
|
||||
SAVE_C_REGS_HELPER 0, 0, 0, 1, 0
|
||||
.endm
|
||||
|
||||
.macro SAVE_EXTRA_REGS offset=0
|
||||
movq %r15, 0*8+\offset(%rsp)
|
||||
movq %r14, 1*8+\offset(%rsp)
|
||||
movq %r13, 2*8+\offset(%rsp)
|
||||
movq %r12, 3*8+\offset(%rsp)
|
||||
movq %rbp, 4*8+\offset(%rsp)
|
||||
movq %rbx, 5*8+\offset(%rsp)
|
||||
UNWIND_HINT_REGS offset=\offset
|
||||
.endm
|
||||
|
||||
.macro POP_EXTRA_REGS
|
||||
.macro POP_REGS pop_rdi=1 skip_r11rcx=0
|
||||
popq %r15
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
popq %rbp
|
||||
popq %rbx
|
||||
.endm
|
||||
|
||||
.macro POP_C_REGS
|
||||
.if \skip_r11rcx
|
||||
popq %rsi
|
||||
.else
|
||||
popq %r11
|
||||
.endif
|
||||
popq %r10
|
||||
popq %r9
|
||||
popq %r8
|
||||
popq %rax
|
||||
.if \skip_r11rcx
|
||||
popq %rsi
|
||||
.else
|
||||
popq %rcx
|
||||
.endif
|
||||
popq %rdx
|
||||
popq %rsi
|
||||
.if \pop_rdi
|
||||
popq %rdi
|
||||
.endm
|
||||
|
||||
.macro icebp
|
||||
.byte 0xf1
|
||||
.endm
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This is a sneaky trick to help the unwinder find pt_regs on the stack. The
|
||||
@ -178,7 +167,7 @@ For 32-bit we have the following conventions - kernel is built with
|
||||
* is just setting the LSB, which makes it an invalid stack address and is also
|
||||
* a signal to the unwinder that it's a pt_regs pointer in disguise.
|
||||
*
|
||||
* NOTE: This macro must be used *after* SAVE_EXTRA_REGS because it corrupts
|
||||
* NOTE: This macro must be used *after* PUSH_AND_CLEAR_REGS because it corrupts
|
||||
* the original rbp.
|
||||
*/
|
||||
.macro ENCODE_FRAME_POINTER ptregs_offset=0
|
||||
|
@ -209,7 +209,7 @@ ENTRY(entry_SYSCALL_64)
|
||||
|
||||
swapgs
|
||||
/*
|
||||
* This path is not taken when PAGE_TABLE_ISOLATION is disabled so it
|
||||
* This path is only taken when PAGE_TABLE_ISOLATION is disabled so it
|
||||
* is not required to switch CR3.
|
||||
*/
|
||||
movq %rsp, PER_CPU_VAR(rsp_scratch)
|
||||
@ -223,22 +223,8 @@ ENTRY(entry_SYSCALL_64)
|
||||
pushq %rcx /* pt_regs->ip */
|
||||
GLOBAL(entry_SYSCALL_64_after_hwframe)
|
||||
pushq %rax /* pt_regs->orig_ax */
|
||||
pushq %rdi /* pt_regs->di */
|
||||
pushq %rsi /* pt_regs->si */
|
||||
pushq %rdx /* pt_regs->dx */
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
pushq %r8 /* pt_regs->r8 */
|
||||
pushq %r9 /* pt_regs->r9 */
|
||||
pushq %r10 /* pt_regs->r10 */
|
||||
pushq %r11 /* pt_regs->r11 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
pushq %rbp /* pt_regs->rbp */
|
||||
pushq %r12 /* pt_regs->r12 */
|
||||
pushq %r13 /* pt_regs->r13 */
|
||||
pushq %r14 /* pt_regs->r14 */
|
||||
pushq %r15 /* pt_regs->r15 */
|
||||
UNWIND_HINT_REGS
|
||||
|
||||
PUSH_AND_CLEAR_REGS rax=$-ENOSYS
|
||||
|
||||
TRACE_IRQS_OFF
|
||||
|
||||
@ -317,15 +303,7 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
|
||||
syscall_return_via_sysret:
|
||||
/* rcx and r11 are already restored (see code above) */
|
||||
UNWIND_HINT_EMPTY
|
||||
POP_EXTRA_REGS
|
||||
popq %rsi /* skip r11 */
|
||||
popq %r10
|
||||
popq %r9
|
||||
popq %r8
|
||||
popq %rax
|
||||
popq %rsi /* skip rcx */
|
||||
popq %rdx
|
||||
popq %rsi
|
||||
POP_REGS pop_rdi=0 skip_r11rcx=1
|
||||
|
||||
/*
|
||||
* Now all regs are restored except RSP and RDI.
|
||||
@ -555,9 +533,7 @@ END(irq_entries_start)
|
||||
call switch_to_thread_stack
|
||||
1:
|
||||
|
||||
ALLOC_PT_GPREGS_ON_STACK
|
||||
SAVE_C_REGS
|
||||
SAVE_EXTRA_REGS
|
||||
PUSH_AND_CLEAR_REGS
|
||||
ENCODE_FRAME_POINTER
|
||||
|
||||
testb $3, CS(%rsp)
|
||||
@ -618,15 +594,7 @@ GLOBAL(swapgs_restore_regs_and_return_to_usermode)
|
||||
ud2
|
||||
1:
|
||||
#endif
|
||||
POP_EXTRA_REGS
|
||||
popq %r11
|
||||
popq %r10
|
||||
popq %r9
|
||||
popq %r8
|
||||
popq %rax
|
||||
popq %rcx
|
||||
popq %rdx
|
||||
popq %rsi
|
||||
POP_REGS pop_rdi=0
|
||||
|
||||
/*
|
||||
* The stack is now user RDI, orig_ax, RIP, CS, EFLAGS, RSP, SS.
|
||||
@ -684,8 +652,7 @@ GLOBAL(restore_regs_and_return_to_kernel)
|
||||
ud2
|
||||
1:
|
||||
#endif
|
||||
POP_EXTRA_REGS
|
||||
POP_C_REGS
|
||||
POP_REGS
|
||||
addq $8, %rsp /* skip regs->orig_ax */
|
||||
INTERRUPT_RETURN
|
||||
|
||||
@ -900,7 +867,9 @@ ENTRY(\sym)
|
||||
pushq $-1 /* ORIG_RAX: no syscall to restart */
|
||||
.endif
|
||||
|
||||
ALLOC_PT_GPREGS_ON_STACK
|
||||
/* Save all registers in pt_regs */
|
||||
PUSH_AND_CLEAR_REGS
|
||||
ENCODE_FRAME_POINTER
|
||||
|
||||
.if \paranoid < 2
|
||||
testb $3, CS(%rsp) /* If coming from userspace, switch stacks */
|
||||
@ -1111,9 +1080,7 @@ ENTRY(xen_failsafe_callback)
|
||||
addq $0x30, %rsp
|
||||
UNWIND_HINT_IRET_REGS
|
||||
pushq $-1 /* orig_ax = -1 => not a system call */
|
||||
ALLOC_PT_GPREGS_ON_STACK
|
||||
SAVE_C_REGS
|
||||
SAVE_EXTRA_REGS
|
||||
PUSH_AND_CLEAR_REGS
|
||||
ENCODE_FRAME_POINTER
|
||||
jmp error_exit
|
||||
END(xen_failsafe_callback)
|
||||
@ -1150,16 +1117,13 @@ idtentry machine_check do_mce has_error_code=0 paranoid=1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Save all registers in pt_regs, and switch gs if needed.
|
||||
* Switch gs if needed.
|
||||
* Use slow, but surefire "are we in kernel?" check.
|
||||
* Return: ebx=0: need swapgs on exit, ebx=1: otherwise
|
||||
*/
|
||||
ENTRY(paranoid_entry)
|
||||
UNWIND_HINT_FUNC
|
||||
cld
|
||||
SAVE_C_REGS 8
|
||||
SAVE_EXTRA_REGS 8
|
||||
ENCODE_FRAME_POINTER 8
|
||||
movl $1, %ebx
|
||||
movl $MSR_GS_BASE, %ecx
|
||||
rdmsr
|
||||
@ -1198,21 +1162,18 @@ ENTRY(paranoid_exit)
|
||||
jmp .Lparanoid_exit_restore
|
||||
.Lparanoid_exit_no_swapgs:
|
||||
TRACE_IRQS_IRETQ_DEBUG
|
||||
RESTORE_CR3 scratch_reg=%rbx save_reg=%r14
|
||||
.Lparanoid_exit_restore:
|
||||
jmp restore_regs_and_return_to_kernel
|
||||
END(paranoid_exit)
|
||||
|
||||
/*
|
||||
* Save all registers in pt_regs, and switch gs if needed.
|
||||
* Switch gs if needed.
|
||||
* Return: EBX=0: came from user mode; EBX=1: otherwise
|
||||
*/
|
||||
ENTRY(error_entry)
|
||||
UNWIND_HINT_FUNC
|
||||
UNWIND_HINT_REGS offset=8
|
||||
cld
|
||||
SAVE_C_REGS 8
|
||||
SAVE_EXTRA_REGS 8
|
||||
ENCODE_FRAME_POINTER 8
|
||||
xorl %ebx, %ebx
|
||||
testb $3, CS+8(%rsp)
|
||||
jz .Lerror_kernelspace
|
||||
|
||||
@ -1393,22 +1354,7 @@ ENTRY(nmi)
|
||||
pushq 1*8(%rdx) /* pt_regs->rip */
|
||||
UNWIND_HINT_IRET_REGS
|
||||
pushq $-1 /* pt_regs->orig_ax */
|
||||
pushq %rdi /* pt_regs->di */
|
||||
pushq %rsi /* pt_regs->si */
|
||||
pushq (%rdx) /* pt_regs->dx */
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq %rax /* pt_regs->ax */
|
||||
pushq %r8 /* pt_regs->r8 */
|
||||
pushq %r9 /* pt_regs->r9 */
|
||||
pushq %r10 /* pt_regs->r10 */
|
||||
pushq %r11 /* pt_regs->r11 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
pushq %rbp /* pt_regs->rbp */
|
||||
pushq %r12 /* pt_regs->r12 */
|
||||
pushq %r13 /* pt_regs->r13 */
|
||||
pushq %r14 /* pt_regs->r14 */
|
||||
pushq %r15 /* pt_regs->r15 */
|
||||
UNWIND_HINT_REGS
|
||||
PUSH_AND_CLEAR_REGS rdx=(%rdx)
|
||||
ENCODE_FRAME_POINTER
|
||||
|
||||
/*
|
||||
@ -1618,7 +1564,8 @@ end_repeat_nmi:
|
||||
* frame to point back to repeat_nmi.
|
||||
*/
|
||||
pushq $-1 /* ORIG_RAX: no syscall to restart */
|
||||
ALLOC_PT_GPREGS_ON_STACK
|
||||
PUSH_AND_CLEAR_REGS
|
||||
ENCODE_FRAME_POINTER
|
||||
|
||||
/*
|
||||
* Use paranoid_entry to handle SWAPGS, but no need to use paranoid_exit
|
||||
@ -1642,8 +1589,7 @@ end_repeat_nmi:
|
||||
nmi_swapgs:
|
||||
SWAPGS_UNSAFE_STACK
|
||||
nmi_restore:
|
||||
POP_EXTRA_REGS
|
||||
POP_C_REGS
|
||||
POP_REGS
|
||||
|
||||
/*
|
||||
* Skip orig_ax and the "outermost" frame to point RSP at the "iret"
|
||||
|
@ -85,15 +85,25 @@ ENTRY(entry_SYSENTER_compat)
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
pushq $0 /* pt_regs->r8 = 0 */
|
||||
xorq %r8, %r8 /* nospec r8 */
|
||||
pushq $0 /* pt_regs->r9 = 0 */
|
||||
xorq %r9, %r9 /* nospec r9 */
|
||||
pushq $0 /* pt_regs->r10 = 0 */
|
||||
xorq %r10, %r10 /* nospec r10 */
|
||||
pushq $0 /* pt_regs->r11 = 0 */
|
||||
xorq %r11, %r11 /* nospec r11 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
xorl %ebx, %ebx /* nospec rbx */
|
||||
pushq %rbp /* pt_regs->rbp (will be overwritten) */
|
||||
xorl %ebp, %ebp /* nospec rbp */
|
||||
pushq $0 /* pt_regs->r12 = 0 */
|
||||
xorq %r12, %r12 /* nospec r12 */
|
||||
pushq $0 /* pt_regs->r13 = 0 */
|
||||
xorq %r13, %r13 /* nospec r13 */
|
||||
pushq $0 /* pt_regs->r14 = 0 */
|
||||
xorq %r14, %r14 /* nospec r14 */
|
||||
pushq $0 /* pt_regs->r15 = 0 */
|
||||
xorq %r15, %r15 /* nospec r15 */
|
||||
cld
|
||||
|
||||
/*
|
||||
@ -214,15 +224,25 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe)
|
||||
pushq %rbp /* pt_regs->cx (stashed in bp) */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
pushq $0 /* pt_regs->r8 = 0 */
|
||||
xorq %r8, %r8 /* nospec r8 */
|
||||
pushq $0 /* pt_regs->r9 = 0 */
|
||||
xorq %r9, %r9 /* nospec r9 */
|
||||
pushq $0 /* pt_regs->r10 = 0 */
|
||||
xorq %r10, %r10 /* nospec r10 */
|
||||
pushq $0 /* pt_regs->r11 = 0 */
|
||||
xorq %r11, %r11 /* nospec r11 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
xorl %ebx, %ebx /* nospec rbx */
|
||||
pushq %rbp /* pt_regs->rbp (will be overwritten) */
|
||||
xorl %ebp, %ebp /* nospec rbp */
|
||||
pushq $0 /* pt_regs->r12 = 0 */
|
||||
xorq %r12, %r12 /* nospec r12 */
|
||||
pushq $0 /* pt_regs->r13 = 0 */
|
||||
xorq %r13, %r13 /* nospec r13 */
|
||||
pushq $0 /* pt_regs->r14 = 0 */
|
||||
xorq %r14, %r14 /* nospec r14 */
|
||||
pushq $0 /* pt_regs->r15 = 0 */
|
||||
xorq %r15, %r15 /* nospec r15 */
|
||||
|
||||
/*
|
||||
* User mode is traced as though IRQs are on, and SYSENTER
|
||||
@ -338,15 +358,25 @@ ENTRY(entry_INT80_compat)
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
pushq $0 /* pt_regs->r8 = 0 */
|
||||
xorq %r8, %r8 /* nospec r8 */
|
||||
pushq $0 /* pt_regs->r9 = 0 */
|
||||
xorq %r9, %r9 /* nospec r9 */
|
||||
pushq $0 /* pt_regs->r10 = 0 */
|
||||
xorq %r10, %r10 /* nospec r10 */
|
||||
pushq $0 /* pt_regs->r11 = 0 */
|
||||
xorq %r11, %r11 /* nospec r11 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
xorl %ebx, %ebx /* nospec rbx */
|
||||
pushq %rbp /* pt_regs->rbp */
|
||||
xorl %ebp, %ebp /* nospec rbp */
|
||||
pushq %r12 /* pt_regs->r12 */
|
||||
xorq %r12, %r12 /* nospec r12 */
|
||||
pushq %r13 /* pt_regs->r13 */
|
||||
xorq %r13, %r13 /* nospec r13 */
|
||||
pushq %r14 /* pt_regs->r14 */
|
||||
xorq %r14, %r14 /* nospec r14 */
|
||||
pushq %r15 /* pt_regs->r15 */
|
||||
xorq %r15, %r15 /* nospec r15 */
|
||||
cld
|
||||
|
||||
/*
|
||||
|
@ -3559,7 +3559,7 @@ static int intel_snb_pebs_broken(int cpu)
|
||||
break;
|
||||
|
||||
case INTEL_FAM6_SANDYBRIDGE_X:
|
||||
switch (cpu_data(cpu).x86_mask) {
|
||||
switch (cpu_data(cpu).x86_stepping) {
|
||||
case 6: rev = 0x618; break;
|
||||
case 7: rev = 0x70c; break;
|
||||
}
|
||||
|
@ -1186,7 +1186,7 @@ void __init intel_pmu_lbr_init_atom(void)
|
||||
* on PMU interrupt
|
||||
*/
|
||||
if (boot_cpu_data.x86_model == 28
|
||||
&& boot_cpu_data.x86_mask < 10) {
|
||||
&& boot_cpu_data.x86_stepping < 10) {
|
||||
pr_cont("LBR disabled due to erratum");
|
||||
return;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ static __initconst const struct x86_pmu p6_pmu = {
|
||||
|
||||
static __init void p6_pmu_rdpmc_quirk(void)
|
||||
{
|
||||
if (boot_cpu_data.x86_mask < 9) {
|
||||
if (boot_cpu_data.x86_stepping < 9) {
|
||||
/*
|
||||
* PPro erratum 26; fixed in stepping 9 and above.
|
||||
*/
|
||||
|
@ -94,7 +94,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
|
||||
if (boot_cpu_data.x86 == 0x0F &&
|
||||
boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
|
||||
boot_cpu_data.x86_model <= 0x05 &&
|
||||
boot_cpu_data.x86_mask < 0x0A)
|
||||
boot_cpu_data.x86_stepping < 0x0A)
|
||||
return 1;
|
||||
else if (boot_cpu_has(X86_BUG_AMD_APIC_C1E))
|
||||
return 1;
|
||||
|
@ -40,7 +40,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
|
||||
|
||||
asm ("cmp %1,%2; sbb %0,%0;"
|
||||
:"=r" (mask)
|
||||
:"r"(size),"r" (index)
|
||||
:"g"(size),"r" (index)
|
||||
:"cc");
|
||||
return mask;
|
||||
}
|
||||
|
@ -5,23 +5,20 @@
|
||||
#include <linux/stringify.h>
|
||||
|
||||
/*
|
||||
* Since some emulators terminate on UD2, we cannot use it for WARN.
|
||||
* Since various instruction decoders disagree on the length of UD1,
|
||||
* we cannot use it either. So use UD0 for WARN.
|
||||
* Despite that some emulators terminate on UD2, we use it for WARN().
|
||||
*
|
||||
* (binutils knows about "ud1" but {en,de}codes it as 2 bytes, whereas
|
||||
* our kernel decoder thinks it takes a ModRM byte, which seems consistent
|
||||
* with various things like the Intel SDM instruction encoding rules)
|
||||
* Since various instruction decoders/specs disagree on the encoding of
|
||||
* UD0/UD1.
|
||||
*/
|
||||
|
||||
#define ASM_UD0 ".byte 0x0f, 0xff"
|
||||
#define ASM_UD0 ".byte 0x0f, 0xff" /* + ModRM (for Intel) */
|
||||
#define ASM_UD1 ".byte 0x0f, 0xb9" /* + ModRM */
|
||||
#define ASM_UD2 ".byte 0x0f, 0x0b"
|
||||
|
||||
#define INSN_UD0 0xff0f
|
||||
#define INSN_UD2 0x0b0f
|
||||
|
||||
#define LEN_UD0 2
|
||||
#define LEN_UD2 2
|
||||
|
||||
#ifdef CONFIG_GENERIC_BUG
|
||||
|
||||
@ -77,7 +74,11 @@ do { \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define __WARN_FLAGS(flags) _BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags))
|
||||
#define __WARN_FLAGS(flags) \
|
||||
do { \
|
||||
_BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags)); \
|
||||
annotate_reachable(); \
|
||||
} while (0)
|
||||
|
||||
#include <asm-generic/bug.h>
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
* Documentation/DMA-API.txt for documentation.
|
||||
*/
|
||||
|
||||
#include <linux/kmemcheck.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/dma-debug.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -1,43 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef ASM_X86_KMEMCHECK_H
|
||||
#define ASM_X86_KMEMCHECK_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#ifdef CONFIG_KMEMCHECK
|
||||
bool kmemcheck_active(struct pt_regs *regs);
|
||||
|
||||
void kmemcheck_show(struct pt_regs *regs);
|
||||
void kmemcheck_hide(struct pt_regs *regs);
|
||||
|
||||
bool kmemcheck_fault(struct pt_regs *regs,
|
||||
unsigned long address, unsigned long error_code);
|
||||
bool kmemcheck_trap(struct pt_regs *regs);
|
||||
#else
|
||||
static inline bool kmemcheck_active(struct pt_regs *regs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void kmemcheck_show(struct pt_regs *regs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void kmemcheck_hide(struct pt_regs *regs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool kmemcheck_fault(struct pt_regs *regs,
|
||||
unsigned long address, unsigned long error_code)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool kmemcheck_trap(struct pt_regs *regs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_KMEMCHECK */
|
||||
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/alternative-asm.h>
|
||||
#include <asm/cpufeatures.h>
|
||||
#include <asm/msr-index.h>
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
@ -164,10 +165,15 @@ static inline void vmexit_fill_RSB(void)
|
||||
|
||||
static inline void indirect_branch_prediction_barrier(void)
|
||||
{
|
||||
alternative_input("",
|
||||
"call __ibp_barrier",
|
||||
X86_FEATURE_USE_IBPB,
|
||||
ASM_NO_INPUT_CLOBBER("eax", "ecx", "edx", "memory"));
|
||||
asm volatile(ALTERNATIVE("",
|
||||
"movl %[msr], %%ecx\n\t"
|
||||
"movl %[val], %%eax\n\t"
|
||||
"movl $0, %%edx\n\t"
|
||||
"wrmsr",
|
||||
X86_FEATURE_USE_IBPB)
|
||||
: : [msr] "i" (MSR_IA32_PRED_CMD),
|
||||
[val] "i" (PRED_CMD_IBPB)
|
||||
: "eax", "ecx", "edx", "memory");
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -52,10 +52,6 @@ static inline void clear_page(void *page)
|
||||
|
||||
void copy_page(void *to, void *from);
|
||||
|
||||
#ifdef CONFIG_X86_MCE
|
||||
#define arch_unmap_kpfn arch_unmap_kpfn
|
||||
#endif
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#ifdef CONFIG_X86_VSYSCALL_EMULATION
|
||||
|
@ -297,9 +297,9 @@ static inline void __flush_tlb_global(void)
|
||||
{
|
||||
PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel);
|
||||
}
|
||||
static inline void __flush_tlb_single(unsigned long addr)
|
||||
static inline void __flush_tlb_one_user(unsigned long addr)
|
||||
{
|
||||
PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr);
|
||||
PVOP_VCALL1(pv_mmu_ops.flush_tlb_one_user, addr);
|
||||
}
|
||||
|
||||
static inline void flush_tlb_others(const struct cpumask *cpumask,
|
||||
|
@ -217,7 +217,7 @@ struct pv_mmu_ops {
|
||||
/* TLB operations */
|
||||
void (*flush_tlb_user)(void);
|
||||
void (*flush_tlb_kernel)(void);
|
||||
void (*flush_tlb_single)(unsigned long addr);
|
||||
void (*flush_tlb_one_user)(unsigned long addr);
|
||||
void (*flush_tlb_others)(const struct cpumask *cpus,
|
||||
const struct flush_tlb_info *info);
|
||||
|
||||
|
@ -668,11 +668,6 @@ static inline bool pte_accessible(struct mm_struct *mm, pte_t a)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int pte_hidden(pte_t pte)
|
||||
{
|
||||
return pte_flags(pte) & _PAGE_HIDDEN;
|
||||
}
|
||||
|
||||
static inline int pmd_present(pmd_t pmd)
|
||||
{
|
||||
/*
|
||||
|
@ -61,7 +61,7 @@ void paging_init(void);
|
||||
#define kpte_clear_flush(ptep, vaddr) \
|
||||
do { \
|
||||
pte_clear(&init_mm, (vaddr), (ptep)); \
|
||||
__flush_tlb_one((vaddr)); \
|
||||
__flush_tlb_one_kernel((vaddr)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
#define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1
|
||||
#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1
|
||||
#define _PAGE_BIT_HIDDEN _PAGE_BIT_SOFTW3 /* hidden by kmemcheck */
|
||||
#define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */
|
||||
#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4
|
||||
|
||||
@ -79,18 +78,6 @@
|
||||
#define _PAGE_KNL_ERRATUM_MASK 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KMEMCHECK
|
||||
#define _PAGE_HIDDEN (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN)
|
||||
#else
|
||||
#define _PAGE_HIDDEN (_AT(pteval_t, 0))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The same hidden bit is used by kmemcheck, but since kmemcheck
|
||||
* works on kernel pages while soft-dirty engine on user space,
|
||||
* they do not conflict with each other.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MEM_SOFT_DIRTY
|
||||
#define _PAGE_SOFT_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_SOFT_DIRTY)
|
||||
#else
|
||||
|
@ -91,7 +91,7 @@ struct cpuinfo_x86 {
|
||||
__u8 x86; /* CPU family */
|
||||
__u8 x86_vendor; /* CPU vendor */
|
||||
__u8 x86_model;
|
||||
__u8 x86_mask;
|
||||
__u8 x86_stepping;
|
||||
#ifdef CONFIG_X86_64
|
||||
/* Number of 4K pages in DTLB/ITLB combined(in pages): */
|
||||
int x86_tlbsize;
|
||||
@ -109,7 +109,7 @@ struct cpuinfo_x86 {
|
||||
char x86_vendor_id[16];
|
||||
char x86_model_id[64];
|
||||
/* in KB - valid for CPUS which support this call: */
|
||||
int x86_cache_size;
|
||||
unsigned int x86_cache_size;
|
||||
int x86_cache_alignment; /* In bytes */
|
||||
/* Cache QoS architectural values: */
|
||||
int x86_cache_max_rmid; /* max index */
|
||||
@ -968,7 +968,4 @@ bool xen_set_default_idle(void);
|
||||
|
||||
void stop_this_cpu(void *dummy);
|
||||
void df_debug(struct pt_regs *regs, long error_code);
|
||||
|
||||
void __ibp_barrier(void);
|
||||
|
||||
#endif /* _ASM_X86_PROCESSOR_H */
|
||||
|
@ -179,8 +179,6 @@ static inline void *__memcpy3d(void *to, const void *from, size_t len)
|
||||
* No 3D Now!
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_KMEMCHECK
|
||||
|
||||
#if (__GNUC__ >= 4)
|
||||
#define memcpy(t, f, n) __builtin_memcpy(t, f, n)
|
||||
#else
|
||||
@ -189,13 +187,6 @@ static inline void *__memcpy3d(void *to, const void *from, size_t len)
|
||||
? __constant_memcpy((t), (f), (n)) \
|
||||
: __memcpy((t), (f), (n)))
|
||||
#endif
|
||||
#else
|
||||
/*
|
||||
* kmemcheck becomes very happy if we use the REP instructions unconditionally,
|
||||
* because it means that we know both memory operands in advance.
|
||||
*/
|
||||
#define memcpy(t, f, n) __memcpy((t), (f), (n))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* !CONFIG_FORTIFY_SOURCE */
|
||||
|
@ -33,7 +33,6 @@ extern void *memcpy(void *to, const void *from, size_t len);
|
||||
extern void *__memcpy(void *to, const void *from, size_t len);
|
||||
|
||||
#ifndef CONFIG_FORTIFY_SOURCE
|
||||
#ifndef CONFIG_KMEMCHECK
|
||||
#if (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || __GNUC__ < 4
|
||||
#define memcpy(dst, src, len) \
|
||||
({ \
|
||||
@ -46,13 +45,6 @@ extern void *__memcpy(void *to, const void *from, size_t len);
|
||||
__ret; \
|
||||
})
|
||||
#endif
|
||||
#else
|
||||
/*
|
||||
* kmemcheck becomes very happy if we use the REP instructions unconditionally,
|
||||
* because it means that we know both memory operands in advance.
|
||||
*/
|
||||
#define memcpy(dst, src, len) __inline_memcpy((dst), (src), (len))
|
||||
#endif
|
||||
#endif /* !CONFIG_FORTIFY_SOURCE */
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
|
@ -140,7 +140,7 @@ static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid)
|
||||
#else
|
||||
#define __flush_tlb() __native_flush_tlb()
|
||||
#define __flush_tlb_global() __native_flush_tlb_global()
|
||||
#define __flush_tlb_single(addr) __native_flush_tlb_single(addr)
|
||||
#define __flush_tlb_one_user(addr) __native_flush_tlb_one_user(addr)
|
||||
#endif
|
||||
|
||||
static inline bool tlb_defer_switch_to_init_mm(void)
|
||||
@ -397,7 +397,7 @@ static inline void __native_flush_tlb_global(void)
|
||||
/*
|
||||
* flush one page in the user mapping
|
||||
*/
|
||||
static inline void __native_flush_tlb_single(unsigned long addr)
|
||||
static inline void __native_flush_tlb_one_user(unsigned long addr)
|
||||
{
|
||||
u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid);
|
||||
|
||||
@ -434,18 +434,31 @@ static inline void __flush_tlb_all(void)
|
||||
/*
|
||||
* flush one page in the kernel mapping
|
||||
*/
|
||||
static inline void __flush_tlb_one(unsigned long addr)
|
||||
static inline void __flush_tlb_one_kernel(unsigned long addr)
|
||||
{
|
||||
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE);
|
||||
__flush_tlb_single(addr);
|
||||
|
||||
/*
|
||||
* If PTI is off, then __flush_tlb_one_user() is just INVLPG or its
|
||||
* paravirt equivalent. Even with PCID, this is sufficient: we only
|
||||
* use PCID if we also use global PTEs for the kernel mapping, and
|
||||
* INVLPG flushes global translations across all address spaces.
|
||||
*
|
||||
* If PTI is on, then the kernel is mapped with non-global PTEs, and
|
||||
* __flush_tlb_one_user() will flush the given address for the current
|
||||
* kernel address space and for its usermode counterpart, but it does
|
||||
* not flush it for other address spaces.
|
||||
*/
|
||||
__flush_tlb_one_user(addr);
|
||||
|
||||
if (!static_cpu_has(X86_FEATURE_PTI))
|
||||
return;
|
||||
|
||||
/*
|
||||
* __flush_tlb_single() will have cleared the TLB entry for this ASID,
|
||||
* but since kernel space is replicated across all, we must also
|
||||
* invalidate all others.
|
||||
* See above. We need to propagate the flush to all other address
|
||||
* spaces. In principle, we only need to propagate it to kernelmode
|
||||
* address spaces, but the extra bookkeeping we would need is not
|
||||
* worth it.
|
||||
*/
|
||||
invalidate_other_asid();
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
#ifdef CONFIG_KMEMCHECK
|
||||
/* kmemcheck doesn't handle MMX/SSE/SSE2 instructions */
|
||||
# include <asm-generic/xor.h>
|
||||
#elif !defined(_ASM_X86_XOR_H)
|
||||
#ifndef _ASM_X86_XOR_H
|
||||
#define _ASM_X86_XOR_H
|
||||
|
||||
/*
|
||||
|
@ -55,5 +55,5 @@ void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
|
||||
|
||||
void arch_apei_flush_tlb_one(unsigned long addr)
|
||||
{
|
||||
__flush_tlb_one(addr);
|
||||
__flush_tlb_one_kernel(addr);
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ int amd_cache_northbridges(void)
|
||||
if (boot_cpu_data.x86 == 0x10 &&
|
||||
boot_cpu_data.x86_model >= 0x8 &&
|
||||
(boot_cpu_data.x86_model > 0x9 ||
|
||||
boot_cpu_data.x86_mask >= 0x1))
|
||||
boot_cpu_data.x86_stepping >= 0x1))
|
||||
amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE;
|
||||
|
||||
if (boot_cpu_data.x86 == 0x15)
|
||||
|
@ -553,7 +553,7 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
|
||||
|
||||
static u32 hsx_deadline_rev(void)
|
||||
{
|
||||
switch (boot_cpu_data.x86_mask) {
|
||||
switch (boot_cpu_data.x86_stepping) {
|
||||
case 0x02: return 0x3a; /* EP */
|
||||
case 0x04: return 0x0f; /* EX */
|
||||
}
|
||||
@ -563,7 +563,7 @@ static u32 hsx_deadline_rev(void)
|
||||
|
||||
static u32 bdx_deadline_rev(void)
|
||||
{
|
||||
switch (boot_cpu_data.x86_mask) {
|
||||
switch (boot_cpu_data.x86_stepping) {
|
||||
case 0x02: return 0x00000011;
|
||||
case 0x03: return 0x0700000e;
|
||||
case 0x04: return 0x0f00000c;
|
||||
@ -575,7 +575,7 @@ static u32 bdx_deadline_rev(void)
|
||||
|
||||
static u32 skx_deadline_rev(void)
|
||||
{
|
||||
switch (boot_cpu_data.x86_mask) {
|
||||
switch (boot_cpu_data.x86_stepping) {
|
||||
case 0x03: return 0x01000136;
|
||||
case 0x04: return 0x02000014;
|
||||
}
|
||||
|
@ -2389,6 +2389,7 @@ static int __init apm_init(void)
|
||||
if (HZ != 100)
|
||||
idle_period = (idle_period * HZ) / 100;
|
||||
if (idle_threshold < 100) {
|
||||
cpuidle_poll_state_init(&apm_idle_driver);
|
||||
if (!cpuidle_register_driver(&apm_idle_driver))
|
||||
if (cpuidle_register_device(&apm_cpuidle_device))
|
||||
cpuidle_unregister_driver(&apm_idle_driver);
|
||||
|
@ -18,7 +18,7 @@ void foo(void)
|
||||
OFFSET(CPUINFO_x86, cpuinfo_x86, x86);
|
||||
OFFSET(CPUINFO_x86_vendor, cpuinfo_x86, x86_vendor);
|
||||
OFFSET(CPUINFO_x86_model, cpuinfo_x86, x86_model);
|
||||
OFFSET(CPUINFO_x86_mask, cpuinfo_x86, x86_mask);
|
||||
OFFSET(CPUINFO_x86_stepping, cpuinfo_x86, x86_stepping);
|
||||
OFFSET(CPUINFO_cpuid_level, cpuinfo_x86, cpuid_level);
|
||||
OFFSET(CPUINFO_x86_capability, cpuinfo_x86, x86_capability);
|
||||
OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id);
|
||||
|
@ -119,7 +119,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
|
||||
return;
|
||||
}
|
||||
|
||||
if (c->x86_model == 6 && c->x86_mask == 1) {
|
||||
if (c->x86_model == 6 && c->x86_stepping == 1) {
|
||||
const int K6_BUG_LOOP = 1000000;
|
||||
int n;
|
||||
void (*f_vide)(void);
|
||||
@ -149,7 +149,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
|
||||
|
||||
/* K6 with old style WHCR */
|
||||
if (c->x86_model < 8 ||
|
||||
(c->x86_model == 8 && c->x86_mask < 8)) {
|
||||
(c->x86_model == 8 && c->x86_stepping < 8)) {
|
||||
/* We can only write allocate on the low 508Mb */
|
||||
if (mbytes > 508)
|
||||
mbytes = 508;
|
||||
@ -168,7 +168,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((c->x86_model == 8 && c->x86_mask > 7) ||
|
||||
if ((c->x86_model == 8 && c->x86_stepping > 7) ||
|
||||
c->x86_model == 9 || c->x86_model == 13) {
|
||||
/* The more serious chips .. */
|
||||
|
||||
@ -221,7 +221,7 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
|
||||
* are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx
|
||||
* As per AMD technical note 27212 0.2
|
||||
*/
|
||||
if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) {
|
||||
if ((c->x86_model == 8 && c->x86_stepping >= 1) || (c->x86_model > 8)) {
|
||||
rdmsr(MSR_K7_CLK_CTL, l, h);
|
||||
if ((l & 0xfff00000) != 0x20000000) {
|
||||
pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
|
||||
@ -241,12 +241,12 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
|
||||
* but they are not certified as MP capable.
|
||||
*/
|
||||
/* Athlon 660/661 is valid. */
|
||||
if ((c->x86_model == 6) && ((c->x86_mask == 0) ||
|
||||
(c->x86_mask == 1)))
|
||||
if ((c->x86_model == 6) && ((c->x86_stepping == 0) ||
|
||||
(c->x86_stepping == 1)))
|
||||
return;
|
||||
|
||||
/* Duron 670 is valid */
|
||||
if ((c->x86_model == 7) && (c->x86_mask == 0))
|
||||
if ((c->x86_model == 7) && (c->x86_stepping == 0))
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -256,8 +256,8 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
|
||||
* See http://www.heise.de/newsticker/data/jow-18.10.01-000 for
|
||||
* more.
|
||||
*/
|
||||
if (((c->x86_model == 6) && (c->x86_mask >= 2)) ||
|
||||
((c->x86_model == 7) && (c->x86_mask >= 1)) ||
|
||||
if (((c->x86_model == 6) && (c->x86_stepping >= 2)) ||
|
||||
((c->x86_model == 7) && (c->x86_stepping >= 1)) ||
|
||||
(c->x86_model > 7))
|
||||
if (cpu_has(c, X86_FEATURE_MP))
|
||||
return;
|
||||
@ -583,7 +583,7 @@ static void early_init_amd(struct cpuinfo_x86 *c)
|
||||
/* Set MTRR capability flag if appropriate */
|
||||
if (c->x86 == 5)
|
||||
if (c->x86_model == 13 || c->x86_model == 9 ||
|
||||
(c->x86_model == 8 && c->x86_mask >= 8))
|
||||
(c->x86_model == 8 && c->x86_stepping >= 8))
|
||||
set_cpu_cap(c, X86_FEATURE_K6_MTRR);
|
||||
#endif
|
||||
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
|
||||
@ -769,7 +769,7 @@ static void init_amd_zn(struct cpuinfo_x86 *c)
|
||||
* Fix erratum 1076: CPB feature bit not being set in CPUID. It affects
|
||||
* all up to and including B1.
|
||||
*/
|
||||
if (c->x86_model <= 1 && c->x86_mask <= 1)
|
||||
if (c->x86_model <= 1 && c->x86_stepping <= 1)
|
||||
set_cpu_cap(c, X86_FEATURE_CPB);
|
||||
}
|
||||
|
||||
@ -880,11 +880,11 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
|
||||
/* AMD errata T13 (order #21922) */
|
||||
if ((c->x86 == 6)) {
|
||||
/* Duron Rev A0 */
|
||||
if (c->x86_model == 3 && c->x86_mask == 0)
|
||||
if (c->x86_model == 3 && c->x86_stepping == 0)
|
||||
size = 64;
|
||||
/* Tbird rev A1/A2 */
|
||||
if (c->x86_model == 4 &&
|
||||
(c->x86_mask == 0 || c->x86_mask == 1))
|
||||
(c->x86_stepping == 0 || c->x86_stepping == 1))
|
||||
size = 256;
|
||||
}
|
||||
return size;
|
||||
@ -1021,7 +1021,7 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
|
||||
}
|
||||
|
||||
/* OSVW unavailable or ID unknown, match family-model-stepping range */
|
||||
ms = (cpu->x86_model << 4) | cpu->x86_mask;
|
||||
ms = (cpu->x86_model << 4) | cpu->x86_stepping;
|
||||
while ((range = *erratum++))
|
||||
if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) &&
|
||||
(ms >= AMD_MODEL_RANGE_START(range)) &&
|
||||
|
@ -162,8 +162,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
|
||||
if (cmdline_find_option_bool(boot_command_line, "nospectre_v2"))
|
||||
return SPECTRE_V2_CMD_NONE;
|
||||
else {
|
||||
ret = cmdline_find_option(boot_command_line, "spectre_v2", arg,
|
||||
sizeof(arg));
|
||||
ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg));
|
||||
if (ret < 0)
|
||||
return SPECTRE_V2_CMD_AUTO;
|
||||
|
||||
@ -175,8 +174,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(mitigation_options)) {
|
||||
pr_err("unknown option (%s). Switching to AUTO select\n",
|
||||
mitigation_options[i].option);
|
||||
pr_err("unknown option (%s). Switching to AUTO select\n", arg);
|
||||
return SPECTRE_V2_CMD_AUTO;
|
||||
}
|
||||
}
|
||||
@ -185,8 +183,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
|
||||
cmd == SPECTRE_V2_CMD_RETPOLINE_AMD ||
|
||||
cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) &&
|
||||
!IS_ENABLED(CONFIG_RETPOLINE)) {
|
||||
pr_err("%s selected but not compiled in. Switching to AUTO select\n",
|
||||
mitigation_options[i].option);
|
||||
pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option);
|
||||
return SPECTRE_V2_CMD_AUTO;
|
||||
}
|
||||
|
||||
@ -256,14 +253,14 @@ static void __init spectre_v2_select_mitigation(void)
|
||||
goto retpoline_auto;
|
||||
break;
|
||||
}
|
||||
pr_err("kernel not compiled with retpoline; no mitigation available!");
|
||||
pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!");
|
||||
return;
|
||||
|
||||
retpoline_auto:
|
||||
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
|
||||
retpoline_amd:
|
||||
if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
|
||||
pr_err("LFENCE not serializing. Switching to generic retpoline\n");
|
||||
pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n");
|
||||
goto retpoline_generic;
|
||||
}
|
||||
mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD :
|
||||
@ -281,7 +278,7 @@ retpoline_auto:
|
||||
pr_info("%s\n", spectre_v2_strings[mode]);
|
||||
|
||||
/*
|
||||
* If neither SMEP or KPTI are available, there is a risk of
|
||||
* If neither SMEP nor PTI are available, there is a risk of
|
||||
* hitting userspace addresses in the RSB after a context switch
|
||||
* from a shallow call stack to a deeper one. To prevent this fill
|
||||
* the entire RSB, even when using IBRS.
|
||||
@ -295,21 +292,20 @@ retpoline_auto:
|
||||
if ((!boot_cpu_has(X86_FEATURE_PTI) &&
|
||||
!boot_cpu_has(X86_FEATURE_SMEP)) || is_skylake_era()) {
|
||||
setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
|
||||
pr_info("Filling RSB on context switch\n");
|
||||
pr_info("Spectre v2 mitigation: Filling RSB on context switch\n");
|
||||
}
|
||||
|
||||
/* Initialize Indirect Branch Prediction Barrier if supported */
|
||||
if (boot_cpu_has(X86_FEATURE_IBPB)) {
|
||||
setup_force_cpu_cap(X86_FEATURE_USE_IBPB);
|
||||
pr_info("Enabling Indirect Branch Prediction Barrier\n");
|
||||
pr_info("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n");
|
||||
}
|
||||
}
|
||||
|
||||
#undef pr_fmt
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
ssize_t cpu_show_meltdown(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN))
|
||||
return sprintf(buf, "Not affected\n");
|
||||
@ -318,16 +314,14 @@ ssize_t cpu_show_meltdown(struct device *dev,
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spectre_v1(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1))
|
||||
return sprintf(buf, "Not affected\n");
|
||||
return sprintf(buf, "Mitigation: __user pointer sanitization\n");
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spectre_v2(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
|
||||
return sprintf(buf, "Not affected\n");
|
||||
@ -337,9 +331,3 @@ ssize_t cpu_show_spectre_v2(struct device *dev,
|
||||
spectre_v2_module_string());
|
||||
}
|
||||
#endif
|
||||
|
||||
void __ibp_barrier(void)
|
||||
{
|
||||
__wrmsr(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__ibp_barrier);
|
||||
|
@ -136,7 +136,7 @@ static void init_centaur(struct cpuinfo_x86 *c)
|
||||
clear_cpu_cap(c, X86_FEATURE_TSC);
|
||||
break;
|
||||
case 8:
|
||||
switch (c->x86_mask) {
|
||||
switch (c->x86_stepping) {
|
||||
default:
|
||||
name = "2";
|
||||
break;
|
||||
@ -211,7 +211,7 @@ centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
|
||||
* - Note, it seems this may only be in engineering samples.
|
||||
*/
|
||||
if ((c->x86 == 6) && (c->x86_model == 9) &&
|
||||
(c->x86_mask == 1) && (size == 65))
|
||||
(c->x86_stepping == 1) && (size == 65))
|
||||
size -= 1;
|
||||
return size;
|
||||
}
|
||||
|
@ -707,7 +707,7 @@ void cpu_detect(struct cpuinfo_x86 *c)
|
||||
cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
|
||||
c->x86 = x86_family(tfms);
|
||||
c->x86_model = x86_model(tfms);
|
||||
c->x86_mask = x86_stepping(tfms);
|
||||
c->x86_stepping = x86_stepping(tfms);
|
||||
|
||||
if (cap0 & (1<<19)) {
|
||||
c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
|
||||
@ -1160,9 +1160,9 @@ static void identify_cpu(struct cpuinfo_x86 *c)
|
||||
int i;
|
||||
|
||||
c->loops_per_jiffy = loops_per_jiffy;
|
||||
c->x86_cache_size = -1;
|
||||
c->x86_cache_size = 0;
|
||||
c->x86_vendor = X86_VENDOR_UNKNOWN;
|
||||
c->x86_model = c->x86_mask = 0; /* So far unknown... */
|
||||
c->x86_model = c->x86_stepping = 0; /* So far unknown... */
|
||||
c->x86_vendor_id[0] = '\0'; /* Unset */
|
||||
c->x86_model_id[0] = '\0'; /* Unset */
|
||||
c->x86_max_cores = 1;
|
||||
@ -1353,8 +1353,8 @@ void print_cpu_info(struct cpuinfo_x86 *c)
|
||||
|
||||
pr_cont(" (family: 0x%x, model: 0x%x", c->x86, c->x86_model);
|
||||
|
||||
if (c->x86_mask || c->cpuid_level >= 0)
|
||||
pr_cont(", stepping: 0x%x)\n", c->x86_mask);
|
||||
if (c->x86_stepping || c->cpuid_level >= 0)
|
||||
pr_cont(", stepping: 0x%x)\n", c->x86_stepping);
|
||||
else
|
||||
pr_cont(")\n");
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ static void init_cyrix(struct cpuinfo_x86 *c)
|
||||
|
||||
/* common case step number/rev -- exceptions handled below */
|
||||
c->x86_model = (dir1 >> 4) + 1;
|
||||
c->x86_mask = dir1 & 0xf;
|
||||
c->x86_stepping = dir1 & 0xf;
|
||||
|
||||
/* Now cook; the original recipe is by Channing Corn, from Cyrix.
|
||||
* We do the same thing for each generation: we work out
|
||||
|
@ -116,14 +116,13 @@ struct sku_microcode {
|
||||
u32 microcode;
|
||||
};
|
||||
static const struct sku_microcode spectre_bad_microcodes[] = {
|
||||
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x0B, 0x84 },
|
||||
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x0A, 0x84 },
|
||||
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x09, 0x84 },
|
||||
{ INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x84 },
|
||||
{ INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x84 },
|
||||
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x0B, 0x80 },
|
||||
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x0A, 0x80 },
|
||||
{ INTEL_FAM6_KABYLAKE_DESKTOP, 0x09, 0x80 },
|
||||
{ INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x80 },
|
||||
{ INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x80 },
|
||||
{ INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e },
|
||||
{ INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c },
|
||||
{ INTEL_FAM6_SKYLAKE_MOBILE, 0x03, 0xc2 },
|
||||
{ INTEL_FAM6_SKYLAKE_DESKTOP, 0x03, 0xc2 },
|
||||
{ INTEL_FAM6_BROADWELL_CORE, 0x04, 0x28 },
|
||||
{ INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b },
|
||||
@ -136,8 +135,6 @@ static const struct sku_microcode spectre_bad_microcodes[] = {
|
||||
{ INTEL_FAM6_HASWELL_X, 0x02, 0x3b },
|
||||
{ INTEL_FAM6_HASWELL_X, 0x04, 0x10 },
|
||||
{ INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a },
|
||||
/* Updated in the 20180108 release; blacklist until we know otherwise */
|
||||
{ INTEL_FAM6_ATOM_GEMINI_LAKE, 0x01, 0x22 },
|
||||
/* Observed in the wild */
|
||||
{ INTEL_FAM6_SANDYBRIDGE_X, 0x06, 0x61b },
|
||||
{ INTEL_FAM6_SANDYBRIDGE_X, 0x07, 0x712 },
|
||||
@ -149,7 +146,7 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
|
||||
if (c->x86_model == spectre_bad_microcodes[i].model &&
|
||||
c->x86_mask == spectre_bad_microcodes[i].stepping)
|
||||
c->x86_stepping == spectre_bad_microcodes[i].stepping)
|
||||
return (c->microcode <= spectre_bad_microcodes[i].microcode);
|
||||
}
|
||||
return false;
|
||||
@ -196,7 +193,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
|
||||
* need the microcode to have already been loaded... so if it is
|
||||
* not, recommend a BIOS update and disable large pages.
|
||||
*/
|
||||
if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2 &&
|
||||
if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_stepping <= 2 &&
|
||||
c->microcode < 0x20e) {
|
||||
pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n");
|
||||
clear_cpu_cap(c, X86_FEATURE_PSE);
|
||||
@ -212,7 +209,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
|
||||
|
||||
/* CPUID workaround for 0F33/0F34 CPU */
|
||||
if (c->x86 == 0xF && c->x86_model == 0x3
|
||||
&& (c->x86_mask == 0x3 || c->x86_mask == 0x4))
|
||||
&& (c->x86_stepping == 0x3 || c->x86_stepping == 0x4))
|
||||
c->x86_phys_bits = 36;
|
||||
|
||||
/*
|
||||
@ -253,21 +250,6 @@ static void early_init_intel(struct cpuinfo_x86 *c)
|
||||
if (c->x86 == 6 && c->x86_model < 15)
|
||||
clear_cpu_cap(c, X86_FEATURE_PAT);
|
||||
|
||||
#ifdef CONFIG_KMEMCHECK
|
||||
/*
|
||||
* P4s have a "fast strings" feature which causes single-
|
||||
* stepping REP instructions to only generate a #DB on
|
||||
* cache-line boundaries.
|
||||
*
|
||||
* Ingo Molnar reported a Pentium D (model 6) and a Xeon
|
||||
* (model 2) with the same problem.
|
||||
*/
|
||||
if (c->x86 == 15)
|
||||
if (msr_clear_bit(MSR_IA32_MISC_ENABLE,
|
||||
MSR_IA32_MISC_ENABLE_FAST_STRING_BIT) > 0)
|
||||
pr_info("kmemcheck: Disabling fast string operations\n");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If fast string is not enabled in IA32_MISC_ENABLE for any reason,
|
||||
* clear the fast string and enhanced fast string CPU capabilities.
|
||||
@ -325,7 +307,7 @@ int ppro_with_ram_bug(void)
|
||||
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
|
||||
boot_cpu_data.x86 == 6 &&
|
||||
boot_cpu_data.x86_model == 1 &&
|
||||
boot_cpu_data.x86_mask < 8) {
|
||||
boot_cpu_data.x86_stepping < 8) {
|
||||
pr_info("Pentium Pro with Errata#50 detected. Taking evasive action.\n");
|
||||
return 1;
|
||||
}
|
||||
@ -342,7 +324,7 @@ static void intel_smp_check(struct cpuinfo_x86 *c)
|
||||
* Mask B, Pentium, but not Pentium MMX
|
||||
*/
|
||||
if (c->x86 == 5 &&
|
||||
c->x86_mask >= 1 && c->x86_mask <= 4 &&
|
||||
c->x86_stepping >= 1 && c->x86_stepping <= 4 &&
|
||||
c->x86_model <= 3) {
|
||||
/*
|
||||
* Remember we have B step Pentia with bugs
|
||||
@ -385,7 +367,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
|
||||
* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until
|
||||
* model 3 mask 3
|
||||
*/
|
||||
if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
|
||||
if ((c->x86<<8 | c->x86_model<<4 | c->x86_stepping) < 0x633)
|
||||
clear_cpu_cap(c, X86_FEATURE_SEP);
|
||||
|
||||
/*
|
||||
@ -403,7 +385,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
|
||||
* P4 Xeon erratum 037 workaround.
|
||||
* Hardware prefetcher may cause stale data to be loaded into the cache.
|
||||
*/
|
||||
if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) {
|
||||
if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_stepping == 1)) {
|
||||
if (msr_set_bit(MSR_IA32_MISC_ENABLE,
|
||||
MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT) > 0) {
|
||||
pr_info("CPU: C0 stepping P4 Xeon detected.\n");
|
||||
@ -418,7 +400,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
|
||||
* Specification Update").
|
||||
*/
|
||||
if (boot_cpu_has(X86_FEATURE_APIC) && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
|
||||
(c->x86_mask < 0x6 || c->x86_mask == 0xb))
|
||||
(c->x86_stepping < 0x6 || c->x86_stepping == 0xb))
|
||||
set_cpu_bug(c, X86_BUG_11AP);
|
||||
|
||||
|
||||
@ -665,7 +647,7 @@ static void init_intel(struct cpuinfo_x86 *c)
|
||||
case 6:
|
||||
if (l2 == 128)
|
||||
p = "Celeron (Mendocino)";
|
||||
else if (c->x86_mask == 0 || c->x86_mask == 5)
|
||||
else if (c->x86_stepping == 0 || c->x86_stepping == 5)
|
||||
p = "Celeron-A";
|
||||
break;
|
||||
|
||||
|
@ -771,7 +771,7 @@ static __init void rdt_quirks(void)
|
||||
cache_alloc_hsw_probe();
|
||||
break;
|
||||
case INTEL_FAM6_SKYLAKE_X:
|
||||
if (boot_cpu_data.x86_mask <= 4)
|
||||
if (boot_cpu_data.x86_stepping <= 4)
|
||||
set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat");
|
||||
}
|
||||
}
|
||||
|
@ -115,4 +115,19 @@ static inline void mce_unregister_injector_chain(struct notifier_block *nb) { }
|
||||
|
||||
extern struct mca_config mca_cfg;
|
||||
|
||||
#ifndef CONFIG_X86_64
|
||||
/*
|
||||
* On 32-bit systems it would be difficult to safely unmap a poison page
|
||||
* from the kernel 1:1 map because there are no non-canonical addresses that
|
||||
* we can use to refer to the address without risking a speculative access.
|
||||
* However, this isn't much of an issue because:
|
||||
* 1) Few unmappable pages are in the 1:1 map. Most are in HIGHMEM which
|
||||
* are only mapped into the kernel as needed
|
||||
* 2) Few people would run a 32-bit kernel on a machine that supports
|
||||
* recoverable errors because they have too much memory to boot 32-bit.
|
||||
*/
|
||||
static inline void mce_unmap_kpfn(unsigned long pfn) {}
|
||||
#define mce_unmap_kpfn mce_unmap_kpfn
|
||||
#endif
|
||||
|
||||
#endif /* __X86_MCE_INTERNAL_H__ */
|
||||
|
@ -106,6 +106,10 @@ static struct irq_work mce_irq_work;
|
||||
|
||||
static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
|
||||
|
||||
#ifndef mce_unmap_kpfn
|
||||
static void mce_unmap_kpfn(unsigned long pfn);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CPU/chipset specific EDAC code can register a notifier call here to print
|
||||
* MCE errors in a human-readable form.
|
||||
@ -582,7 +586,8 @@ static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
|
||||
|
||||
if (mce_usable_address(mce) && (mce->severity == MCE_AO_SEVERITY)) {
|
||||
pfn = mce->addr >> PAGE_SHIFT;
|
||||
memory_failure(pfn, MCE_VECTOR, 0);
|
||||
if (memory_failure(pfn, MCE_VECTOR, 0))
|
||||
mce_unmap_kpfn(pfn);
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
@ -1049,12 +1054,13 @@ static int do_memory_failure(struct mce *m)
|
||||
ret = memory_failure(m->addr >> PAGE_SHIFT, MCE_VECTOR, flags);
|
||||
if (ret)
|
||||
pr_err("Memory error not recovered");
|
||||
else
|
||||
mce_unmap_kpfn(m->addr >> PAGE_SHIFT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(arch_unmap_kpfn) && defined(CONFIG_MEMORY_FAILURE)
|
||||
|
||||
void arch_unmap_kpfn(unsigned long pfn)
|
||||
#ifndef mce_unmap_kpfn
|
||||
static void mce_unmap_kpfn(unsigned long pfn)
|
||||
{
|
||||
unsigned long decoy_addr;
|
||||
|
||||
@ -1065,7 +1071,7 @@ void arch_unmap_kpfn(unsigned long pfn)
|
||||
* We would like to just call:
|
||||
* set_memory_np((unsigned long)pfn_to_kaddr(pfn), 1);
|
||||
* but doing that would radically increase the odds of a
|
||||
* speculative access to the posion page because we'd have
|
||||
* speculative access to the poison page because we'd have
|
||||
* the virtual address of the kernel 1:1 mapping sitting
|
||||
* around in registers.
|
||||
* Instead we get tricky. We create a non-canonical address
|
||||
@ -1090,7 +1096,6 @@ void arch_unmap_kpfn(unsigned long pfn)
|
||||
|
||||
if (set_memory_np(decoy_addr, 1))
|
||||
pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -921,7 +921,7 @@ static bool is_blacklisted(unsigned int cpu)
|
||||
*/
|
||||
if (c->x86 == 6 &&
|
||||
c->x86_model == INTEL_FAM6_BROADWELL_X &&
|
||||
c->x86_mask == 0x01 &&
|
||||
c->x86_stepping == 0x01 &&
|
||||
llc_size_per_core > 2621440 &&
|
||||
c->microcode < 0x0b000021) {
|
||||
pr_err_once("Erratum BDF90: late loading with revision < 0x0b000021 (0x%x) disabled.\n", c->microcode);
|
||||
@ -944,7 +944,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device,
|
||||
return UCODE_NFOUND;
|
||||
|
||||
sprintf(name, "intel-ucode/%02x-%02x-%02x",
|
||||
c->x86, c->x86_model, c->x86_mask);
|
||||
c->x86, c->x86_model, c->x86_stepping);
|
||||
|
||||
if (request_firmware_direct(&firmware, name, device)) {
|
||||
pr_debug("data file %s load failed\n", name);
|
||||
@ -982,7 +982,7 @@ static struct microcode_ops microcode_intel_ops = {
|
||||
|
||||
static int __init calc_llc_size_per_core(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u64 llc_size = c->x86_cache_size * 1024;
|
||||
u64 llc_size = c->x86_cache_size * 1024ULL;
|
||||
|
||||
do_div(llc_size, c->x86_max_cores);
|
||||
|
||||
|
@ -859,7 +859,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size,
|
||||
*/
|
||||
if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 &&
|
||||
boot_cpu_data.x86_model == 1 &&
|
||||
boot_cpu_data.x86_mask <= 7) {
|
||||
boot_cpu_data.x86_stepping <= 7) {
|
||||
if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
|
||||
pr_warn("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
|
||||
return -EINVAL;
|
||||
|
@ -711,8 +711,8 @@ void __init mtrr_bp_init(void)
|
||||
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
|
||||
boot_cpu_data.x86 == 0xF &&
|
||||
boot_cpu_data.x86_model == 0x3 &&
|
||||
(boot_cpu_data.x86_mask == 0x3 ||
|
||||
boot_cpu_data.x86_mask == 0x4))
|
||||
(boot_cpu_data.x86_stepping == 0x3 ||
|
||||
boot_cpu_data.x86_stepping == 0x4))
|
||||
phys_addr = 36;
|
||||
|
||||
size_or_mask = SIZE_OR_MASK_BITS(phys_addr);
|
||||
|
@ -72,8 +72,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
c->x86_model,
|
||||
c->x86_model_id[0] ? c->x86_model_id : "unknown");
|
||||
|
||||
if (c->x86_mask || c->cpuid_level >= 0)
|
||||
seq_printf(m, "stepping\t: %d\n", c->x86_mask);
|
||||
if (c->x86_stepping || c->cpuid_level >= 0)
|
||||
seq_printf(m, "stepping\t: %d\n", c->x86_stepping);
|
||||
else
|
||||
seq_puts(m, "stepping\t: unknown\n");
|
||||
if (c->microcode)
|
||||
@ -91,8 +91,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
}
|
||||
|
||||
/* Cache size */
|
||||
if (c->x86_cache_size >= 0)
|
||||
seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
|
||||
if (c->x86_cache_size)
|
||||
seq_printf(m, "cache size\t: %u KB\n", c->x86_cache_size);
|
||||
|
||||
show_cpuinfo_core(m, c, cpu);
|
||||
show_cpuinfo_misc(m, c);
|
||||
|
@ -527,6 +527,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
|
||||
INTEL_SKL_IDS(&gen9_early_ops),
|
||||
INTEL_BXT_IDS(&gen9_early_ops),
|
||||
INTEL_KBL_IDS(&gen9_early_ops),
|
||||
INTEL_CFL_IDS(&gen9_early_ops),
|
||||
INTEL_GLK_IDS(&gen9_early_ops),
|
||||
INTEL_CNL_IDS(&gen9_early_ops),
|
||||
};
|
||||
|
@ -57,7 +57,7 @@
|
||||
# error "Need more virtual address space for the ESPFIX hack"
|
||||
#endif
|
||||
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_ZERO)
|
||||
|
||||
/* This contains the *bottom* address of the espfix stack */
|
||||
DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack);
|
||||
|
@ -37,7 +37,7 @@
|
||||
#define X86 new_cpu_data+CPUINFO_x86
|
||||
#define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor
|
||||
#define X86_MODEL new_cpu_data+CPUINFO_x86_model
|
||||
#define X86_MASK new_cpu_data+CPUINFO_x86_mask
|
||||
#define X86_STEPPING new_cpu_data+CPUINFO_x86_stepping
|
||||
#define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math
|
||||
#define X86_CPUID new_cpu_data+CPUINFO_cpuid_level
|
||||
#define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability
|
||||
@ -332,7 +332,7 @@ ENTRY(startup_32_smp)
|
||||
shrb $4,%al
|
||||
movb %al,X86_MODEL
|
||||
andb $0x0f,%cl # mask mask revision
|
||||
movb %cl,X86_MASK
|
||||
movb %cl,X86_STEPPING
|
||||
movl %edx,X86_CAPABILITY
|
||||
|
||||
.Lis486:
|
||||
|
@ -407,7 +407,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
|
||||
processor.apicver = mpc_default_type > 4 ? 0x10 : 0x01;
|
||||
processor.cpuflag = CPU_ENABLED;
|
||||
processor.cpufeature = (boot_cpu_data.x86 << 8) |
|
||||
(boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
|
||||
(boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_stepping;
|
||||
processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX];
|
||||
processor.reserved[0] = 0;
|
||||
processor.reserved[1] = 0;
|
||||
|
@ -190,9 +190,9 @@ static void native_flush_tlb_global(void)
|
||||
__native_flush_tlb_global();
|
||||
}
|
||||
|
||||
static void native_flush_tlb_single(unsigned long addr)
|
||||
static void native_flush_tlb_one_user(unsigned long addr)
|
||||
{
|
||||
__native_flush_tlb_single(addr);
|
||||
__native_flush_tlb_one_user(addr);
|
||||
}
|
||||
|
||||
struct static_key paravirt_steal_enabled;
|
||||
@ -391,7 +391,7 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = {
|
||||
|
||||
.flush_tlb_user = native_flush_tlb,
|
||||
.flush_tlb_kernel = native_flush_tlb_global,
|
||||
.flush_tlb_single = native_flush_tlb_single,
|
||||
.flush_tlb_one_user = native_flush_tlb_one_user,
|
||||
.flush_tlb_others = native_flush_tlb_others,
|
||||
|
||||
.pgd_alloc = __paravirt_pgd_alloc,
|
||||
|
@ -68,6 +68,9 @@ relocate_kernel:
|
||||
movq %cr4, %rax
|
||||
movq %rax, CR4(%r11)
|
||||
|
||||
/* Save CR4. Required to enable the right paging mode later. */
|
||||
movq %rax, %r13
|
||||
|
||||
/* zero out flags, and disable interrupts */
|
||||
pushq $0
|
||||
popfq
|
||||
@ -126,8 +129,13 @@ identity_mapped:
|
||||
/*
|
||||
* Set cr4 to a known state:
|
||||
* - physical address extension enabled
|
||||
* - 5-level paging, if it was enabled before
|
||||
*/
|
||||
movl $X86_CR4_PAE, %eax
|
||||
testq $X86_CR4_LA57, %r13
|
||||
jz 1f
|
||||
orl $X86_CR4_LA57, %eax
|
||||
1:
|
||||
movq %rax, %cr4
|
||||
|
||||
jmp 1f
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include <linux/edac.h>
|
||||
#endif
|
||||
|
||||
#include <asm/kmemcheck.h>
|
||||
#include <asm/stacktrace.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/debugreg.h>
|
||||
@ -181,7 +180,7 @@ int fixup_bug(struct pt_regs *regs, int trapnr)
|
||||
break;
|
||||
|
||||
case BUG_TRAP_TYPE_WARN:
|
||||
regs->ip += LEN_UD0;
|
||||
regs->ip += LEN_UD2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -764,10 +763,6 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
|
||||
if (!dr6 && user_mode(regs))
|
||||
user_icebp = 1;
|
||||
|
||||
/* Catch kmemcheck conditions! */
|
||||
if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
|
||||
goto exit;
|
||||
|
||||
/* Store the virtualized DR6 value */
|
||||
tsk->thread.debugreg6 = dr6;
|
||||
|
||||
|
@ -5063,7 +5063,7 @@ void kvm_mmu_uninit_vm(struct kvm *kvm)
|
||||
typedef bool (*slot_level_handler) (struct kvm *kvm, struct kvm_rmap_head *rmap_head);
|
||||
|
||||
/* The caller should hold mmu-lock before calling this function. */
|
||||
static bool
|
||||
static __always_inline bool
|
||||
slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
slot_level_handler fn, int start_level, int end_level,
|
||||
gfn_t start_gfn, gfn_t end_gfn, bool lock_flush_tlb)
|
||||
@ -5093,7 +5093,7 @@ slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
return flush;
|
||||
}
|
||||
|
||||
static bool
|
||||
static __always_inline bool
|
||||
slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
slot_level_handler fn, int start_level, int end_level,
|
||||
bool lock_flush_tlb)
|
||||
@ -5104,7 +5104,7 @@ slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
lock_flush_tlb);
|
||||
}
|
||||
|
||||
static bool
|
||||
static __always_inline bool
|
||||
slot_handle_all_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
slot_level_handler fn, bool lock_flush_tlb)
|
||||
{
|
||||
@ -5112,7 +5112,7 @@ slot_handle_all_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
PT_MAX_HUGEPAGE_LEVEL, lock_flush_tlb);
|
||||
}
|
||||
|
||||
static bool
|
||||
static __always_inline bool
|
||||
slot_handle_large_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
slot_level_handler fn, bool lock_flush_tlb)
|
||||
{
|
||||
@ -5120,7 +5120,7 @@ slot_handle_large_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
PT_MAX_HUGEPAGE_LEVEL, lock_flush_tlb);
|
||||
}
|
||||
|
||||
static bool
|
||||
static __always_inline bool
|
||||
slot_handle_leaf(struct kvm *kvm, struct kvm_memory_slot *memslot,
|
||||
slot_level_handler fn, bool lock_flush_tlb)
|
||||
{
|
||||
|
@ -10127,7 +10127,8 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu,
|
||||
if (cpu_has_vmx_msr_bitmap() &&
|
||||
nested_cpu_has(vmcs12, CPU_BASED_USE_MSR_BITMAPS) &&
|
||||
nested_vmx_merge_msr_bitmap(vcpu, vmcs12))
|
||||
;
|
||||
vmcs_set_bits(CPU_BASED_VM_EXEC_CONTROL,
|
||||
CPU_BASED_USE_MSR_BITMAPS);
|
||||
else
|
||||
vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL,
|
||||
CPU_BASED_USE_MSR_BITMAPS);
|
||||
@ -10216,8 +10217,8 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
|
||||
* updated to reflect this when L1 (or its L2s) actually write to
|
||||
* the MSR.
|
||||
*/
|
||||
bool pred_cmd = msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
|
||||
bool spec_ctrl = msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL);
|
||||
bool pred_cmd = !msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
|
||||
bool spec_ctrl = !msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL);
|
||||
|
||||
if (!nested_cpu_has_virt_x2apic_mode(vmcs12) &&
|
||||
!pred_cmd && !spec_ctrl)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user