mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 03:50:24 +09:00
Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-android
* linux-linaro-lsk-v4.4: (783 commits)
Linux 4.4.159
iw_cxgb4: only allow 1 flush on user qps
HID: sony: Support DS4 dongle
HID: sony: Update device ids
arm64: Add trace_hardirqs_off annotation in ret_to_user
ext4: don't mark mmp buffer head dirty
ext4: fix online resizing for bigalloc file systems with a 1k block size
ext4: fix online resize's handling of a too-small final block group
ext4: recalucate superblock checksum after updating free blocks/inodes
ext4: avoid divide by zero fault when deleting corrupted inline directories
tty: vt_ioctl: fix potential Spectre v1
drm/nouveau/drm/nouveau: Use pm_runtime_get_noresume() in connector_detect()
ocfs2: fix ocfs2 read block panic
scsi: target: iscsi: Use hex2bin instead of a re-implementation
neighbour: confirm neigh entries when ARP packet is received
net: hp100: fix always-true check for link up state
net/appletalk: fix minor pointer leak to userspace in SIOCFINDIPDDPRT
ipv6: fix possible use-after-free in ip6_xmit()
gso_segment: Reset skb->mac_len after modifying network header
mm: shmem.c: Correctly annotate new inodes for lockdep
...
Conflicts:
Makefile
fs/squashfs/block.c
include/uapi/linux/prctl.h
kernel/fork.c
kernel/sys.c
Trivial merge conflicts in above files. Resolved by rebasing
corresponding AOSP changes.
arch/arm64/mm/init.c
Pick the changes from upstream version of AOSP patch
"arm64: check for upper PAGE_SHIFT bits in pfn_valid" instead.
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
This commit is contained in:
@@ -276,6 +276,7 @@ What: /sys/devices/system/cpu/vulnerabilities
|
||||
/sys/devices/system/cpu/vulnerabilities/meltdown
|
||||
/sys/devices/system/cpu/vulnerabilities/spectre_v1
|
||||
/sys/devices/system/cpu/vulnerabilities/spectre_v2
|
||||
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
|
||||
Date: January 2018
|
||||
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||
Description: Information about CPU vulnerabilities
|
||||
|
||||
@@ -25,7 +25,7 @@ o GNU C 3.2 # gcc --version
|
||||
o GNU make 3.80 # make --version
|
||||
o binutils 2.12 # ld -v
|
||||
o util-linux 2.10o # fdformat --version
|
||||
o module-init-tools 0.9.10 # depmod -V
|
||||
o kmod 13 # depmod -V
|
||||
o e2fsprogs 1.41.4 # e2fsck -V
|
||||
o jfsutils 1.1.3 # fsck.jfs -V
|
||||
o reiserfsprogs 3.6.3 # reiserfsck -V
|
||||
@@ -132,12 +132,6 @@ is not build with CONFIG_KALLSYMS and you have no way to rebuild and
|
||||
reproduce the Oops with that option, then you can still decode that Oops
|
||||
with ksymoops.
|
||||
|
||||
Module-Init-Tools
|
||||
-----------------
|
||||
|
||||
A new module loader is now in the kernel that requires module-init-tools
|
||||
to use. It is backward compatible with the 2.4.x series kernels.
|
||||
|
||||
Mkinitrd
|
||||
--------
|
||||
|
||||
@@ -319,14 +313,15 @@ Util-linux
|
||||
----------
|
||||
o <ftp://ftp.kernel.org/pub/linux/utils/util-linux/>
|
||||
|
||||
Kmod
|
||||
----
|
||||
o <https://www.kernel.org/pub/linux/utils/kernel/kmod/>
|
||||
o <https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git>
|
||||
|
||||
Ksymoops
|
||||
--------
|
||||
o <ftp://ftp.kernel.org/pub/linux/utils/kernel/ksymoops/v2.4/>
|
||||
|
||||
Module-Init-Tools
|
||||
-----------------
|
||||
o <ftp://ftp.kernel.org/pub/linux/kernel/people/rusty/modules/>
|
||||
|
||||
Mkinitrd
|
||||
--------
|
||||
o <https://code.launchpad.net/initrd-tools/main>
|
||||
|
||||
@@ -2520,6 +2520,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
allow data leaks with this option, which is equivalent
|
||||
to spectre_v2=off.
|
||||
|
||||
nospec_store_bypass_disable
|
||||
[HW] Disable all mitigations for the Speculative Store Bypass vulnerability
|
||||
|
||||
noxsave [BUGS=X86] Disables x86 extended register state save
|
||||
and restore using xsave. The kernel will fallback to
|
||||
enabling legacy floating-point and sse state.
|
||||
@@ -3687,6 +3690,48 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
Not specifying this option is equivalent to
|
||||
spectre_v2=auto.
|
||||
|
||||
spec_store_bypass_disable=
|
||||
[HW] Control Speculative Store Bypass (SSB) Disable mitigation
|
||||
(Speculative Store Bypass vulnerability)
|
||||
|
||||
Certain CPUs are vulnerable to an exploit against a
|
||||
a common industry wide performance optimization known
|
||||
as "Speculative Store Bypass" in which recent stores
|
||||
to the same memory location may not be observed by
|
||||
later loads during speculative execution. The idea
|
||||
is that such stores are unlikely and that they can
|
||||
be detected prior to instruction retirement at the
|
||||
end of a particular speculation execution window.
|
||||
|
||||
In vulnerable processors, the speculatively forwarded
|
||||
store can be used in a cache side channel attack, for
|
||||
example to read memory to which the attacker does not
|
||||
directly have access (e.g. inside sandboxed code).
|
||||
|
||||
This parameter controls whether the Speculative Store
|
||||
Bypass optimization is used.
|
||||
|
||||
on - Unconditionally disable Speculative Store Bypass
|
||||
off - Unconditionally enable Speculative Store Bypass
|
||||
auto - Kernel detects whether the CPU model contains an
|
||||
implementation of Speculative Store Bypass and
|
||||
picks the most appropriate mitigation. If the
|
||||
CPU is not vulnerable, "off" is selected. If the
|
||||
CPU is vulnerable the default mitigation is
|
||||
architecture and Kconfig dependent. See below.
|
||||
prctl - Control Speculative Store Bypass per thread
|
||||
via prctl. Speculative Store Bypass is enabled
|
||||
for a process by default. The state of the control
|
||||
is inherited on fork.
|
||||
seccomp - Same as "prctl" above, but all seccomp threads
|
||||
will disable SSB unless they explicitly opt out.
|
||||
|
||||
Not specifying this option is equivalent to
|
||||
spec_store_bypass_disable=auto.
|
||||
|
||||
Default mitigations:
|
||||
X86: If CONFIG_SECCOMP=y "seccomp", otherwise "prctl"
|
||||
|
||||
spia_io_base= [HW,MTD]
|
||||
spia_fio_base=
|
||||
spia_pedr=
|
||||
|
||||
94
Documentation/spec_ctrl.txt
Normal file
94
Documentation/spec_ctrl.txt
Normal file
@@ -0,0 +1,94 @@
|
||||
===================
|
||||
Speculation Control
|
||||
===================
|
||||
|
||||
Quite some CPUs have speculation-related misfeatures which are in
|
||||
fact vulnerabilities causing data leaks in various forms even across
|
||||
privilege domains.
|
||||
|
||||
The kernel provides mitigation for such vulnerabilities in various
|
||||
forms. Some of these mitigations are compile-time configurable and some
|
||||
can be supplied on the kernel command line.
|
||||
|
||||
There is also a class of mitigations which are very expensive, but they can
|
||||
be restricted to a certain set of processes or tasks in controlled
|
||||
environments. The mechanism to control these mitigations is via
|
||||
:manpage:`prctl(2)`.
|
||||
|
||||
There are two prctl options which are related to this:
|
||||
|
||||
* PR_GET_SPECULATION_CTRL
|
||||
|
||||
* PR_SET_SPECULATION_CTRL
|
||||
|
||||
PR_GET_SPECULATION_CTRL
|
||||
-----------------------
|
||||
|
||||
PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature
|
||||
which is selected with arg2 of prctl(2). The return value uses bits 0-3 with
|
||||
the following meaning:
|
||||
|
||||
==== ===================== ===================================================
|
||||
Bit Define Description
|
||||
==== ===================== ===================================================
|
||||
0 PR_SPEC_PRCTL Mitigation can be controlled per task by
|
||||
PR_SET_SPECULATION_CTRL.
|
||||
1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is
|
||||
disabled.
|
||||
2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is
|
||||
enabled.
|
||||
3 PR_SPEC_FORCE_DISABLE Same as PR_SPEC_DISABLE, but cannot be undone. A
|
||||
subsequent prctl(..., PR_SPEC_ENABLE) will fail.
|
||||
==== ===================== ===================================================
|
||||
|
||||
If all bits are 0 the CPU is not affected by the speculation misfeature.
|
||||
|
||||
If PR_SPEC_PRCTL is set, then the per-task control of the mitigation is
|
||||
available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation
|
||||
misfeature will fail.
|
||||
|
||||
PR_SET_SPECULATION_CTRL
|
||||
-----------------------
|
||||
|
||||
PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which
|
||||
is selected by arg2 of :manpage:`prctl(2)` per task. arg3 is used to hand
|
||||
in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE or
|
||||
PR_SPEC_FORCE_DISABLE.
|
||||
|
||||
Common error codes
|
||||
------------------
|
||||
======= =================================================================
|
||||
Value Meaning
|
||||
======= =================================================================
|
||||
EINVAL The prctl is not implemented by the architecture or unused
|
||||
prctl(2) arguments are not 0.
|
||||
|
||||
ENODEV arg2 is selecting a not supported speculation misfeature.
|
||||
======= =================================================================
|
||||
|
||||
PR_SET_SPECULATION_CTRL error codes
|
||||
-----------------------------------
|
||||
======= =================================================================
|
||||
Value Meaning
|
||||
======= =================================================================
|
||||
0 Success
|
||||
|
||||
ERANGE arg3 is incorrect, i.e. it's neither PR_SPEC_ENABLE nor
|
||||
PR_SPEC_DISABLE nor PR_SPEC_FORCE_DISABLE.
|
||||
|
||||
ENXIO Control of the selected speculation misfeature is not possible.
|
||||
See PR_GET_SPECULATION_CTRL.
|
||||
|
||||
EPERM Speculation was disabled with PR_SPEC_FORCE_DISABLE and caller
|
||||
tried to enable it again.
|
||||
======= =================================================================
|
||||
|
||||
Speculation misfeature controls
|
||||
-------------------------------
|
||||
- PR_SPEC_STORE_BYPASS: Speculative Store Bypass
|
||||
|
||||
Invocations:
|
||||
* prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0);
|
||||
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);
|
||||
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);
|
||||
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0);
|
||||
7
Makefile
7
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 143
|
||||
SUBLEVEL = 159
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
@@ -419,7 +419,9 @@ export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
|
||||
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
|
||||
|
||||
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
|
||||
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV CFLAGS_KCOV CFLAGS_KASAN
|
||||
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
|
||||
export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE
|
||||
export CFLAGS_KCOV
|
||||
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
|
||||
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
|
||||
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
|
||||
@@ -625,6 +627,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias)
|
||||
|
||||
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
|
||||
KBUILD_CFLAGS += $(call cc-option,-Oz,-Os)
|
||||
|
||||
@@ -526,24 +526,19 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
|
||||
SYSCALL_DEFINE1(osf_utsname, char __user *, name)
|
||||
{
|
||||
int error;
|
||||
char tmp[5 * 32];
|
||||
|
||||
down_read(&uts_sem);
|
||||
error = -EFAULT;
|
||||
if (copy_to_user(name + 0, utsname()->sysname, 32))
|
||||
goto out;
|
||||
if (copy_to_user(name + 32, utsname()->nodename, 32))
|
||||
goto out;
|
||||
if (copy_to_user(name + 64, utsname()->release, 32))
|
||||
goto out;
|
||||
if (copy_to_user(name + 96, utsname()->version, 32))
|
||||
goto out;
|
||||
if (copy_to_user(name + 128, utsname()->machine, 32))
|
||||
goto out;
|
||||
memcpy(tmp + 0 * 32, utsname()->sysname, 32);
|
||||
memcpy(tmp + 1 * 32, utsname()->nodename, 32);
|
||||
memcpy(tmp + 2 * 32, utsname()->release, 32);
|
||||
memcpy(tmp + 3 * 32, utsname()->version, 32);
|
||||
memcpy(tmp + 4 * 32, utsname()->machine, 32);
|
||||
up_read(&uts_sem);
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
up_read(&uts_sem);
|
||||
return error;
|
||||
if (copy_to_user(name, tmp, sizeof(tmp)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE0(getpagesize)
|
||||
@@ -561,24 +556,22 @@ SYSCALL_DEFINE0(getdtablesize)
|
||||
*/
|
||||
SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen)
|
||||
{
|
||||
unsigned len;
|
||||
int i;
|
||||
int len, err = 0;
|
||||
char *kname;
|
||||
char tmp[32];
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, name, namelen))
|
||||
return -EFAULT;
|
||||
|
||||
len = namelen;
|
||||
if (len > 32)
|
||||
len = 32;
|
||||
if (namelen < 0 || namelen > 32)
|
||||
namelen = 32;
|
||||
|
||||
down_read(&uts_sem);
|
||||
for (i = 0; i < len; ++i) {
|
||||
__put_user(utsname()->domainname[i], name + i);
|
||||
if (utsname()->domainname[i] == '\0')
|
||||
break;
|
||||
}
|
||||
kname = utsname()->domainname;
|
||||
len = strnlen(kname, namelen);
|
||||
len = min(len + 1, namelen);
|
||||
memcpy(tmp, kname, len);
|
||||
up_read(&uts_sem);
|
||||
|
||||
if (copy_to_user(name, tmp, len))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -741,13 +734,14 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
|
||||
};
|
||||
unsigned long offset;
|
||||
const char *res;
|
||||
long len, err = -EINVAL;
|
||||
long len;
|
||||
char tmp[__NEW_UTS_LEN + 1];
|
||||
|
||||
offset = command-1;
|
||||
if (offset >= ARRAY_SIZE(sysinfo_table)) {
|
||||
/* Digital UNIX has a few unpublished interfaces here */
|
||||
printk("sysinfo(%d)", command);
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
down_read(&uts_sem);
|
||||
@@ -755,13 +749,11 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
|
||||
len = strlen(res)+1;
|
||||
if ((unsigned long)len > (unsigned long)count)
|
||||
len = count;
|
||||
if (copy_to_user(buf, res, len))
|
||||
err = -EFAULT;
|
||||
else
|
||||
err = 0;
|
||||
memcpy(tmp, res, len);
|
||||
up_read(&uts_sem);
|
||||
out:
|
||||
return err;
|
||||
if (copy_to_user(buf, tmp, len))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
|
||||
|
||||
@@ -14,7 +14,7 @@ endif
|
||||
|
||||
KBUILD_DEFCONFIG := nsim_700_defconfig
|
||||
|
||||
cflags-y += -fno-common -pipe -fno-builtin -D__linux__
|
||||
cflags-y += -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__
|
||||
cflags-$(CONFIG_ISA_ARCOMPACT) += -mA7
|
||||
cflags-$(CONFIG_ISA_ARCV2) += -mcpu=archs
|
||||
|
||||
@@ -137,16 +137,3 @@ dtbs: scripts
|
||||
|
||||
archclean:
|
||||
$(Q)$(MAKE) $(clean)=$(boot)
|
||||
|
||||
# Hacks to enable final link due to absence of link-time branch relexation
|
||||
# and gcc choosing optimal(shorter) branches at -O3
|
||||
#
|
||||
# vineetg Feb 2010: -mlong-calls switched off for overall kernel build
|
||||
# However lib/decompress_inflate.o (.init.text) calls
|
||||
# zlib_inflate_workspacesize (.text) causing relocation errors.
|
||||
# Thus forcing all exten calls in this file to be long calls
|
||||
export CFLAGS_decompress_inflate.o = -mmedium-calls
|
||||
export CFLAGS_initramfs.o = -mmedium-calls
|
||||
ifdef CONFIG_SMP
|
||||
export CFLAGS_core.o = -mmedium-calls
|
||||
endif
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
CONFIG_CROSS_COMPILE="arc-linux-"
|
||||
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
CONFIG_CROSS_COMPILE="arc-linux-"
|
||||
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
CONFIG_CROSS_COMPILE="arc-linux-"
|
||||
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
#ifndef __ASM_ARC_UDELAY_H
|
||||
#define __ASM_ARC_UDELAY_H
|
||||
|
||||
#include <asm-generic/types.h>
|
||||
#include <asm/param.h> /* HZ */
|
||||
|
||||
extern unsigned long loops_per_jiffy;
|
||||
|
||||
static inline void __delay(unsigned long loops)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
|
||||
@@ -34,9 +34,7 @@ struct machine_desc {
|
||||
const char *name;
|
||||
const char **dt_compat;
|
||||
void (*init_early)(void);
|
||||
#ifdef CONFIG_SMP
|
||||
void (*init_per_cpu)(unsigned int);
|
||||
#endif
|
||||
void (*init_machine)(void);
|
||||
void (*init_late)(void);
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ typedef pte_t * pgtable_t;
|
||||
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|
||||
|
||||
/* Default Permissions for stack/heaps pages (Non Executable) */
|
||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE)
|
||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||
|
||||
#define WANT_PAGE_VIRTUAL 1
|
||||
|
||||
|
||||
@@ -372,7 +372,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
|
||||
|
||||
/* Decode a PTE containing swap "identifier "into constituents */
|
||||
#define __swp_type(pte_lookalike) (((pte_lookalike).val) & 0x1f)
|
||||
#define __swp_offset(pte_lookalike) ((pte_lookalike).val << 13)
|
||||
#define __swp_offset(pte_lookalike) ((pte_lookalike).val >> 13)
|
||||
|
||||
/* NOPs, to keep generic kernel happy */
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
|
||||
@@ -31,10 +31,10 @@ void __init init_IRQ(void)
|
||||
/* a SMP H/w block could do IPI IRQ request here */
|
||||
if (plat_smp_ops.init_per_cpu)
|
||||
plat_smp_ops.init_per_cpu(smp_processor_id());
|
||||
#endif
|
||||
|
||||
if (machine_desc->init_per_cpu)
|
||||
machine_desc->init_per_cpu(smp_processor_id());
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -821,7 +821,7 @@ void flush_cache_mm(struct mm_struct *mm)
|
||||
void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr,
|
||||
unsigned long pfn)
|
||||
{
|
||||
unsigned int paddr = pfn << PAGE_SHIFT;
|
||||
phys_addr_t paddr = pfn << PAGE_SHIFT;
|
||||
|
||||
u_vaddr &= PAGE_MASK;
|
||||
|
||||
@@ -841,8 +841,9 @@ void flush_anon_page(struct vm_area_struct *vma, struct page *page,
|
||||
unsigned long u_vaddr)
|
||||
{
|
||||
/* TBD: do we really need to clear the kernel mapping */
|
||||
__flush_dcache_page(page_address(page), u_vaddr);
|
||||
__flush_dcache_page(page_address(page), page_address(page));
|
||||
__flush_dcache_page((phys_addr_t)page_address(page), u_vaddr);
|
||||
__flush_dcache_page((phys_addr_t)page_address(page),
|
||||
(phys_addr_t)page_address(page));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,11 @@
|
||||
};
|
||||
};
|
||||
|
||||
/* Table Table 5-79 of the TRM shows 480ab000 is reserved */
|
||||
&usb_otg_hs {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&iva {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -508,6 +508,8 @@
|
||||
|
||||
touchscreen-size-x = <480>;
|
||||
touchscreen-size-y = <272>;
|
||||
|
||||
wakeup-source;
|
||||
};
|
||||
|
||||
tlv320aic3106: tlv320aic3106@1b {
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
reg = <0x18008000 0x100>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
|
||||
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency = <100000>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -138,7 +138,7 @@
|
||||
reg = <0x1800b000 0x100>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency = <100000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -267,11 +267,7 @@
|
||||
compatible = "ti,dm6441-gpio";
|
||||
gpio-controller;
|
||||
reg = <0x226000 0x1000>;
|
||||
interrupts = <42 IRQ_TYPE_EDGE_BOTH
|
||||
43 IRQ_TYPE_EDGE_BOTH 44 IRQ_TYPE_EDGE_BOTH
|
||||
45 IRQ_TYPE_EDGE_BOTH 46 IRQ_TYPE_EDGE_BOTH
|
||||
47 IRQ_TYPE_EDGE_BOTH 48 IRQ_TYPE_EDGE_BOTH
|
||||
49 IRQ_TYPE_EDGE_BOTH 50 IRQ_TYPE_EDGE_BOTH>;
|
||||
interrupts = <42 43 44 45 46 47 48 49 50>;
|
||||
ti,ngpio = <144>;
|
||||
ti,davinci-gpio-unbanked = <0>;
|
||||
status = "disabled";
|
||||
|
||||
@@ -1250,7 +1250,7 @@
|
||||
/* non-prefetchable memory */
|
||||
0x82000000 0 0x08000000 0x08000000 0 0x00f00000>;
|
||||
num-lanes = <1>;
|
||||
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks IMX6SX_CLK_PCIE_REF_125M>,
|
||||
<&clks IMX6SX_CLK_PCIE_AXI>,
|
||||
<&clks IMX6SX_CLK_LVDS1_OUT>,
|
||||
|
||||
@@ -201,6 +201,7 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x70>;
|
||||
reset-gpio = <&gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -145,9 +145,11 @@ CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_CHIPIDEA=y
|
||||
CONFIG_USB_CHIPIDEA_UDC=y
|
||||
CONFIG_USB_CHIPIDEA_HOST=y
|
||||
CONFIG_USB_CHIPIDEA_ULPI=y
|
||||
CONFIG_NOP_USB_XCEIV=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_ETH=m
|
||||
CONFIG_USB_ULPI_BUS=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
|
||||
@@ -117,6 +117,7 @@ static inline u32 gic_read_iar(void)
|
||||
u32 irqstat;
|
||||
|
||||
asm volatile("mrc " __stringify(ICC_IAR1) : "=r" (irqstat));
|
||||
dsb(sy);
|
||||
return irqstat;
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ extern int __put_user_8(void *, unsigned long long);
|
||||
({ \
|
||||
unsigned long __limit = current_thread_info()->addr_limit - 1; \
|
||||
const typeof(*(p)) __user *__tmp_p = (p); \
|
||||
register const typeof(*(p)) __r2 asm("r2") = (x); \
|
||||
register typeof(*(p)) __r2 asm("r2") = (x); \
|
||||
register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
|
||||
register unsigned long __l asm("r1") = __limit; \
|
||||
register int __e asm("r0"); \
|
||||
|
||||
@@ -899,19 +899,35 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
|
||||
pmd = stage2_get_pmd(kvm, cache, addr);
|
||||
VM_BUG_ON(!pmd);
|
||||
|
||||
/*
|
||||
* Mapping in huge pages should only happen through a fault. If a
|
||||
* page is merged into a transparent huge page, the individual
|
||||
* subpages of that huge page should be unmapped through MMU
|
||||
* notifiers before we get here.
|
||||
*
|
||||
* Merging of CompoundPages is not supported; they should become
|
||||
* splitting first, unmapped, merged, and mapped back in on-demand.
|
||||
*/
|
||||
VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
|
||||
|
||||
old_pmd = *pmd;
|
||||
if (pmd_present(old_pmd)) {
|
||||
/*
|
||||
* Multiple vcpus faulting on the same PMD entry, can
|
||||
* lead to them sequentially updating the PMD with the
|
||||
* same value. Following the break-before-make
|
||||
* (pmd_clear() followed by tlb_flush()) process can
|
||||
* hinder forward progress due to refaults generated
|
||||
* on missing translations.
|
||||
*
|
||||
* Skip updating the page table if the entry is
|
||||
* unchanged.
|
||||
*/
|
||||
if (pmd_val(old_pmd) == pmd_val(*new_pmd))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Mapping in huge pages should only happen through a
|
||||
* fault. If a page is merged into a transparent huge
|
||||
* page, the individual subpages of that huge page
|
||||
* should be unmapped through MMU notifiers before we
|
||||
* get here.
|
||||
*
|
||||
* Merging of CompoundPages is not supported; they
|
||||
* should become splitting first, unmapped, merged,
|
||||
* and mapped back in on-demand.
|
||||
*/
|
||||
VM_BUG_ON(pmd_pfn(old_pmd) != pmd_pfn(*new_pmd));
|
||||
|
||||
pmd_clear(pmd);
|
||||
kvm_tlb_flush_vmid_ipa(kvm, addr);
|
||||
} else {
|
||||
@@ -968,6 +984,10 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
|
||||
/* Create 2nd stage page table mapping - Level 3 */
|
||||
old_pte = *pte;
|
||||
if (pte_present(old_pte)) {
|
||||
/* Skip page table update if there is no change */
|
||||
if (pte_val(old_pte) == pte_val(*new_pte))
|
||||
return 0;
|
||||
|
||||
kvm_set_pte(pte, __pte(0));
|
||||
kvm_tlb_flush_vmid_ipa(kvm, addr);
|
||||
} else {
|
||||
|
||||
@@ -260,6 +260,7 @@ static int __init exynos_pmu_irq_init(struct device_node *node,
|
||||
NULL);
|
||||
if (!domain) {
|
||||
iounmap(pmu_base_addr);
|
||||
pmu_base_addr = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -148,13 +148,20 @@ static int hi3xxx_hotplug_init(void)
|
||||
struct device_node *node;
|
||||
|
||||
node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
|
||||
if (node) {
|
||||
ctrl_base = of_iomap(node, 0);
|
||||
id = HI3620_CTRL;
|
||||
return 0;
|
||||
if (!node) {
|
||||
id = ERROR_CTRL;
|
||||
return -ENOENT;
|
||||
}
|
||||
id = ERROR_CTRL;
|
||||
return -ENOENT;
|
||||
|
||||
ctrl_base = of_iomap(node, 0);
|
||||
of_node_put(node);
|
||||
if (!ctrl_base) {
|
||||
id = ERROR_CTRL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
id = HI3620_CTRL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hi3xxx_set_cpu(int cpu, bool enable)
|
||||
@@ -173,11 +180,15 @@ static bool hix5hd2_hotplug_init(void)
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl");
|
||||
if (np) {
|
||||
ctrl_base = of_iomap(np, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (!np)
|
||||
return false;
|
||||
|
||||
ctrl_base = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
if (!ctrl_base)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void hix5hd2_set_cpu(int cpu, bool enable)
|
||||
@@ -219,10 +230,10 @@ void hip01_set_cpu(int cpu, bool enable)
|
||||
|
||||
if (!ctrl_base) {
|
||||
np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
|
||||
if (np)
|
||||
ctrl_base = of_iomap(np, 0);
|
||||
else
|
||||
BUG();
|
||||
BUG_ON(!np);
|
||||
ctrl_base = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
BUG_ON(!ctrl_base);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
|
||||
@@ -185,7 +185,7 @@ static int pxa_irq_suspend(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pxa_internal_irq_nr / 32; i++) {
|
||||
for (i = 0; i < DIV_ROUND_UP(pxa_internal_irq_nr, 32); i++) {
|
||||
void __iomem *base = irq_base(i);
|
||||
|
||||
saved_icmr[i] = __raw_readl(base + ICMR);
|
||||
@@ -204,7 +204,7 @@ static void pxa_irq_resume(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pxa_internal_irq_nr / 32; i++) {
|
||||
for (i = 0; i < DIV_ROUND_UP(pxa_internal_irq_nr, 32); i++) {
|
||||
void __iomem *base = irq_base(i);
|
||||
|
||||
__raw_writel(saved_icmr[i], base + ICMR);
|
||||
|
||||
@@ -716,19 +716,28 @@ int __mark_rodata_ro(void *unused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kernel_set_to_readonly __read_mostly;
|
||||
|
||||
void mark_rodata_ro(void)
|
||||
{
|
||||
kernel_set_to_readonly = 1;
|
||||
stop_machine(__mark_rodata_ro, NULL, NULL);
|
||||
}
|
||||
|
||||
void set_kernel_text_rw(void)
|
||||
{
|
||||
if (!kernel_set_to_readonly)
|
||||
return;
|
||||
|
||||
set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), false,
|
||||
current->active_mm);
|
||||
}
|
||||
|
||||
void set_kernel_text_ro(void)
|
||||
{
|
||||
if (!kernel_set_to_readonly)
|
||||
return;
|
||||
|
||||
set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true,
|
||||
current->active_mm);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
led@6 {
|
||||
label = "apq8016-sbc:blue:bt";
|
||||
gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "bt";
|
||||
linux,default-trigger = "bluetooth-power";
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -183,7 +183,7 @@ static void smp_store_cpu_info(unsigned int cpuid)
|
||||
* This is the secondary CPU boot entry. We're using this CPUs
|
||||
* idle thread stack, but a set of temporary page tables.
|
||||
*/
|
||||
asmlinkage void secondary_start_kernel(void)
|
||||
asmlinkage notrace void secondary_start_kernel(void)
|
||||
{
|
||||
struct mm_struct *mm = &init_mm;
|
||||
unsigned int cpu;
|
||||
|
||||
@@ -267,11 +267,13 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
|
||||
#define PFN_MASK ((1UL << (64 - PAGE_SHIFT)) - 1)
|
||||
|
||||
int pfn_valid(unsigned long pfn)
|
||||
{
|
||||
return (pfn & PFN_MASK) == pfn && memblock_is_map_memory(pfn << PAGE_SHIFT);
|
||||
phys_addr_t addr = pfn << PAGE_SHIFT;
|
||||
|
||||
if ((addr >> PAGE_SHIFT) != pfn)
|
||||
return 0;
|
||||
return memblock_is_memory(addr);
|
||||
}
|
||||
EXPORT_SYMBOL(pfn_valid);
|
||||
#endif
|
||||
|
||||
@@ -882,12 +882,12 @@ int pmd_clear_huge(pmd_t *pmd)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
|
||||
int pud_free_pmd_page(pud_t *pud)
|
||||
int pud_free_pmd_page(pud_t *pud, unsigned long addr)
|
||||
{
|
||||
return pud_none(*pud);
|
||||
}
|
||||
|
||||
int pmd_free_pte_page(pmd_t *pmd)
|
||||
int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
|
||||
{
|
||||
return pmd_none(*pmd);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
|
||||
static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
|
||||
unsigned long address)
|
||||
{
|
||||
pgtable_page_dtor(page);
|
||||
__free_page(page);
|
||||
}
|
||||
|
||||
@@ -73,8 +74,9 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm,
|
||||
return page;
|
||||
}
|
||||
|
||||
extern inline void pte_free(struct mm_struct *mm, struct page *page)
|
||||
static inline void pte_free(struct mm_struct *mm, struct page *page)
|
||||
{
|
||||
pgtable_page_dtor(page);
|
||||
__free_page(page);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,17 +21,19 @@ $(obj)/linux.bin.gz: $(obj)/linux.bin FORCE
|
||||
quiet_cmd_cp = CP $< $@$2
|
||||
cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
|
||||
|
||||
quiet_cmd_strip = STRIP $@
|
||||
quiet_cmd_strip = STRIP $< $@$2
|
||||
cmd_strip = $(STRIP) -K microblaze_start -K _end -K __log_buf \
|
||||
-K _fdt_start vmlinux -o $@
|
||||
-K _fdt_start $< -o $@$2
|
||||
|
||||
UIMAGE_LOADADDR = $(CONFIG_KERNEL_BASE_ADDR)
|
||||
UIMAGE_IN = $@
|
||||
UIMAGE_OUT = $@.ub
|
||||
|
||||
$(obj)/simpleImage.%: vmlinux FORCE
|
||||
$(call if_changed,cp,.unstrip)
|
||||
$(call if_changed,objcopy)
|
||||
$(call if_changed,uimage)
|
||||
$(call if_changed,strip)
|
||||
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
|
||||
$(call if_changed,strip,.strip)
|
||||
@echo 'Kernel: $(UIMAGE_OUT) is ready' ' (#'`cat .version`')'
|
||||
|
||||
clean-files += simpleImage.*.unstrip linux.bin.ub dts/*.dtb
|
||||
|
||||
@@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init);
|
||||
|
||||
void ath79_ddr_wb_flush(u32 reg)
|
||||
{
|
||||
void __iomem *flush_reg = ath79_ddr_wb_flush_base + reg;
|
||||
void __iomem *flush_reg = ath79_ddr_wb_flush_base + (reg * 4);
|
||||
|
||||
/* Flush the DDR write buffer. */
|
||||
__raw_writel(0x1, flush_reg);
|
||||
|
||||
@@ -44,6 +44,7 @@ static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
|
||||
|
||||
static void ath79_restart(char *command)
|
||||
{
|
||||
local_irq_disable();
|
||||
ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
|
||||
for (;;)
|
||||
if (cpu_wait)
|
||||
|
||||
@@ -249,12 +249,6 @@ static int __init bcm47xx_cpu_fixes(void)
|
||||
*/
|
||||
if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
|
||||
cpu_wait = NULL;
|
||||
|
||||
/*
|
||||
* BCM47XX Erratum "R10: PCIe Transactions Periodically Fail"
|
||||
* Enable ExternalSync for sync instruction to take effect
|
||||
*/
|
||||
set_c0_config7(MIPS_CONF7_ES);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -349,6 +349,7 @@ static int __init octeon_ehci_device_init(void)
|
||||
return 0;
|
||||
|
||||
pd = of_find_device_by_node(ehci_node);
|
||||
of_node_put(ehci_node);
|
||||
if (!pd)
|
||||
return 0;
|
||||
|
||||
@@ -411,6 +412,7 @@ static int __init octeon_ohci_device_init(void)
|
||||
return 0;
|
||||
|
||||
pd = of_find_device_by_node(ohci_node);
|
||||
of_node_put(ohci_node);
|
||||
if (!pd)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -141,14 +141,14 @@ static inline void * phys_to_virt(unsigned long address)
|
||||
/*
|
||||
* ISA I/O bus memory addresses are 1:1 with the physical address.
|
||||
*/
|
||||
static inline unsigned long isa_virt_to_bus(volatile void * address)
|
||||
static inline unsigned long isa_virt_to_bus(volatile void *address)
|
||||
{
|
||||
return (unsigned long)address - PAGE_OFFSET;
|
||||
return virt_to_phys(address);
|
||||
}
|
||||
|
||||
static inline void * isa_bus_to_virt(unsigned long address)
|
||||
static inline void *isa_bus_to_virt(unsigned long address)
|
||||
{
|
||||
return (void *)(address + PAGE_OFFSET);
|
||||
return phys_to_virt(address);
|
||||
}
|
||||
|
||||
#define isa_page_to_bus page_to_phys
|
||||
|
||||
@@ -133,6 +133,7 @@ static inline u32 ath79_pll_rr(unsigned reg)
|
||||
static inline void ath79_reset_wr(unsigned reg, u32 val)
|
||||
{
|
||||
__raw_writel(val, ath79_reset_base + reg);
|
||||
(void) __raw_readl(ath79_reset_base + reg); /* flush */
|
||||
}
|
||||
|
||||
static inline u32 ath79_reset_rr(unsigned reg)
|
||||
|
||||
@@ -606,8 +606,6 @@
|
||||
#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
|
||||
|
||||
#define MIPS_CONF7_RPS (_ULCAST_(1) << 2)
|
||||
/* ExternalSync */
|
||||
#define MIPS_CONF7_ES (_ULCAST_(1) << 8)
|
||||
|
||||
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
|
||||
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
|
||||
@@ -2015,7 +2013,6 @@ __BUILD_SET_C0(status)
|
||||
__BUILD_SET_C0(cause)
|
||||
__BUILD_SET_C0(config)
|
||||
__BUILD_SET_C0(config5)
|
||||
__BUILD_SET_C0(config7)
|
||||
__BUILD_SET_C0(intcontrol)
|
||||
__BUILD_SET_C0(intctl)
|
||||
__BUILD_SET_C0(srsmap)
|
||||
|
||||
@@ -89,7 +89,7 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
|
||||
phys_addr_t size = resource_size(rsrc);
|
||||
|
||||
*start = fixup_bigphys_addr(rsrc->start, size);
|
||||
*end = rsrc->start + size;
|
||||
*end = rsrc->start + size - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -137,7 +137,7 @@ struct mips_fpu_struct {
|
||||
|
||||
#define NUM_DSP_REGS 6
|
||||
|
||||
typedef __u32 dspreg_t;
|
||||
typedef unsigned long dspreg_t;
|
||||
|
||||
struct mips_dsp_state {
|
||||
dspreg_t dspr[NUM_DSP_REGS];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
platform-$(CONFIG_MACH_INGENIC) += jz4740/
|
||||
cflags-$(CONFIG_MACH_INGENIC) += -I$(srctree)/arch/mips/include/asm/mach-jz4740
|
||||
load-$(CONFIG_MACH_INGENIC) += 0xffffffff80010000
|
||||
zload-$(CONFIG_MACH_INGENIC) += 0xffffffff80600000
|
||||
zload-$(CONFIG_MACH_INGENIC) += 0xffffffff81000000
|
||||
|
||||
@@ -117,7 +117,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
struct thread_info *ti = task_thread_info(p);
|
||||
struct pt_regs *childregs, *regs = current_pt_regs();
|
||||
unsigned long childksp;
|
||||
p->set_child_tid = p->clear_child_tid = NULL;
|
||||
|
||||
childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32;
|
||||
|
||||
|
||||
@@ -878,7 +878,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
goto out;
|
||||
}
|
||||
dregs = __get_dsp_regs(child);
|
||||
tmp = (unsigned long) (dregs[addr - DSP_BASE]);
|
||||
tmp = dregs[addr - DSP_BASE];
|
||||
break;
|
||||
}
|
||||
case DSP_CONTROL:
|
||||
|
||||
@@ -140,7 +140,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
goto out;
|
||||
}
|
||||
dregs = __get_dsp_regs(child);
|
||||
tmp = (unsigned long) (dregs[addr - DSP_BASE]);
|
||||
tmp = dregs[addr - DSP_BASE];
|
||||
break;
|
||||
}
|
||||
case DSP_CONTROL:
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/irqchip/mips-gic.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/timekeeper_internal.h>
|
||||
|
||||
#include <asm/abi.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
/* Kernel-provided data used by the VDSO. */
|
||||
@@ -128,12 +130,30 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||
vvar_size = gic_size + PAGE_SIZE;
|
||||
size = vvar_size + image->size;
|
||||
|
||||
/*
|
||||
* Find a region that's large enough for us to perform the
|
||||
* colour-matching alignment below.
|
||||
*/
|
||||
if (cpu_has_dc_aliases)
|
||||
size += shm_align_mask + 1;
|
||||
|
||||
base = get_unmapped_area(NULL, 0, size, 0, 0);
|
||||
if (IS_ERR_VALUE(base)) {
|
||||
ret = base;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we suffer from dcache aliasing, ensure that the VDSO data page
|
||||
* mapping is coloured the same as the kernel's mapping of that memory.
|
||||
* This ensures that when the kernel updates the VDSO data userland
|
||||
* will observe it without requiring cache invalidations.
|
||||
*/
|
||||
if (cpu_has_dc_aliases) {
|
||||
base = __ALIGN_MASK(base, shm_align_mask);
|
||||
base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask;
|
||||
}
|
||||
|
||||
data_addr = base + gic_size;
|
||||
vdso_addr = data_addr + PAGE_SIZE;
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include "libgcc.h"
|
||||
|
||||
/*
|
||||
* GCC 7 suboptimally generates __multi3 calls for mips64r6, so for that
|
||||
* specific case only we'll implement it here.
|
||||
* GCC 7 & older can suboptimally generate __multi3 calls for mips64r6, so for
|
||||
* that specific case only we implement that intrinsic here.
|
||||
*
|
||||
* See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981
|
||||
*/
|
||||
#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ == 7)
|
||||
#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ < 8)
|
||||
|
||||
/* multiply 64-bit values, low 64-bits returned */
|
||||
static inline long long notrace dmulu(long long a, long long b)
|
||||
|
||||
@@ -138,7 +138,7 @@ u32 pci_ohci_read_reg(int reg)
|
||||
break;
|
||||
case PCI_OHCI_INT_REG:
|
||||
_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
|
||||
if ((lo & 0x00000f00) == CS5536_USB_INTR)
|
||||
if (((lo >> PIC_YSEL_LOW_USB_SHIFT) & 0xf) == CS5536_USB_INTR)
|
||||
conf_data = 1;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -712,7 +712,8 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
|
||||
static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
|
||||
{
|
||||
/* Catch bad driver code */
|
||||
BUG_ON(size == 0);
|
||||
if (WARN_ON(size == 0))
|
||||
return;
|
||||
|
||||
preempt_disable();
|
||||
if (cpu_has_inclusive_pcaches) {
|
||||
@@ -745,7 +746,8 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
|
||||
static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
|
||||
{
|
||||
/* Catch bad driver code */
|
||||
BUG_ON(size == 0);
|
||||
if (WARN_ON(size == 0))
|
||||
return;
|
||||
|
||||
preempt_disable();
|
||||
if (cpu_has_inclusive_pcaches) {
|
||||
|
||||
@@ -152,8 +152,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
|
||||
top_of_kernel_stack = sp;
|
||||
|
||||
p->set_child_tid = p->clear_child_tid = NULL;
|
||||
|
||||
/* Locate userspace context on stack... */
|
||||
sp -= STACK_FRAME_OVERHEAD; /* redzone */
|
||||
sp -= sizeof(struct pt_regs);
|
||||
|
||||
@@ -178,7 +178,7 @@ config PREFETCH
|
||||
|
||||
config MLONGCALLS
|
||||
bool "Enable the -mlong-calls compiler option for big kernels"
|
||||
def_bool y if (!MODULES)
|
||||
default y
|
||||
depends on PA8X00
|
||||
help
|
||||
If you configure the kernel to include many drivers built-in instead
|
||||
|
||||
32
arch/parisc/include/asm/barrier.h
Normal file
32
arch/parisc/include/asm/barrier.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_BARRIER_H
|
||||
#define __ASM_BARRIER_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* The synchronize caches instruction executes as a nop on systems in
|
||||
which all memory references are performed in order. */
|
||||
#define synchronize_caches() __asm__ __volatile__ ("sync" : : : "memory")
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
#define mb() do { synchronize_caches(); } while (0)
|
||||
#define rmb() mb()
|
||||
#define wmb() mb()
|
||||
#define dma_rmb() mb()
|
||||
#define dma_wmb() mb()
|
||||
#else
|
||||
#define mb() barrier()
|
||||
#define rmb() barrier()
|
||||
#define wmb() barrier()
|
||||
#define dma_rmb() barrier()
|
||||
#define dma_wmb() barrier()
|
||||
#endif
|
||||
|
||||
#define __smp_mb() mb()
|
||||
#define __smp_rmb() mb()
|
||||
#define __smp_wmb() mb()
|
||||
|
||||
#include <asm-generic/barrier.h>
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* __ASM_BARRIER_H */
|
||||
@@ -21,7 +21,6 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x,
|
||||
{
|
||||
volatile unsigned int *a;
|
||||
|
||||
mb();
|
||||
a = __ldcw_align(x);
|
||||
while (__ldcw(a) == 0)
|
||||
while (*a == 0)
|
||||
@@ -31,16 +30,15 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x,
|
||||
local_irq_disable();
|
||||
} else
|
||||
cpu_relax();
|
||||
mb();
|
||||
}
|
||||
|
||||
static inline void arch_spin_unlock(arch_spinlock_t *x)
|
||||
{
|
||||
volatile unsigned int *a;
|
||||
mb();
|
||||
|
||||
a = __ldcw_align(x);
|
||||
*a = 1;
|
||||
mb();
|
||||
*a = 1;
|
||||
}
|
||||
|
||||
static inline int arch_spin_trylock(arch_spinlock_t *x)
|
||||
@@ -48,10 +46,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *x)
|
||||
volatile unsigned int *a;
|
||||
int ret;
|
||||
|
||||
mb();
|
||||
a = __ldcw_align(x);
|
||||
ret = __ldcw(a) != 0;
|
||||
mb();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -481,6 +481,8 @@
|
||||
/* Release pa_tlb_lock lock without reloading lock address. */
|
||||
.macro tlb_unlock0 spc,tmp
|
||||
#ifdef CONFIG_SMP
|
||||
or,COND(=) %r0,\spc,%r0
|
||||
sync
|
||||
or,COND(=) %r0,\spc,%r0
|
||||
stw \spc,0(\tmp)
|
||||
#endif
|
||||
|
||||
@@ -354,6 +354,7 @@ ENDPROC(flush_data_cache_local)
|
||||
.macro tlb_unlock la,flags,tmp
|
||||
#ifdef CONFIG_SMP
|
||||
ldi 1,\tmp
|
||||
sync
|
||||
stw \tmp,0(\la)
|
||||
mtsm \flags
|
||||
#endif
|
||||
|
||||
@@ -627,11 +627,12 @@ cas_action:
|
||||
stw %r1, 4(%sr2,%r20)
|
||||
#endif
|
||||
/* The load and store could fail */
|
||||
1: ldw,ma 0(%r26), %r28
|
||||
1: ldw 0(%r26), %r28
|
||||
sub,<> %r28, %r25, %r0
|
||||
2: stw,ma %r24, 0(%r26)
|
||||
2: stw %r24, 0(%r26)
|
||||
/* Free lock */
|
||||
stw,ma %r20, 0(%sr2,%r20)
|
||||
sync
|
||||
stw %r20, 0(%sr2,%r20)
|
||||
#if ENABLE_LWS_DEBUG
|
||||
/* Clear thread register indicator */
|
||||
stw %r0, 4(%sr2,%r20)
|
||||
@@ -645,6 +646,7 @@ cas_action:
|
||||
3:
|
||||
/* Error occurred on load or store */
|
||||
/* Free lock */
|
||||
sync
|
||||
stw %r20, 0(%sr2,%r20)
|
||||
#if ENABLE_LWS_DEBUG
|
||||
stw %r0, 4(%sr2,%r20)
|
||||
@@ -794,30 +796,30 @@ cas2_action:
|
||||
ldo 1(%r0),%r28
|
||||
|
||||
/* 8bit CAS */
|
||||
13: ldb,ma 0(%r26), %r29
|
||||
13: ldb 0(%r26), %r29
|
||||
sub,= %r29, %r25, %r0
|
||||
b,n cas2_end
|
||||
14: stb,ma %r24, 0(%r26)
|
||||
14: stb %r24, 0(%r26)
|
||||
b cas2_end
|
||||
copy %r0, %r28
|
||||
nop
|
||||
nop
|
||||
|
||||
/* 16bit CAS */
|
||||
15: ldh,ma 0(%r26), %r29
|
||||
15: ldh 0(%r26), %r29
|
||||
sub,= %r29, %r25, %r0
|
||||
b,n cas2_end
|
||||
16: sth,ma %r24, 0(%r26)
|
||||
16: sth %r24, 0(%r26)
|
||||
b cas2_end
|
||||
copy %r0, %r28
|
||||
nop
|
||||
nop
|
||||
|
||||
/* 32bit CAS */
|
||||
17: ldw,ma 0(%r26), %r29
|
||||
17: ldw 0(%r26), %r29
|
||||
sub,= %r29, %r25, %r0
|
||||
b,n cas2_end
|
||||
18: stw,ma %r24, 0(%r26)
|
||||
18: stw %r24, 0(%r26)
|
||||
b cas2_end
|
||||
copy %r0, %r28
|
||||
nop
|
||||
@@ -825,10 +827,10 @@ cas2_action:
|
||||
|
||||
/* 64bit CAS */
|
||||
#ifdef CONFIG_64BIT
|
||||
19: ldd,ma 0(%r26), %r29
|
||||
19: ldd 0(%r26), %r29
|
||||
sub,*= %r29, %r25, %r0
|
||||
b,n cas2_end
|
||||
20: std,ma %r24, 0(%r26)
|
||||
20: std %r24, 0(%r26)
|
||||
copy %r0, %r28
|
||||
#else
|
||||
/* Compare first word */
|
||||
@@ -846,7 +848,8 @@ cas2_action:
|
||||
|
||||
cas2_end:
|
||||
/* Free lock */
|
||||
stw,ma %r20, 0(%sr2,%r20)
|
||||
sync
|
||||
stw %r20, 0(%sr2,%r20)
|
||||
/* Enable interrupts */
|
||||
ssm PSW_SM_I, %r0
|
||||
/* Return to userspace, set no error */
|
||||
@@ -856,6 +859,7 @@ cas2_end:
|
||||
22:
|
||||
/* Error occurred on load or store */
|
||||
/* Free lock */
|
||||
sync
|
||||
stw %r20, 0(%sr2,%r20)
|
||||
ssm PSW_SM_I, %r0
|
||||
ldo 1(%r0),%r28
|
||||
|
||||
@@ -194,9 +194,6 @@ struct fadump_crash_info_header {
|
||||
struct cpumask cpu_online_mask;
|
||||
};
|
||||
|
||||
/* Crash memory ranges */
|
||||
#define INIT_CRASHMEM_RANGES (INIT_MEMBLOCK_REGIONS + 2)
|
||||
|
||||
struct fad_crash_memory_ranges {
|
||||
unsigned long long base;
|
||||
unsigned long long size;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <linux/crash_dump.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/prom.h>
|
||||
@@ -48,8 +49,10 @@ static struct fadump_mem_struct fdm;
|
||||
static const struct fadump_mem_struct *fdm_active;
|
||||
|
||||
static DEFINE_MUTEX(fadump_mutex);
|
||||
struct fad_crash_memory_ranges crash_memory_ranges[INIT_CRASHMEM_RANGES];
|
||||
struct fad_crash_memory_ranges *crash_memory_ranges;
|
||||
int crash_memory_ranges_size;
|
||||
int crash_mem_ranges;
|
||||
int max_crash_mem_ranges;
|
||||
|
||||
/* Scan the Firmware Assisted dump configuration details. */
|
||||
int __init early_init_dt_scan_fw_dump(unsigned long node,
|
||||
@@ -726,38 +729,88 @@ static int __init process_fadump(const struct fadump_mem_struct *fdm_active)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fadump_add_crash_memory(unsigned long long base,
|
||||
unsigned long long end)
|
||||
static void free_crash_memory_ranges(void)
|
||||
{
|
||||
kfree(crash_memory_ranges);
|
||||
crash_memory_ranges = NULL;
|
||||
crash_memory_ranges_size = 0;
|
||||
max_crash_mem_ranges = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate or reallocate crash memory ranges array in incremental units
|
||||
* of PAGE_SIZE.
|
||||
*/
|
||||
static int allocate_crash_memory_ranges(void)
|
||||
{
|
||||
struct fad_crash_memory_ranges *new_array;
|
||||
u64 new_size;
|
||||
|
||||
new_size = crash_memory_ranges_size + PAGE_SIZE;
|
||||
pr_debug("Allocating %llu bytes of memory for crash memory ranges\n",
|
||||
new_size);
|
||||
|
||||
new_array = krealloc(crash_memory_ranges, new_size, GFP_KERNEL);
|
||||
if (new_array == NULL) {
|
||||
pr_err("Insufficient memory for setting up crash memory ranges\n");
|
||||
free_crash_memory_ranges();
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
crash_memory_ranges = new_array;
|
||||
crash_memory_ranges_size = new_size;
|
||||
max_crash_mem_ranges = (new_size /
|
||||
sizeof(struct fad_crash_memory_ranges));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fadump_add_crash_memory(unsigned long long base,
|
||||
unsigned long long end)
|
||||
{
|
||||
if (base == end)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (crash_mem_ranges == max_crash_mem_ranges) {
|
||||
int ret;
|
||||
|
||||
ret = allocate_crash_memory_ranges();
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("crash_memory_range[%d] [%#016llx-%#016llx], %#llx bytes\n",
|
||||
crash_mem_ranges, base, end - 1, (end - base));
|
||||
crash_memory_ranges[crash_mem_ranges].base = base;
|
||||
crash_memory_ranges[crash_mem_ranges].size = end - base;
|
||||
crash_mem_ranges++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fadump_exclude_reserved_area(unsigned long long start,
|
||||
static int fadump_exclude_reserved_area(unsigned long long start,
|
||||
unsigned long long end)
|
||||
{
|
||||
unsigned long long ra_start, ra_end;
|
||||
int ret = 0;
|
||||
|
||||
ra_start = fw_dump.reserve_dump_area_start;
|
||||
ra_end = ra_start + fw_dump.reserve_dump_area_size;
|
||||
|
||||
if ((ra_start < end) && (ra_end > start)) {
|
||||
if ((start < ra_start) && (end > ra_end)) {
|
||||
fadump_add_crash_memory(start, ra_start);
|
||||
fadump_add_crash_memory(ra_end, end);
|
||||
ret = fadump_add_crash_memory(start, ra_start);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = fadump_add_crash_memory(ra_end, end);
|
||||
} else if (start < ra_start) {
|
||||
fadump_add_crash_memory(start, ra_start);
|
||||
ret = fadump_add_crash_memory(start, ra_start);
|
||||
} else if (ra_end < end) {
|
||||
fadump_add_crash_memory(ra_end, end);
|
||||
ret = fadump_add_crash_memory(ra_end, end);
|
||||
}
|
||||
} else
|
||||
fadump_add_crash_memory(start, end);
|
||||
ret = fadump_add_crash_memory(start, end);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fadump_init_elfcore_header(char *bufp)
|
||||
@@ -793,10 +846,11 @@ static int fadump_init_elfcore_header(char *bufp)
|
||||
* Traverse through memblock structure and setup crash memory ranges. These
|
||||
* ranges will be used create PT_LOAD program headers in elfcore header.
|
||||
*/
|
||||
static void fadump_setup_crash_memory_ranges(void)
|
||||
static int fadump_setup_crash_memory_ranges(void)
|
||||
{
|
||||
struct memblock_region *reg;
|
||||
unsigned long long start, end;
|
||||
int ret;
|
||||
|
||||
pr_debug("Setup crash memory ranges.\n");
|
||||
crash_mem_ranges = 0;
|
||||
@@ -807,7 +861,9 @@ static void fadump_setup_crash_memory_ranges(void)
|
||||
* specified during fadump registration. We need to create a separate
|
||||
* program header for this chunk with the correct offset.
|
||||
*/
|
||||
fadump_add_crash_memory(RMA_START, fw_dump.boot_memory_size);
|
||||
ret = fadump_add_crash_memory(RMA_START, fw_dump.boot_memory_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for_each_memblock(memory, reg) {
|
||||
start = (unsigned long long)reg->base;
|
||||
@@ -816,8 +872,12 @@ static void fadump_setup_crash_memory_ranges(void)
|
||||
start = fw_dump.boot_memory_size;
|
||||
|
||||
/* add this range excluding the reserved dump area. */
|
||||
fadump_exclude_reserved_area(start, end);
|
||||
ret = fadump_exclude_reserved_area(start, end);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -941,6 +1001,7 @@ static void register_fadump(void)
|
||||
{
|
||||
unsigned long addr;
|
||||
void *vaddr;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If no memory is reserved then we can not register for firmware-
|
||||
@@ -949,7 +1010,9 @@ static void register_fadump(void)
|
||||
if (!fw_dump.reserve_dump_area_size)
|
||||
return;
|
||||
|
||||
fadump_setup_crash_memory_ranges();
|
||||
ret = fadump_setup_crash_memory_ranges();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
addr = be64_to_cpu(fdm.rmr_region.destination_address) + be64_to_cpu(fdm.rmr_region.source_len);
|
||||
/* Initialize fadump crash info header. */
|
||||
@@ -1028,6 +1091,7 @@ void fadump_cleanup(void)
|
||||
} else if (fw_dump.dump_registered) {
|
||||
/* Un-register Firmware-assisted dump if it was registered. */
|
||||
fadump_unregister_dump(&fdm);
|
||||
free_crash_memory_ranges();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -720,7 +720,7 @@ start_here:
|
||||
tovirt(r6,r6)
|
||||
lis r5, abatron_pteptrs@h
|
||||
ori r5, r5, abatron_pteptrs@l
|
||||
stw r5, 0xf0(r0) /* Must match your Abatron config file */
|
||||
stw r5, 0xf0(0) /* Must match your Abatron config file */
|
||||
tophys(r5,r5)
|
||||
stw r6, 0(r5)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
@@ -69,14 +69,14 @@ static inline void slb_shadow_update(unsigned long ea, int ssize,
|
||||
* updating it. No write barriers are needed here, provided
|
||||
* we only update the current CPU's SLB shadow buffer.
|
||||
*/
|
||||
p->save_area[index].esid = 0;
|
||||
p->save_area[index].vsid = cpu_to_be64(mk_vsid_data(ea, ssize, flags));
|
||||
p->save_area[index].esid = cpu_to_be64(mk_esid_data(ea, ssize, index));
|
||||
WRITE_ONCE(p->save_area[index].esid, 0);
|
||||
WRITE_ONCE(p->save_area[index].vsid, cpu_to_be64(mk_vsid_data(ea, ssize, flags)));
|
||||
WRITE_ONCE(p->save_area[index].esid, cpu_to_be64(mk_esid_data(ea, ssize, index)));
|
||||
}
|
||||
|
||||
static inline void slb_shadow_clear(enum slb_index index)
|
||||
{
|
||||
get_slb_shadow()->save_area[index].esid = 0;
|
||||
WRITE_ONCE(get_slb_shadow()->save_area[index].esid, 0);
|
||||
}
|
||||
|
||||
static inline void create_shadowed_slbe(unsigned long ea, int ssize,
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <asm/sections.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <platforms/chrp/chrp.h>
|
||||
|
||||
extern spinlock_t rtc_lock;
|
||||
|
||||
#define NVRAM_AS0 0x74
|
||||
@@ -62,7 +64,7 @@ long __init chrp_time_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int chrp_cmos_clock_read(int addr)
|
||||
static int chrp_cmos_clock_read(int addr)
|
||||
{
|
||||
if (nvram_as1 != 0)
|
||||
outb(addr>>8, nvram_as1);
|
||||
@@ -70,7 +72,7 @@ int chrp_cmos_clock_read(int addr)
|
||||
return (inb(nvram_data));
|
||||
}
|
||||
|
||||
void chrp_cmos_clock_write(unsigned long val, int addr)
|
||||
static void chrp_cmos_clock_write(unsigned long val, int addr)
|
||||
{
|
||||
if (nvram_as1 != 0)
|
||||
outb(addr>>8, nvram_as1);
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
*/
|
||||
#define HW_BROADWAY_ICR 0x00
|
||||
#define HW_BROADWAY_IMR 0x04
|
||||
#define HW_STARLET_ICR 0x08
|
||||
#define HW_STARLET_IMR 0x0c
|
||||
|
||||
|
||||
/*
|
||||
@@ -74,6 +76,9 @@ static void hlwd_pic_unmask(struct irq_data *d)
|
||||
void __iomem *io_base = irq_data_get_irq_chip_data(d);
|
||||
|
||||
setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
|
||||
|
||||
/* Make sure the ARM (aka. Starlet) doesn't handle this interrupt. */
|
||||
clrbits32(io_base + HW_STARLET_IMR, 1 << irq);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -467,7 +467,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
|
||||
boot_infos_t *bi = (boot_infos_t *) r4;
|
||||
unsigned long hdr;
|
||||
unsigned long space;
|
||||
unsigned long ptr, x;
|
||||
unsigned long ptr;
|
||||
char *model;
|
||||
unsigned long offset = reloc_offset();
|
||||
|
||||
@@ -561,6 +561,8 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
|
||||
* MMU switched OFF, so this should not be useful anymore.
|
||||
*/
|
||||
if (bi->version < 4) {
|
||||
unsigned long x __maybe_unused;
|
||||
|
||||
bootx_printf("Touching pages...\n");
|
||||
|
||||
/*
|
||||
|
||||
@@ -359,6 +359,7 @@ static int pmac_late_init(void)
|
||||
}
|
||||
machine_late_initcall(powermac, pmac_late_init);
|
||||
|
||||
void note_bootable_part(dev_t dev, int part, int goodness);
|
||||
/*
|
||||
* This is __init_refok because we check for "initializing" before
|
||||
* touching any of the __init sensitive things and "initializing"
|
||||
|
||||
@@ -371,7 +371,7 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
|
||||
/* Closed or other error drop */
|
||||
if (rc != OPAL_SUCCESS && rc != OPAL_BUSY &&
|
||||
rc != OPAL_BUSY_EVENT) {
|
||||
written = total_len;
|
||||
written += total_len;
|
||||
break;
|
||||
}
|
||||
if (rc == OPAL_SUCCESS) {
|
||||
|
||||
@@ -300,7 +300,7 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
|
||||
}
|
||||
|
||||
savep = __va(regs->gpr[3]);
|
||||
regs->gpr[3] = savep[0]; /* restore original r3 */
|
||||
regs->gpr[3] = be64_to_cpu(savep[0]); /* restore original r3 */
|
||||
|
||||
/* If it isn't an extended log we can use the per cpu 64bit buffer */
|
||||
h = (struct rtas_error_log *)&savep[1];
|
||||
@@ -311,7 +311,7 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
|
||||
int len, error_log_length;
|
||||
|
||||
error_log_length = 8 + rtas_error_extended_log_length(h);
|
||||
len = max_t(int, error_log_length, RTAS_ERROR_LOG_MAX);
|
||||
len = min_t(int, error_log_length, RTAS_ERROR_LOG_MAX);
|
||||
memset(global_mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
|
||||
memcpy(global_mce_data_buf, h, len);
|
||||
errhdr = (struct rtas_error_log *)global_mce_data_buf;
|
||||
|
||||
@@ -196,7 +196,7 @@ static int mpic_msgr_probe(struct platform_device *dev)
|
||||
|
||||
/* IO map the message register block. */
|
||||
of_address_to_resource(np, 0, &rsrc);
|
||||
msgr_block_addr = ioremap(rsrc.start, rsrc.end - rsrc.start);
|
||||
msgr_block_addr = ioremap(rsrc.start, resource_size(&rsrc));
|
||||
if (!msgr_block_addr) {
|
||||
dev_err(&dev->dev, "Failed to iomap MPIC message registers");
|
||||
return -EFAULT;
|
||||
|
||||
@@ -113,7 +113,7 @@ struct hws_basic_entry {
|
||||
|
||||
struct hws_diag_entry {
|
||||
unsigned int def:16; /* 0-15 Data Entry Format */
|
||||
unsigned int R:14; /* 16-19 and 20-30 reserved */
|
||||
unsigned int R:15; /* 16-19 and 20-30 reserved */
|
||||
unsigned int I:1; /* 31 entry valid or invalid */
|
||||
u8 data[]; /* Machine-dependent sample data */
|
||||
} __packed;
|
||||
@@ -129,7 +129,9 @@ struct hws_trailer_entry {
|
||||
unsigned int f:1; /* 0 - Block Full Indicator */
|
||||
unsigned int a:1; /* 1 - Alert request control */
|
||||
unsigned int t:1; /* 2 - Timestamp format */
|
||||
unsigned long long:61; /* 3 - 63: Reserved */
|
||||
unsigned int :29; /* 3 - 31: Reserved */
|
||||
unsigned int bsdes:16; /* 32-47: size of basic SDE */
|
||||
unsigned int dsdes:16; /* 48-63: size of diagnostic SDE */
|
||||
};
|
||||
unsigned long long flags; /* 0 - 63: All indicators */
|
||||
};
|
||||
|
||||
@@ -261,7 +261,6 @@ struct qdio_outbuf_state {
|
||||
void *user;
|
||||
};
|
||||
|
||||
#define QDIO_OUTBUF_STATE_FLAG_NONE 0x00
|
||||
#define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01
|
||||
|
||||
#define CHSC_AC1_INITIATE_INPUTQ 0x80
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
*/
|
||||
ENTRY(memset)
|
||||
ltgr %r4,%r4
|
||||
bzr %r14
|
||||
jz .Lmemset_exit
|
||||
ltgr %r3,%r3
|
||||
jnz .Lmemset_fill
|
||||
aghi %r4,-1
|
||||
@@ -41,12 +41,13 @@ ENTRY(memset)
|
||||
.Lmemset_clear_rest:
|
||||
larl %r3,.Lmemset_xc
|
||||
ex %r4,0(%r3)
|
||||
.Lmemset_exit:
|
||||
BR_EX %r14
|
||||
.Lmemset_fill:
|
||||
stc %r3,0(%r2)
|
||||
cghi %r4,1
|
||||
lgr %r1,%r2
|
||||
ber %r14
|
||||
je .Lmemset_fill_exit
|
||||
aghi %r4,-2
|
||||
srlg %r3,%r4,8
|
||||
ltgr %r3,%r3
|
||||
@@ -58,6 +59,7 @@ ENTRY(memset)
|
||||
.Lmemset_fill_rest:
|
||||
larl %r3,.Lmemset_mvc
|
||||
ex %r4,0(%r3)
|
||||
.Lmemset_fill_exit:
|
||||
BR_EX %r14
|
||||
.Lmemset_xc:
|
||||
xc 0(1,%r1),0(%r1)
|
||||
@@ -71,7 +73,7 @@ ENTRY(memset)
|
||||
*/
|
||||
ENTRY(memcpy)
|
||||
ltgr %r4,%r4
|
||||
bzr %r14
|
||||
jz .Lmemcpy_exit
|
||||
aghi %r4,-1
|
||||
srlg %r5,%r4,8
|
||||
ltgr %r5,%r5
|
||||
@@ -80,6 +82,7 @@ ENTRY(memcpy)
|
||||
.Lmemcpy_rest:
|
||||
larl %r5,.Lmemcpy_mvc
|
||||
ex %r4,0(%r5)
|
||||
.Lmemcpy_exit:
|
||||
BR_EX %r14
|
||||
.Lmemcpy_loop:
|
||||
mvc 0(256,%r1),0(%r3)
|
||||
|
||||
@@ -459,6 +459,8 @@ retry:
|
||||
/* No reason to continue if interrupted by SIGKILL. */
|
||||
if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
|
||||
fault = VM_FAULT_SIGNAL;
|
||||
if (flags & FAULT_FLAG_RETRY_NOWAIT)
|
||||
goto out_up;
|
||||
goto out;
|
||||
}
|
||||
if (unlikely(fault & VM_FAULT_ERROR))
|
||||
|
||||
@@ -522,8 +522,6 @@ static void bpf_jit_epilogue(struct bpf_jit *jit)
|
||||
/* br %r1 */
|
||||
_EMIT2(0x07f1);
|
||||
} else {
|
||||
/* larl %r1,.+14 */
|
||||
EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14);
|
||||
/* ex 0,S390_lowcore.br_r1_tampoline */
|
||||
EMIT4_DISP(0x44000000, REG_0, REG_0,
|
||||
offsetof(struct _lowcore, br_r1_trampoline));
|
||||
|
||||
@@ -412,6 +412,8 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||
hwirq = 0;
|
||||
for_each_pci_msi_entry(msi, pdev) {
|
||||
rc = -EIO;
|
||||
if (hwirq >= msi_vecs)
|
||||
break;
|
||||
irq = irq_alloc_desc(0); /* Alloc irq on node 0 */
|
||||
if (irq < 0)
|
||||
goto out_msi;
|
||||
|
||||
@@ -201,23 +201,27 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig,
|
||||
|
||||
asmlinkage long sys_getdomainname(char __user *name, int len)
|
||||
{
|
||||
int nlen, err;
|
||||
|
||||
int nlen, err;
|
||||
char tmp[__NEW_UTS_LEN + 1];
|
||||
|
||||
if (len < 0)
|
||||
return -EINVAL;
|
||||
|
||||
down_read(&uts_sem);
|
||||
|
||||
down_read(&uts_sem);
|
||||
|
||||
nlen = strlen(utsname()->domainname) + 1;
|
||||
err = -EINVAL;
|
||||
if (nlen > len)
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
memcpy(tmp, utsname()->domainname, nlen);
|
||||
|
||||
err = -EFAULT;
|
||||
if (!copy_to_user(name, utsname()->domainname, nlen))
|
||||
err = 0;
|
||||
up_read(&uts_sem);
|
||||
|
||||
out:
|
||||
if (copy_to_user(name, tmp, nlen))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
out_unlock:
|
||||
up_read(&uts_sem);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -524,23 +524,27 @@ extern void check_pending(int signum);
|
||||
|
||||
SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len)
|
||||
{
|
||||
int nlen, err;
|
||||
int nlen, err;
|
||||
char tmp[__NEW_UTS_LEN + 1];
|
||||
|
||||
if (len < 0)
|
||||
return -EINVAL;
|
||||
|
||||
down_read(&uts_sem);
|
||||
|
||||
down_read(&uts_sem);
|
||||
|
||||
nlen = strlen(utsname()->domainname) + 1;
|
||||
err = -EINVAL;
|
||||
if (nlen > len)
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
memcpy(tmp, utsname()->domainname, nlen);
|
||||
|
||||
err = -EFAULT;
|
||||
if (!copy_to_user(name, utsname()->domainname, nlen))
|
||||
err = 0;
|
||||
up_read(&uts_sem);
|
||||
|
||||
out:
|
||||
if (copy_to_user(name, tmp, nlen))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
out_unlock:
|
||||
up_read(&uts_sem);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -79,24 +79,33 @@ ENTRY(entry_SYSENTER_compat)
|
||||
ASM_CLAC /* Clear AC after saving FLAGS */
|
||||
|
||||
pushq $__USER32_CS /* pt_regs->cs */
|
||||
xorq %r8,%r8
|
||||
pushq %r8 /* pt_regs->ip = 0 (placeholder) */
|
||||
pushq $0 /* pt_regs->ip = 0 (placeholder) */
|
||||
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 = 0 */
|
||||
pushq %r8 /* pt_regs->r9 = 0 */
|
||||
pushq %r8 /* pt_regs->r10 = 0 */
|
||||
pushq %r8 /* pt_regs->r11 = 0 */
|
||||
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) */
|
||||
pushq %r8 /* pt_regs->r12 = 0 */
|
||||
pushq %r8 /* pt_regs->r13 = 0 */
|
||||
pushq %r8 /* pt_regs->r14 = 0 */
|
||||
pushq %r8 /* pt_regs->r15 = 0 */
|
||||
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
|
||||
|
||||
/*
|
||||
@@ -185,17 +194,26 @@ ENTRY(entry_SYSCALL_compat)
|
||||
pushq %rdx /* pt_regs->dx */
|
||||
pushq %rbp /* pt_regs->cx (stashed in bp) */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
xorq %r8,%r8
|
||||
pushq %r8 /* pt_regs->r8 = 0 */
|
||||
pushq %r8 /* pt_regs->r9 = 0 */
|
||||
pushq %r8 /* pt_regs->r10 = 0 */
|
||||
pushq %r8 /* pt_regs->r11 = 0 */
|
||||
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) */
|
||||
pushq %r8 /* pt_regs->r12 = 0 */
|
||||
pushq %r8 /* pt_regs->r13 = 0 */
|
||||
pushq %r8 /* pt_regs->r14 = 0 */
|
||||
pushq %r8 /* pt_regs->r15 = 0 */
|
||||
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
|
||||
@@ -292,17 +310,26 @@ ENTRY(entry_INT80_compat)
|
||||
pushq %rdx /* pt_regs->dx */
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
xorq %r8,%r8
|
||||
pushq %r8 /* pt_regs->r8 = 0 */
|
||||
pushq %r8 /* pt_regs->r9 = 0 */
|
||||
pushq %r8 /* pt_regs->r10 = 0 */
|
||||
pushq %r8 /* pt_regs->r11 = 0 */
|
||||
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
|
||||
|
||||
/*
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#ifndef _ASM_X86_MACH_DEFAULT_APM_H
|
||||
#define _ASM_X86_MACH_DEFAULT_APM_H
|
||||
|
||||
#include <asm/nospec-branch.h>
|
||||
|
||||
#ifdef APM_ZERO_SEGS
|
||||
# define APM_DO_ZERO_SEGS \
|
||||
"pushl %%ds\n\t" \
|
||||
@@ -31,6 +33,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,
|
||||
* N.B. We do NOT need a cld after the BIOS call
|
||||
* because we always save and restore the flags.
|
||||
*/
|
||||
firmware_restrict_branch_speculation_start();
|
||||
__asm__ __volatile__(APM_DO_ZERO_SEGS
|
||||
"pushl %%edi\n\t"
|
||||
"pushl %%ebp\n\t"
|
||||
@@ -43,6 +46,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,
|
||||
"=S" (*esi)
|
||||
: "a" (func), "b" (ebx_in), "c" (ecx_in)
|
||||
: "memory", "cc");
|
||||
firmware_restrict_branch_speculation_end();
|
||||
}
|
||||
|
||||
static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
|
||||
@@ -55,6 +59,7 @@ static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
|
||||
* N.B. We do NOT need a cld after the BIOS call
|
||||
* because we always save and restore the flags.
|
||||
*/
|
||||
firmware_restrict_branch_speculation_start();
|
||||
__asm__ __volatile__(APM_DO_ZERO_SEGS
|
||||
"pushl %%edi\n\t"
|
||||
"pushl %%ebp\n\t"
|
||||
@@ -67,6 +72,7 @@ static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
|
||||
"=S" (si)
|
||||
: "a" (func), "b" (ebx_in), "c" (ecx_in)
|
||||
: "memory", "cc");
|
||||
firmware_restrict_branch_speculation_end();
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
|
||||
|
||||
asm volatile ("cmp %1,%2; sbb %0,%0;"
|
||||
:"=r" (mask)
|
||||
:"r"(size),"r" (index)
|
||||
:"g"(size),"r" (index)
|
||||
:"cc");
|
||||
return mask;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ enum cpuid_leafs
|
||||
CPUID_8000_000A_EDX,
|
||||
CPUID_7_ECX,
|
||||
CPUID_8000_0007_EBX,
|
||||
CPUID_7_EDX,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_X86_FEATURE_NAMES
|
||||
@@ -78,8 +79,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
||||
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
|
||||
REQUIRED_MASK_CHECK || \
|
||||
BUILD_BUG_ON_ZERO(NCAPINTS != 18))
|
||||
BUILD_BUG_ON_ZERO(NCAPINTS != 19))
|
||||
|
||||
#define DISABLED_MASK_BIT_SET(feature_bit) \
|
||||
( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
|
||||
@@ -100,8 +102,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
|
||||
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \
|
||||
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
|
||||
DISABLED_MASK_CHECK || \
|
||||
BUILD_BUG_ON_ZERO(NCAPINTS != 18))
|
||||
BUILD_BUG_ON_ZERO(NCAPINTS != 19))
|
||||
|
||||
#define cpu_has(c, bit) \
|
||||
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/*
|
||||
* Defines x86 CPU feature bits
|
||||
*/
|
||||
#define NCAPINTS 18 /* N 32-bit words worth of info */
|
||||
#define NCAPINTS 19 /* N 32-bit words worth of info */
|
||||
#define NBUGINTS 1 /* N 32-bit bug flags */
|
||||
|
||||
/*
|
||||
@@ -193,14 +193,29 @@
|
||||
#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
|
||||
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
|
||||
|
||||
#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
|
||||
#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* Fill RSB on context switches */
|
||||
#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
|
||||
#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
|
||||
|
||||
#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
|
||||
#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
|
||||
|
||||
#define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
|
||||
#define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */
|
||||
|
||||
#define X86_FEATURE_RETPOLINE ( 7*32+29) /* Generic Retpoline mitigation for Spectre variant 2 */
|
||||
#define X86_FEATURE_RETPOLINE_AMD ( 7*32+30) /* AMD Retpoline mitigation for Spectre variant 2 */
|
||||
/* Because the ALTERNATIVE scheme is for members of the X86_FEATURE club... */
|
||||
#define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */
|
||||
|
||||
#define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled*/
|
||||
#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
|
||||
#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
|
||||
#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation */
|
||||
|
||||
#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */
|
||||
#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */
|
||||
#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
|
||||
#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
|
||||
#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
|
||||
|
||||
/* Virtualization flags: Linux defined, word 8 */
|
||||
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
|
||||
#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
|
||||
@@ -251,6 +266,10 @@
|
||||
|
||||
/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
|
||||
#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
|
||||
#define X86_FEATURE_AMD_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */
|
||||
#define X86_FEATURE_AMD_IBRS (13*32+14) /* Indirect Branch Restricted Speculation */
|
||||
#define X86_FEATURE_AMD_STIBP (13*32+15) /* Single Thread Indirect Branch Predictors */
|
||||
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
|
||||
|
||||
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
|
||||
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
|
||||
@@ -285,6 +304,16 @@
|
||||
#define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
|
||||
#define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
|
||||
|
||||
|
||||
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
|
||||
#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
|
||||
#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
|
||||
#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
|
||||
#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
|
||||
#define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */
|
||||
#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
|
||||
#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */
|
||||
|
||||
/*
|
||||
* BUG word(s)
|
||||
*/
|
||||
@@ -302,5 +331,7 @@
|
||||
#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */
|
||||
#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
|
||||
#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
|
||||
#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */
|
||||
#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
|
||||
|
||||
#endif /* _ASM_X86_CPUFEATURES_H */
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#define DISABLED_MASK15 0
|
||||
#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)
|
||||
#define DISABLED_MASK17 0
|
||||
#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
|
||||
#define DISABLED_MASK18 0
|
||||
#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
|
||||
|
||||
#endif /* _ASM_X86_DISABLED_FEATURES_H */
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <asm/fpu/api.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/nospec-branch.h>
|
||||
|
||||
/*
|
||||
* We map the EFI regions needed for runtime services non-contiguously,
|
||||
@@ -41,8 +42,10 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);
|
||||
({ \
|
||||
efi_status_t __s; \
|
||||
kernel_fpu_begin(); \
|
||||
firmware_restrict_branch_speculation_start(); \
|
||||
__s = ((efi_##f##_t __attribute__((regparm(0)))*) \
|
||||
efi.systab->runtime->f)(args); \
|
||||
firmware_restrict_branch_speculation_end(); \
|
||||
kernel_fpu_end(); \
|
||||
__s; \
|
||||
})
|
||||
@@ -51,8 +54,10 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);
|
||||
#define __efi_call_virt(f, args...) \
|
||||
({ \
|
||||
kernel_fpu_begin(); \
|
||||
firmware_restrict_branch_speculation_start(); \
|
||||
((efi_##f##_t __attribute__((regparm(0)))*) \
|
||||
efi.systab->runtime->f)(args); \
|
||||
firmware_restrict_branch_speculation_end(); \
|
||||
kernel_fpu_end(); \
|
||||
})
|
||||
|
||||
@@ -73,7 +78,9 @@ extern u64 asmlinkage efi_call(void *fp, ...);
|
||||
efi_sync_low_kernel_mappings(); \
|
||||
preempt_disable(); \
|
||||
__kernel_fpu_begin(); \
|
||||
firmware_restrict_branch_speculation_start(); \
|
||||
__s = efi_call((void *)efi.systab->runtime->f, __VA_ARGS__); \
|
||||
firmware_restrict_branch_speculation_end(); \
|
||||
__kernel_fpu_end(); \
|
||||
preempt_enable(); \
|
||||
__s; \
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#define INTEL_FAM6_CORE_YONAH 0x0E
|
||||
|
||||
#define INTEL_FAM6_CORE2_MEROM 0x0F
|
||||
#define INTEL_FAM6_CORE2_MEROM_L 0x16
|
||||
#define INTEL_FAM6_CORE2_PENRYN 0x17
|
||||
@@ -20,6 +21,7 @@
|
||||
#define INTEL_FAM6_NEHALEM 0x1E
|
||||
#define INTEL_FAM6_NEHALEM_EP 0x1A
|
||||
#define INTEL_FAM6_NEHALEM_EX 0x2E
|
||||
|
||||
#define INTEL_FAM6_WESTMERE 0x25
|
||||
#define INTEL_FAM6_WESTMERE2 0x1F
|
||||
#define INTEL_FAM6_WESTMERE_EP 0x2C
|
||||
@@ -36,9 +38,9 @@
|
||||
#define INTEL_FAM6_HASWELL_GT3E 0x46
|
||||
|
||||
#define INTEL_FAM6_BROADWELL_CORE 0x3D
|
||||
#define INTEL_FAM6_BROADWELL_XEON_D 0x56
|
||||
#define INTEL_FAM6_BROADWELL_GT3E 0x47
|
||||
#define INTEL_FAM6_BROADWELL_X 0x4F
|
||||
#define INTEL_FAM6_BROADWELL_XEON_D 0x56
|
||||
|
||||
#define INTEL_FAM6_SKYLAKE_MOBILE 0x4E
|
||||
#define INTEL_FAM6_SKYLAKE_DESKTOP 0x5E
|
||||
@@ -56,13 +58,15 @@
|
||||
#define INTEL_FAM6_ATOM_SILVERMONT1 0x37 /* BayTrail/BYT / Valleyview */
|
||||
#define INTEL_FAM6_ATOM_SILVERMONT2 0x4D /* Avaton/Rangely */
|
||||
#define INTEL_FAM6_ATOM_AIRMONT 0x4C /* CherryTrail / Braswell */
|
||||
#define INTEL_FAM6_ATOM_MERRIFIELD1 0x4A /* Tangier */
|
||||
#define INTEL_FAM6_ATOM_MERRIFIELD2 0x5A /* Annidale */
|
||||
#define INTEL_FAM6_ATOM_MERRIFIELD 0x4A /* Tangier */
|
||||
#define INTEL_FAM6_ATOM_MOOREFIELD 0x5A /* Annidale */
|
||||
#define INTEL_FAM6_ATOM_GOLDMONT 0x5C
|
||||
#define INTEL_FAM6_ATOM_DENVERTON 0x5F /* Goldmont Microserver */
|
||||
#define INTEL_FAM6_ATOM_GEMINI_LAKE 0x7A
|
||||
|
||||
/* Xeon Phi */
|
||||
|
||||
#define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */
|
||||
#define INTEL_FAM6_XEON_PHI_KNM 0x85 /* Knights Mill */
|
||||
|
||||
#endif /* _ASM_X86_INTEL_FAMILY_H */
|
||||
|
||||
@@ -351,4 +351,10 @@ extern void arch_phys_wc_del(int handle);
|
||||
#define arch_phys_wc_add arch_phys_wc_add
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_PAT
|
||||
extern int arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size);
|
||||
extern void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size);
|
||||
#define arch_io_reserve_memtype_wc arch_io_reserve_memtype_wc
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_IO_H */
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
* Interrupt control:
|
||||
*/
|
||||
|
||||
static inline unsigned long native_save_fl(void)
|
||||
/* Declaration required for gcc < 4.9 to prevent -Werror=missing-prototypes */
|
||||
extern inline unsigned long native_save_fl(void);
|
||||
extern inline unsigned long native_save_fl(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
@@ -26,7 +28,8 @@ static inline unsigned long native_save_fl(void)
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void native_restore_fl(unsigned long flags)
|
||||
extern inline void native_restore_fl(unsigned long flags);
|
||||
extern inline void native_restore_fl(unsigned long flags)
|
||||
{
|
||||
asm volatile("push %0 ; popf"
|
||||
: /* no output */
|
||||
|
||||
@@ -3,12 +3,18 @@
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
/*
|
||||
* The x86 doesn't have a mmu context, but
|
||||
* we put the segment information here.
|
||||
* x86 has arch-specific MMU state beyond what lives in mm_struct.
|
||||
*/
|
||||
typedef struct {
|
||||
/*
|
||||
* ctx_id uniquely identifies this mm_struct. A ctx_id will never
|
||||
* be reused, and zero is not a valid ctx_id.
|
||||
*/
|
||||
u64 ctx_id;
|
||||
|
||||
#ifdef CONFIG_MODIFY_LDT_SYSCALL
|
||||
struct ldt_struct *ldt;
|
||||
#endif
|
||||
@@ -24,6 +30,11 @@ typedef struct {
|
||||
atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */
|
||||
} mm_context_t;
|
||||
|
||||
#define INIT_MM_CONTEXT(mm) \
|
||||
.context = { \
|
||||
.ctx_id = 1, \
|
||||
}
|
||||
|
||||
void leave_mm(int cpu);
|
||||
|
||||
#endif /* _ASM_X86_MMU_H */
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/mpx.h>
|
||||
|
||||
extern atomic64_t last_mm_ctx_id;
|
||||
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
static inline void paravirt_activate_mm(struct mm_struct *prev,
|
||||
struct mm_struct *next)
|
||||
@@ -52,15 +55,15 @@ struct ldt_struct {
|
||||
/*
|
||||
* Used for LDT copy/destruction.
|
||||
*/
|
||||
int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
|
||||
void destroy_context(struct mm_struct *mm);
|
||||
int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm);
|
||||
void destroy_context_ldt(struct mm_struct *mm);
|
||||
#else /* CONFIG_MODIFY_LDT_SYSCALL */
|
||||
static inline int init_new_context(struct task_struct *tsk,
|
||||
struct mm_struct *mm)
|
||||
static inline int init_new_context_ldt(struct task_struct *tsk,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void destroy_context(struct mm_struct *mm) {}
|
||||
static inline void destroy_context_ldt(struct mm_struct *mm) {}
|
||||
#endif
|
||||
|
||||
static inline void load_mm_ldt(struct mm_struct *mm)
|
||||
@@ -102,6 +105,17 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
|
||||
}
|
||||
|
||||
static inline int init_new_context(struct task_struct *tsk,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id);
|
||||
return init_new_context_ldt(tsk, mm);
|
||||
}
|
||||
static inline void destroy_context(struct mm_struct *mm)
|
||||
{
|
||||
destroy_context_ldt(mm);
|
||||
}
|
||||
|
||||
extern void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk);
|
||||
|
||||
|
||||
@@ -32,6 +32,15 @@
|
||||
#define EFER_FFXSR (1<<_EFER_FFXSR)
|
||||
|
||||
/* Intel MSRs. Some also available on other CPUs */
|
||||
#define MSR_IA32_SPEC_CTRL 0x00000048 /* Speculation Control */
|
||||
#define SPEC_CTRL_IBRS (1 << 0) /* Indirect Branch Restricted Speculation */
|
||||
#define SPEC_CTRL_STIBP (1 << 1) /* Single Thread Indirect Branch Predictors */
|
||||
#define SPEC_CTRL_SSBD_SHIFT 2 /* Speculative Store Bypass Disable bit */
|
||||
#define SPEC_CTRL_SSBD (1 << SPEC_CTRL_SSBD_SHIFT) /* Speculative Store Bypass Disable */
|
||||
|
||||
#define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */
|
||||
#define PRED_CMD_IBPB (1 << 0) /* Indirect Branch Prediction Barrier */
|
||||
|
||||
#define MSR_IA32_PERFCTR0 0x000000c1
|
||||
#define MSR_IA32_PERFCTR1 0x000000c2
|
||||
#define MSR_FSB_FREQ 0x000000cd
|
||||
@@ -45,6 +54,16 @@
|
||||
#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
|
||||
|
||||
#define MSR_MTRRcap 0x000000fe
|
||||
|
||||
#define MSR_IA32_ARCH_CAPABILITIES 0x0000010a
|
||||
#define ARCH_CAP_RDCL_NO (1 << 0) /* Not susceptible to Meltdown */
|
||||
#define ARCH_CAP_IBRS_ALL (1 << 1) /* Enhanced IBRS support */
|
||||
#define ARCH_CAP_SSB_NO (1 << 4) /*
|
||||
* Not susceptible to Speculative Store Bypass
|
||||
* attack, so no Speculative Store Bypass
|
||||
* control required.
|
||||
*/
|
||||
|
||||
#define MSR_IA32_BBL_CR_CTL 0x00000119
|
||||
#define MSR_IA32_BBL_CR_CTL3 0x0000011e
|
||||
|
||||
@@ -132,6 +151,7 @@
|
||||
|
||||
/* DEBUGCTLMSR bits (others vary by model): */
|
||||
#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */
|
||||
#define DEBUGCTLMSR_BTF_SHIFT 1
|
||||
#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */
|
||||
#define DEBUGCTLMSR_TR (1UL << 6)
|
||||
#define DEBUGCTLMSR_BTS (1UL << 7)
|
||||
@@ -308,6 +328,8 @@
|
||||
#define MSR_AMD64_IBSOPDATA4 0xc001103d
|
||||
#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
|
||||
|
||||
#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f
|
||||
|
||||
/* Fam 16h MSRs */
|
||||
#define MSR_F16H_L2I_PERF_CTL 0xc0010230
|
||||
#define MSR_F16H_L2I_PERF_CTR 0xc0010231
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/alternative-asm.h>
|
||||
#include <asm/cpufeatures.h>
|
||||
#include <asm/msr-index.h>
|
||||
|
||||
/*
|
||||
* Fill the CPU return stack buffer.
|
||||
@@ -171,6 +172,14 @@ enum spectre_v2_mitigation {
|
||||
SPECTRE_V2_IBRS,
|
||||
};
|
||||
|
||||
/* The Speculative Store Bypass disable variants */
|
||||
enum ssb_mitigation {
|
||||
SPEC_STORE_BYPASS_NONE,
|
||||
SPEC_STORE_BYPASS_DISABLE,
|
||||
SPEC_STORE_BYPASS_PRCTL,
|
||||
SPEC_STORE_BYPASS_SECCOMP,
|
||||
};
|
||||
|
||||
extern char __indirect_thunk_start[];
|
||||
extern char __indirect_thunk_end[];
|
||||
|
||||
@@ -194,6 +203,51 @@ static inline void vmexit_fill_RSB(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature)
|
||||
{
|
||||
asm volatile(ALTERNATIVE("", "wrmsr", %c[feature])
|
||||
: : "c" (msr),
|
||||
"a" ((u32)val),
|
||||
"d" ((u32)(val >> 32)),
|
||||
[feature] "i" (feature)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void indirect_branch_prediction_barrier(void)
|
||||
{
|
||||
u64 val = PRED_CMD_IBPB;
|
||||
|
||||
alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB);
|
||||
}
|
||||
|
||||
/* The Intel SPEC CTRL MSR base value cache */
|
||||
extern u64 x86_spec_ctrl_base;
|
||||
|
||||
/*
|
||||
* With retpoline, we must use IBRS to restrict branch prediction
|
||||
* before calling into firmware.
|
||||
*
|
||||
* (Implemented as CPP macros due to header hell.)
|
||||
*/
|
||||
#define firmware_restrict_branch_speculation_start() \
|
||||
do { \
|
||||
u64 val = x86_spec_ctrl_base | SPEC_CTRL_IBRS; \
|
||||
\
|
||||
preempt_disable(); \
|
||||
alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \
|
||||
X86_FEATURE_USE_IBRS_FW); \
|
||||
} while (0)
|
||||
|
||||
#define firmware_restrict_branch_speculation_end() \
|
||||
do { \
|
||||
u64 val = x86_spec_ctrl_base; \
|
||||
\
|
||||
alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \
|
||||
X86_FEATURE_USE_IBRS_FW); \
|
||||
preempt_enable(); \
|
||||
} while (0)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
|
||||
@@ -27,8 +27,13 @@
|
||||
#define N_EXCEPTION_STACKS 1
|
||||
|
||||
#ifdef CONFIG_X86_PAE
|
||||
/* 44=32+12, the limit we can fit into an unsigned long pfn */
|
||||
#define __PHYSICAL_MASK_SHIFT 44
|
||||
/*
|
||||
* This is beyond the 44 bit limit imposed by the 32bit long pfns,
|
||||
* but we need the full mask to make sure inverted PROT_NONE
|
||||
* entries have all the host bits set in a guest.
|
||||
* The real limit is still 44 bits.
|
||||
*/
|
||||
#define __PHYSICAL_MASK_SHIFT 52
|
||||
#define __VIRTUAL_MASK_SHIFT 32
|
||||
|
||||
#else /* !CONFIG_X86_PAE */
|
||||
|
||||
@@ -77,4 +77,21 @@ static inline unsigned long pte_bitop(unsigned long value, unsigned int rightshi
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val })
|
||||
|
||||
/* No inverted PFNs on 2 level page tables */
|
||||
|
||||
static inline u64 protnone_mask(u64 val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline bool __pte_needs_invert(u64 val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* _ASM_X86_PGTABLE_2LEVEL_H */
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef _ASM_X86_PGTABLE_3LEVEL_H
|
||||
#define _ASM_X86_PGTABLE_3LEVEL_H
|
||||
|
||||
#include <asm/atomic64_32.h>
|
||||
|
||||
/*
|
||||
* Intel Physical Address Extension (PAE) Mode - three-level page
|
||||
* tables on PPro+ CPUs.
|
||||
@@ -142,10 +144,7 @@ static inline pte_t native_ptep_get_and_clear(pte_t *ptep)
|
||||
{
|
||||
pte_t res;
|
||||
|
||||
/* xchg acts as a barrier before the setting of the high bits */
|
||||
res.pte_low = xchg(&ptep->pte_low, 0);
|
||||
res.pte_high = ptep->pte_high;
|
||||
ptep->pte_high = 0;
|
||||
res.pte = (pteval_t)atomic64_xchg((atomic64_t *)ptep, 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -177,11 +176,44 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp)
|
||||
#endif
|
||||
|
||||
/* Encode and de-code a swap entry */
|
||||
#define SWP_TYPE_BITS 5
|
||||
|
||||
#define SWP_OFFSET_FIRST_BIT (_PAGE_BIT_PROTNONE + 1)
|
||||
|
||||
/* We always extract/encode the offset by shifting it all the way up, and then down again */
|
||||
#define SWP_OFFSET_SHIFT (SWP_OFFSET_FIRST_BIT + SWP_TYPE_BITS)
|
||||
|
||||
#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > 5)
|
||||
#define __swp_type(x) (((x).val) & 0x1f)
|
||||
#define __swp_offset(x) ((x).val >> 5)
|
||||
#define __swp_entry(type, offset) ((swp_entry_t){(type) | (offset) << 5})
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high })
|
||||
#define __swp_entry_to_pte(x) ((pte_t){ { .pte_high = (x).val } })
|
||||
|
||||
/*
|
||||
* Normally, __swp_entry() converts from arch-independent swp_entry_t to
|
||||
* arch-dependent swp_entry_t, and __swp_entry_to_pte() just stores the result
|
||||
* to pte. But here we have 32bit swp_entry_t and 64bit pte, and need to use the
|
||||
* whole 64 bits. Thus, we shift the "real" arch-dependent conversion to
|
||||
* __swp_entry_to_pte() through the following helper macro based on 64bit
|
||||
* __swp_entry().
|
||||
*/
|
||||
#define __swp_pteval_entry(type, offset) ((pteval_t) { \
|
||||
(~(pteval_t)(offset) << SWP_OFFSET_SHIFT >> SWP_TYPE_BITS) \
|
||||
| ((pteval_t)(type) << (64 - SWP_TYPE_BITS)) })
|
||||
|
||||
#define __swp_entry_to_pte(x) ((pte_t){ .pte = \
|
||||
__swp_pteval_entry(__swp_type(x), __swp_offset(x)) })
|
||||
/*
|
||||
* Analogically, __pte_to_swp_entry() doesn't just extract the arch-dependent
|
||||
* swp_entry_t, but also has to convert it from 64bit to the 32bit
|
||||
* intermediate representation, using the following macros based on 64bit
|
||||
* __swp_type() and __swp_offset().
|
||||
*/
|
||||
#define __pteval_swp_type(x) ((unsigned long)((x).pte >> (64 - SWP_TYPE_BITS)))
|
||||
#define __pteval_swp_offset(x) ((unsigned long)(~((x).pte) << SWP_TYPE_BITS >> SWP_OFFSET_SHIFT))
|
||||
|
||||
#define __pte_to_swp_entry(pte) (__swp_entry(__pteval_swp_type(pte), \
|
||||
__pteval_swp_offset(pte)))
|
||||
|
||||
#include <asm/pgtable-invert.h>
|
||||
|
||||
#endif /* _ASM_X86_PGTABLE_3LEVEL_H */
|
||||
|
||||
41
arch/x86/include/asm/pgtable-invert.h
Normal file
41
arch/x86/include/asm/pgtable-invert.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_PGTABLE_INVERT_H
|
||||
#define _ASM_PGTABLE_INVERT_H 1
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* A clear pte value is special, and doesn't get inverted.
|
||||
*
|
||||
* Note that even users that only pass a pgprot_t (rather
|
||||
* than a full pte) won't trigger the special zero case,
|
||||
* because even PAGE_NONE has _PAGE_PROTNONE | _PAGE_ACCESSED
|
||||
* set. So the all zero case really is limited to just the
|
||||
* cleared page table entry case.
|
||||
*/
|
||||
static inline bool __pte_needs_invert(u64 val)
|
||||
{
|
||||
return val && !(val & _PAGE_PRESENT);
|
||||
}
|
||||
|
||||
/* Get a mask to xor with the page table entry to get the correct pfn. */
|
||||
static inline u64 protnone_mask(u64 val)
|
||||
{
|
||||
return __pte_needs_invert(val) ? ~0ull : 0;
|
||||
}
|
||||
|
||||
static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask)
|
||||
{
|
||||
/*
|
||||
* When a PTE transitions from NONE to !NONE or vice-versa
|
||||
* invert the PFN part to stop speculation.
|
||||
* pte_pfn undoes this when needed.
|
||||
*/
|
||||
if (__pte_needs_invert(oldval) != __pte_needs_invert(val))
|
||||
val = (val & ~mask) | (~val & mask);
|
||||
return val;
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
@@ -148,19 +148,34 @@ static inline int pte_special(pte_t pte)
|
||||
return pte_flags(pte) & _PAGE_SPECIAL;
|
||||
}
|
||||
|
||||
/* Entries that were set to PROT_NONE are inverted */
|
||||
|
||||
static inline u64 protnone_mask(u64 val);
|
||||
|
||||
static inline unsigned long pte_pfn(pte_t pte)
|
||||
{
|
||||
return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
|
||||
phys_addr_t pfn = pte_val(pte);
|
||||
pfn ^= protnone_mask(pfn);
|
||||
return (pfn & PTE_PFN_MASK) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned long pmd_pfn(pmd_t pmd)
|
||||
{
|
||||
return (pmd_val(pmd) & pmd_pfn_mask(pmd)) >> PAGE_SHIFT;
|
||||
phys_addr_t pfn = pmd_val(pmd);
|
||||
pfn ^= protnone_mask(pfn);
|
||||
return (pfn & pmd_pfn_mask(pmd)) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned long pud_pfn(pud_t pud)
|
||||
{
|
||||
return (pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT;
|
||||
phys_addr_t pfn = pud_val(pud);
|
||||
pfn ^= protnone_mask(pfn);
|
||||
return (pfn & pud_pfn_mask(pud)) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static inline unsigned long pgd_pfn(pgd_t pgd)
|
||||
{
|
||||
return (pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
|
||||
@@ -305,11 +320,6 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd)
|
||||
return pmd_set_flags(pmd, _PAGE_RW);
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
|
||||
{
|
||||
return pmd_clear_flags(pmd, _PAGE_PRESENT | _PAGE_PROTNONE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
|
||||
static inline int pte_soft_dirty(pte_t pte)
|
||||
{
|
||||
@@ -359,19 +369,58 @@ static inline pgprotval_t massage_pgprot(pgprot_t pgprot)
|
||||
|
||||
static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
|
||||
{
|
||||
return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) |
|
||||
massage_pgprot(pgprot));
|
||||
phys_addr_t pfn = (phys_addr_t)page_nr << PAGE_SHIFT;
|
||||
pfn ^= protnone_mask(pgprot_val(pgprot));
|
||||
pfn &= PTE_PFN_MASK;
|
||||
return __pte(pfn | massage_pgprot(pgprot));
|
||||
}
|
||||
|
||||
static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
|
||||
{
|
||||
return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) |
|
||||
massage_pgprot(pgprot));
|
||||
phys_addr_t pfn = (phys_addr_t)page_nr << PAGE_SHIFT;
|
||||
pfn ^= protnone_mask(pgprot_val(pgprot));
|
||||
pfn &= PHYSICAL_PMD_PAGE_MASK;
|
||||
return __pmd(pfn | massage_pgprot(pgprot));
|
||||
}
|
||||
|
||||
static inline pud_t pfn_pud(unsigned long page_nr, pgprot_t pgprot)
|
||||
{
|
||||
phys_addr_t pfn = (phys_addr_t)page_nr << PAGE_SHIFT;
|
||||
pfn ^= protnone_mask(pgprot_val(pgprot));
|
||||
pfn &= PHYSICAL_PUD_PAGE_MASK;
|
||||
return __pud(pfn | massage_pgprot(pgprot));
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
|
||||
{
|
||||
return pfn_pmd(pmd_pfn(pmd),
|
||||
__pgprot(pmd_flags(pmd) & ~(_PAGE_PRESENT|_PAGE_PROTNONE)));
|
||||
}
|
||||
|
||||
static inline pud_t pud_set_flags(pud_t pud, pudval_t set)
|
||||
{
|
||||
pudval_t v = native_pud_val(pud);
|
||||
|
||||
return __pud(v | set);
|
||||
}
|
||||
|
||||
static inline pud_t pud_clear_flags(pud_t pud, pudval_t clear)
|
||||
{
|
||||
pudval_t v = native_pud_val(pud);
|
||||
|
||||
return __pud(v & ~clear);
|
||||
}
|
||||
|
||||
static inline pud_t pud_mkhuge(pud_t pud)
|
||||
{
|
||||
return pud_set_flags(pud, _PAGE_PSE);
|
||||
}
|
||||
|
||||
static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask);
|
||||
|
||||
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
{
|
||||
pteval_t val = pte_val(pte);
|
||||
pteval_t val = pte_val(pte), oldval = val;
|
||||
|
||||
/*
|
||||
* Chop off the NX bit (if present), and add the NX portion of
|
||||
@@ -379,17 +428,17 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
*/
|
||||
val &= _PAGE_CHG_MASK;
|
||||
val |= massage_pgprot(newprot) & ~_PAGE_CHG_MASK;
|
||||
|
||||
val = flip_protnone_guard(oldval, val, PTE_PFN_MASK);
|
||||
return __pte(val);
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
||||
{
|
||||
pmdval_t val = pmd_val(pmd);
|
||||
pmdval_t val = pmd_val(pmd), oldval = val;
|
||||
|
||||
val &= _HPAGE_CHG_MASK;
|
||||
val |= massage_pgprot(newprot) & ~_HPAGE_CHG_MASK;
|
||||
|
||||
val = flip_protnone_guard(oldval, val, PHYSICAL_PMD_PAGE_MASK);
|
||||
return __pmd(val);
|
||||
}
|
||||
|
||||
@@ -534,8 +583,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
|
||||
* Currently stuck as a macro due to indirect forward reference to
|
||||
* linux/mmzone.h's __section_mem_map_addr() definition:
|
||||
*/
|
||||
#define pmd_page(pmd) \
|
||||
pfn_to_page((pmd_val(pmd) & pmd_pfn_mask(pmd)) >> PAGE_SHIFT)
|
||||
#define pmd_page(pmd) pfn_to_page(pmd_pfn(pmd))
|
||||
|
||||
/*
|
||||
* the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
|
||||
@@ -603,8 +651,7 @@ static inline unsigned long pud_page_vaddr(pud_t pud)
|
||||
* Currently stuck as a macro due to indirect forward reference to
|
||||
* linux/mmzone.h's __section_mem_map_addr() definition:
|
||||
*/
|
||||
#define pud_page(pud) \
|
||||
pfn_to_page((pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT)
|
||||
#define pud_page(pud) pfn_to_page(pud_pfn(pud))
|
||||
|
||||
/* Find an entry in the second-level page table.. */
|
||||
static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
|
||||
@@ -644,7 +691,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd)
|
||||
* Currently stuck as a macro due to indirect forward reference to
|
||||
* linux/mmzone.h's __section_mem_map_addr() definition:
|
||||
*/
|
||||
#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
|
||||
#define pgd_page(pgd) pfn_to_page(pgd_pfn(pgd))
|
||||
|
||||
/* to find an entry in a page-table-directory. */
|
||||
static inline unsigned long pud_index(unsigned long address)
|
||||
@@ -926,6 +973,14 @@ static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define __HAVE_ARCH_PFN_MODIFY_ALLOWED 1
|
||||
extern bool pfn_modify_allowed(unsigned long pfn, pgprot_t prot);
|
||||
|
||||
static inline bool arch_has_pfn_modify_check(void)
|
||||
{
|
||||
return boot_cpu_has_bug(X86_BUG_L1TF);
|
||||
}
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
||||
@@ -163,18 +163,52 @@ static inline int pgd_large(pgd_t pgd) { return 0; }
|
||||
#define pte_offset_map(dir, address) pte_offset_kernel((dir), (address))
|
||||
#define pte_unmap(pte) ((void)(pte))/* NOP */
|
||||
|
||||
/* Encode and de-code a swap entry */
|
||||
#define SWP_TYPE_BITS 5
|
||||
#define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 1)
|
||||
/*
|
||||
* Encode and de-code a swap entry
|
||||
*
|
||||
* | ... | 11| 10| 9|8|7|6|5| 4| 3|2| 1|0| <- bit number
|
||||
* | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U| W|P| <- bit names
|
||||
* | TYPE (59-63) | ~OFFSET (9-58) |0|0|X|X| X| X|X|SD|0| <- swp entry
|
||||
*
|
||||
* G (8) is aliased and used as a PROT_NONE indicator for
|
||||
* !present ptes. We need to start storing swap entries above
|
||||
* there. We also need to avoid using A and D because of an
|
||||
* erratum where they can be incorrectly set by hardware on
|
||||
* non-present PTEs.
|
||||
*
|
||||
* SD (1) in swp entry is used to store soft dirty bit, which helps us
|
||||
* remember soft dirty over page migration
|
||||
*
|
||||
* Bit 7 in swp entry should be 0 because pmd_present checks not only P,
|
||||
* but also L and G.
|
||||
*
|
||||
* The offset is inverted by a binary not operation to make the high
|
||||
* physical bits set.
|
||||
*/
|
||||
#define SWP_TYPE_BITS 5
|
||||
|
||||
#define SWP_OFFSET_FIRST_BIT (_PAGE_BIT_PROTNONE + 1)
|
||||
|
||||
/* We always extract/encode the offset by shifting it all the way up, and then down again */
|
||||
#define SWP_OFFSET_SHIFT (SWP_OFFSET_FIRST_BIT+SWP_TYPE_BITS)
|
||||
|
||||
#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
|
||||
|
||||
#define __swp_type(x) (((x).val >> (_PAGE_BIT_PRESENT + 1)) \
|
||||
& ((1U << SWP_TYPE_BITS) - 1))
|
||||
#define __swp_offset(x) ((x).val >> SWP_OFFSET_SHIFT)
|
||||
#define __swp_entry(type, offset) ((swp_entry_t) { \
|
||||
((type) << (_PAGE_BIT_PRESENT + 1)) \
|
||||
| ((offset) << SWP_OFFSET_SHIFT) })
|
||||
/* Extract the high bits for type */
|
||||
#define __swp_type(x) ((x).val >> (64 - SWP_TYPE_BITS))
|
||||
|
||||
/* Shift up (to get rid of type), then down to get value */
|
||||
#define __swp_offset(x) (~(x).val << SWP_TYPE_BITS >> SWP_OFFSET_SHIFT)
|
||||
|
||||
/*
|
||||
* Shift the offset up "too far" by TYPE bits, then down again
|
||||
* The offset is inverted by a binary not operation to make the high
|
||||
* physical bits set.
|
||||
*/
|
||||
#define __swp_entry(type, offset) ((swp_entry_t) { \
|
||||
(~(unsigned long)(offset) << SWP_OFFSET_SHIFT >> SWP_TYPE_BITS) \
|
||||
| ((unsigned long)(type) << (64-SWP_TYPE_BITS)) })
|
||||
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val })
|
||||
|
||||
@@ -201,6 +235,8 @@ extern void cleanup_highmap(void);
|
||||
extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
|
||||
extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
|
||||
|
||||
#include <asm/pgtable-invert.h>
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_X86_PGTABLE_64_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user