LSK 16.06 v4.4-android

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJXen1sAAoJECTWi3JdVIfQs24H/R+WU/3VvkdnYUlls693TRIV
 5npbyI08tZBJ8DBqheioT2wOTqf94scXTXoloD69ZFQ7UZR/Ow05NknWN8h73SpS
 pfCIjGLubxbqKqwnzz4jJolZR3xuz+3P+6b8oEi0psRXuACrrlbOFhdP2N5d55q8
 P+bykwa9hDTKZLBu0KP0EWpba6+K7PSToqRtF37qrLDJ9s4ZHstb/AFzhxPNuSSO
 Kf88IDFdNaLMUzEuM3+khZ439hQ/ddz/IK0o4wGJ32uLxqBboN93NfrTH/MeiNRy
 H5zmiYtShcDeHs+UQ2RfxpRurQ/nIt4Xs7QOF01hzFOeGz53q2eT4y7zb4zCKxY=
 =jVYG
 -----END PGP SIGNATURE-----

Merge tag 'lsk-v4.4-16.06-android'

LSK 16.06 v4.4-android

* tag 'lsk-v4.4-16.06-android': (447 commits)
  Linux 4.4.14
  netfilter: x_tables: introduce and use xt_copy_counters_from_user
  netfilter: x_tables: do compat validation via translate_table
  netfilter: x_tables: xt_compat_match_from_user doesn't need a retval
  netfilter: ip6_tables: simplify translate_compat_table args
  netfilter: ip_tables: simplify translate_compat_table args
  netfilter: arp_tables: simplify translate_compat_table args
  netfilter: x_tables: don't reject valid target size on some architectures
  netfilter: x_tables: validate all offsets and sizes in a rule
  netfilter: x_tables: check for bogus target offset
  netfilter: x_tables: check standard target size too
  netfilter: x_tables: add compat version of xt_check_entry_offsets
  netfilter: x_tables: assert minimum target size
  netfilter: x_tables: kill check_entry helper
  netfilter: x_tables: add and use xt_check_entry_offsets
  netfilter: x_tables: validate targets of jumps
  netfilter: x_tables: don't move to non-existent next rule
  drm/core: Do not preserve framebuffer on rmfb, v4.
  crypto: qat - fix adf_ctl_drv.c:undefined reference to adf_init_pf_wq
  netfilter: x_tables: fix unconditional helper
  ...
This commit is contained in:
Huang, Tao 2016-07-05 18:36:47 +08:00
commit 234718be61
450 changed files with 16277 additions and 8082 deletions

View File

@ -6,13 +6,6 @@ Description: (RW) Add/remove a sink from a trace path. There can be multiple
source for a single sink.
ex: echo 1 > /sys/bus/coresight/devices/20010000.etb/enable_sink
What: /sys/bus/coresight/devices/<memory_map>.etb/status
Date: November 2014
KernelVersion: 3.19
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) List various control and status registers. The specific
layout and content is driver specific.
What: /sys/bus/coresight/devices/<memory_map>.etb/trigger_cntr
Date: November 2014
KernelVersion: 3.19
@ -22,3 +15,65 @@ Description: (RW) Disables write access to the Trace RAM by stopping the
following the trigger event. The number of 32-bit words written
into the Trace RAM following the trigger event is equal to the
value stored in this register+1 (from ARM ETB-TRM).
What: /sys/bus/coresight/devices/<memory_map>.etb/mgmt/rdp
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Defines the depth, in words, of the trace RAM in powers of
2. The value is read directly from HW register RDP, 0x004.
What: /sys/bus/coresight/devices/<memory_map>.etb/mgmt/sts
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the ETB status register. The value
is read directly from HW register STS, 0x00C.
What: /sys/bus/coresight/devices/<memory_map>.etb/mgmt/rrp
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the ETB RAM Read Pointer register
that is used to read entries from the Trace RAM over the APB
interface. The value is read directly from HW register RRP,
0x014.
What: /sys/bus/coresight/devices/<memory_map>.etb/mgmt/rwp
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the ETB RAM Write Pointer register
that is used to sets the write pointer to write entries from
the CoreSight bus into the Trace RAM. The value is read directly
from HW register RWP, 0x018.
What: /sys/bus/coresight/devices/<memory_map>.etb/mgmt/trg
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Similar to "trigger_cntr" above except that this value is
read directly from HW register TRG, 0x01C.
What: /sys/bus/coresight/devices/<memory_map>.etb/mgmt/ctl
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the ETB Control register. The value
is read directly from HW register CTL, 0x020.
What: /sys/bus/coresight/devices/<memory_map>.etb/mgmt/ffsr
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the ETB Formatter and Flush Status
register. The value is read directly from HW register FFSR,
0x300.
What: /sys/bus/coresight/devices/<memory_map>.etb/mgmt/ffcr
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the ETB Formatter and Flush Control
register. The value is read directly from HW register FFCR,
0x304.

View File

@ -359,6 +359,19 @@ Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the Peripheral ID3 Register
(0xFEC). The value is taken directly from the HW.
What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcconfig
Date: February 2016
KernelVersion: 4.07
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the trace configuration register
(0x010) as currently set by SW.
What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trctraceid
Date: February 2016
KernelVersion: 4.07
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Print the content of the trace ID register (0x040).
What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr0
Date: April 2015
KernelVersion: 4.01

View File

@ -0,0 +1,53 @@
What: /sys/bus/coresight/devices/<memory_map>.stm/enable_source
Date: April 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Enable/disable tracing on this specific trace macrocell.
Enabling the trace macrocell implies it has been configured
properly and a sink has been identified for it. The path
of coresight components linking the source to the sink is
configured and managed automatically by the coresight framework.
What: /sys/bus/coresight/devices/<memory_map>.stm/hwevent_enable
Date: April 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Provides access to the HW event enable register, used in
conjunction with HW event bank select register.
What: /sys/bus/coresight/devices/<memory_map>.stm/hwevent_select
Date: April 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Gives access to the HW event block select register
(STMHEBSR) in order to configure up to 256 channels. Used in
conjunction with "hwevent_enable" register as described above.
What: /sys/bus/coresight/devices/<memory_map>.stm/port_enable
Date: April 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Provides access to the stimulus port enable register
(STMSPER). Used in conjunction with "port_select" described
below.
What: /sys/bus/coresight/devices/<memory_map>.stm/port_select
Date: April 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Used to determine which bank of stimulus port bit in
register STMSPER (see above) apply to.
What: /sys/bus/coresight/devices/<memory_map>.stm/status
Date: April 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) List various control and status registers. The specific
layout and content is driver specific.
What: /sys/bus/coresight/devices/<memory_map>.stm/traceid
Date: April 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Holds the trace ID that will appear in the trace stream
coming from this trace entity.

View File

@ -6,3 +6,80 @@ Description: (RW) Disables write access to the Trace RAM by stopping the
formatter after a defined number of words have been stored
following the trigger event. Additional interface for this
driver are expected to be added as it matures.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/rsz
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Defines the size, in 32-bit words, of the local RAM buffer.
The value is read directly from HW register RSZ, 0x004.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/sts
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the TMC status register. The value
is read directly from HW register STS, 0x00C.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/rrp
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the TMC RAM Read Pointer register
that is used to read entries from the Trace RAM over the APB
interface. The value is read directly from HW register RRP,
0x014.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/rwp
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the TMC RAM Write Pointer register
that is used to sets the write pointer to write entries from
the CoreSight bus into the Trace RAM. The value is read directly
from HW register RWP, 0x018.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/trg
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Similar to "trigger_cntr" above except that this value is
read directly from HW register TRG, 0x01C.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/ctl
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the TMC Control register. The value
is read directly from HW register CTL, 0x020.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/ffsr
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the TMC Formatter and Flush Status
register. The value is read directly from HW register FFSR,
0x300.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/ffcr
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the TMC Formatter and Flush Control
register. The value is read directly from HW register FFCR,
0x304.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/mode
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Shows the value held by the TMC Mode register, which
indicate the mode the device has been configured to enact. The
The value is read directly from the MODE register, 0x028.
What: /sys/bus/coresight/devices/<memory_map>.tmc/mgmt/devid
Date: March 2016
KernelVersion: 4.7
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the capabilities of the Coresight TMC.
The value is read directly from the DEVID register, 0xFC8,

View File

@ -12,3 +12,13 @@ KernelVersion: 4.3
Contact: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Description:
Shows the number of channels per master on this STM device.
What: /sys/class/stm/<stm>/hw_override
Date: March 2016
KernelVersion: 4.7
Contact: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Description:
Reads as 0 if master numbers in the STP stream produced by
this stm device will match the master numbers assigned by
the software or 1 if the stm hardware overrides software
assigned masters.

View File

@ -94,6 +94,7 @@ clocks and IDs.
csi_sel 79
iim_gate 80
gpu2d_gate 81
ckli_gate 82
Examples:

View File

@ -213,9 +213,6 @@ TTY_IO_ERROR If set, causes all subsequent userspace read/write
TTY_OTHER_CLOSED Device is a pty and the other side has closed.
TTY_OTHER_DONE Device is a pty and the other side has closed and
all pending input processing has been completed.
TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into
smaller chunks.

View File

@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/fs:
- nr_open
- overflowuid
- overflowgid
- pipe-user-pages-hard
- pipe-user-pages-soft
- protected_hardlinks
- protected_symlinks
- suid_dumpable
@ -159,6 +161,27 @@ The default is 65534.
==============================================================
pipe-user-pages-hard:
Maximum total number of pages a non-privileged user may allocate for pipes.
Once this limit is reached, no new pipes may be allocated until usage goes
below the limit again. When set to 0, no limit is applied, which is the default
setting.
==============================================================
pipe-user-pages-soft:
Maximum total number of pages a non-privileged user may allocate for pipes
before the pipe size gets limited to a single page. Once this limit is reached,
new pipes will be limited to a single page in size for this user in order to
limit total memory usage, and trying to increase them using fcntl() will be
denied until usage goes below the limit again. The default value allows to
allocate up to 1024 pipes at their default size. When set to 0, no limit is
applied.
==============================================================
protected_hardlinks:
A long-standing class of security issues is the hardlink-based

View File

@ -58,6 +58,8 @@ show up in /proc/sys/kernel:
- panic_on_stackoverflow
- panic_on_unrecovered_nmi
- panic_on_warn
- perf_cpu_time_max_percent
- perf_event_paranoid
- pid_max
- powersave-nap [ PPC only ]
- printk
@ -624,6 +626,19 @@ allowed to execute.
==============================================================
perf_event_paranoid:
Controls use of the performance events system by unprivileged
users (without CAP_SYS_ADMIN). The default value is 3 if
CONFIG_SECURITY_PERF_EVENTS_RESTRICT is set, or 1 otherwise.
-1: Allow use of (almost) all events by all users
>=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK
>=1: Disallow CPU event access by users without CAP_SYS_ADMIN
>=2: Disallow kernel profiling by users without CAP_SYS_ADMIN
>=3: Disallow all event access by users without CAP_SYS_ADMIN
==============================================================
pid_max:

View File

@ -190,8 +190,8 @@ expected to be accessed and controlled using those entries.
Last but not least, "struct module *owner" is expected to be set to reflect
the information carried in "THIS_MODULE".
How to use
----------
How to use the tracer modules
-----------------------------
Before trace collection can start, a coresight sink needs to be identify.
There is no limit on the amount of sinks (nor sources) that can be enabled at
@ -297,3 +297,36 @@ Info Tracing enabled
Instruction 13570831 0x8026B584 E28DD00C false ADD sp,sp,#0xc
Instruction 0 0x8026B588 E8BD8000 true LDM sp!,{pc}
Timestamp Timestamp: 17107041535
How to use the STM module
-------------------------
Using the System Trace Macrocell module is the same as the tracers - the only
difference is that clients are driving the trace capture rather
than the program flow through the code.
As with any other CoreSight component, specifics about the STM tracer can be
found in sysfs with more information on each entry being found in [1]:
root@genericarmv8:~# ls /sys/bus/coresight/devices/20100000.stm
enable_source hwevent_select port_enable subsystem uevent
hwevent_enable mgmt port_select traceid
root@genericarmv8:~#
Like any other source a sink needs to be identified and the STM enabled before
being used:
root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20010000.etf/enable_sink
root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20100000.stm/enable_source
From there user space applications can request and use channels using the devfs
interface provided for that purpose by the generic STM API:
root@genericarmv8:~# ls -l /dev/20100000.stm
crw------- 1 root root 10, 61 Jan 3 18:11 /dev/20100000.stm
root@genericarmv8:~#
Details on how to use the generic STM API can be found here [2].
[1]. Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
[2]. Documentation/trace/stm.txt

View File

@ -1007,6 +1007,10 @@ F: drivers/hwtracing/coresight/*
F: Documentation/trace/coresight.txt
F: Documentation/devicetree/bindings/arm/coresight.txt
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-*
F: tools/perf/arch/arm/util/pmu.c
F: tools/perf/arch/arm/util/auxtrace.c
F: tools/perf/arch/arm/util/cs_etm.c
F: tools/perf/arch/arm/util/cs_etm.h
ARM/CORGI MACHINE SUPPORT
M: Richard Purdie <rpurdie@rpsys.net>
@ -9356,6 +9360,7 @@ F: drivers/mmc/host/dw_mmc*
SYSTEM TRACE MODULE CLASS
M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ash/stm.git
F: Documentation/trace/stm.txt
F: drivers/hwtracing/stm/
F: include/linux/stm.h

View File

@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 4
SUBLEVEL = 11
SUBLEVEL = 14
EXTRAVERSION =
NAME = Blurry Fish Butt
@ -376,7 +376,7 @@ AFLAGS_MODULE =
LDFLAGS_MODULE =
CFLAGS_KERNEL =
AFLAGS_KERNEL =
CFLAGS_GCOV = -fprofile-arcs -ftest-coverage
CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im
# Use USERINCLUDE when you must reference the UAPI directories only.
@ -694,9 +694,10 @@ KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
else
# This warning generated too much noise in a regular build.
# Use make W=1 to enable this warning (see scripts/Makefile.build)
# These warnings generated too much noise in a regular build.
# Use make W=1 to enable them (see scripts/Makefile.build)
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
endif
ifdef CONFIG_FRAME_POINTER

View File

@ -57,6 +57,7 @@ CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_SECURITY=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
@ -138,15 +139,16 @@ CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_MPPE=y
CONFIG_PREEMPT=y
CONFIG_QUOTA=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_RTC_CLASS=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SETEND_EMULATION=y
CONFIG_STAGING=y
CONFIG_SWITCH=y
CONFIG_SWP_EMULATION=y
CONFIG_SYNC=y
CONFIG_TUN=y

View File

@ -119,7 +119,6 @@ CONFIG_TIMER_STATS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_UHID=y
CONFIG_UID_STAT=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_HIDDEV=y

View File

@ -245,7 +245,7 @@ button@1 {
button@2 {
label = "Factory Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
};
};
@ -260,7 +260,7 @@ power {
};
sata {
gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
default-state = "off";
};
};
@ -313,7 +313,7 @@ port@5 {
&pinctrl {
keys_pin: keys-pin {
marvell,pins = "mpp24", "mpp47";
marvell,pins = "mpp24", "mpp29";
marvell,function = "gpio";
};

View File

@ -304,13 +304,13 @@ gpio_keys {
button@1 {
label = "WPS";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
};
button@2 {
label = "Factory Reset Button";
linux,code = <KEY_RESTART>;
gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
};
};

View File

@ -298,6 +298,8 @@ max8997_pmic@66 {
compatible = "maxim,max8997-pmic";
reg = <0x66>;
interrupt-parent = <&gpx0>;
interrupts = <7 0>;
max8997,pmic-buck1-uses-gpio-dvs;
max8997,pmic-buck2-uses-gpio-dvs;

View File

@ -837,8 +837,8 @@
#define PIN_PD23__ISC_FIELD PINMUX_PIN(PIN_PD23, 6, 4)
#define PIN_PD24 120
#define PIN_PD24__GPIO PINMUX_PIN(PIN_PD24, 0, 0)
#define PIN_PD24__UTXD2 PINMUX_PIN(PIN_PD23, 1, 2)
#define PIN_PD24__FLEXCOM4_IO3 PINMUX_PIN(PIN_PD23, 3, 3)
#define PIN_PD24__UTXD2 PINMUX_PIN(PIN_PD24, 1, 2)
#define PIN_PD24__FLEXCOM4_IO3 PINMUX_PIN(PIN_PD24, 3, 3)
#define PIN_PD25 121
#define PIN_PD25__GPIO PINMUX_PIN(PIN_PD25, 0, 0)
#define PIN_PD25__SPI1_SPCK PINMUX_PIN(PIN_PD25, 1, 3)

View File

@ -1,28 +0,0 @@
/*
* arch/arm/include/asm/mach/mmc.h
*/
#ifndef ASMARM_MACH_MMC_H
#define ASMARM_MACH_MMC_H
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
struct embedded_sdio_data {
struct sdio_cis cis;
struct sdio_cccr cccr;
struct sdio_embedded_func *funcs;
int num_funcs;
};
struct mmc_platform_data {
unsigned int ocr_mask; /* available voltages */
int built_in; /* built-in device flag */
int card_present; /* card detect state */
u32 (*translate_vdd)(struct device *, unsigned int);
unsigned int (*status)(struct device *);
struct embedded_sdio_data *embedded_sdio;
int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
};
#endif

View File

@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *target,
if (ret)
return ret;
vfp_flush_hwstate(thread);
thread->vfpstate.hard = new_vfp;
vfp_flush_hwstate(thread);
return 0;
}

View File

@ -886,11 +886,14 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
old_pmd = *pmd;
kvm_set_pmd(pmd, *new_pmd);
if (pmd_present(old_pmd))
if (pmd_present(old_pmd)) {
pmd_clear(pmd);
kvm_tlb_flush_vmid_ipa(kvm, addr);
else
} else {
get_page(virt_to_page(pmd));
}
kvm_set_pmd(pmd, *new_pmd);
return 0;
}
@ -939,12 +942,14 @@ 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;
kvm_set_pte(pte, *new_pte);
if (pte_present(old_pte))
if (pte_present(old_pte)) {
kvm_set_pte(pte, __pte(0));
kvm_tlb_flush_vmid_ipa(kvm, addr);
else
} else {
get_page(virt_to_page(pte));
}
kvm_set_pte(pte, *new_pte);
return 0;
}

View File

@ -116,7 +116,7 @@ dtbs: prepare scripts
dtbs_install:
$(Q)$(MAKE) $(dtbinst)=$(boot)/dts
Image.gz-dtb: vmlinux scripts dtbs
Image-dtb Image.gz-dtb: vmlinux scripts dtbs
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
PHONY += vdso_install

View File

@ -1,3 +1,4 @@
Image
Image-dtb
Image.gz
Image.gz-dtb

View File

@ -32,6 +32,9 @@ $(obj)/Image: vmlinux FORCE
$(obj)/Image.bz2: $(obj)/Image FORCE
$(call if_changed,bzip2)
$(obj)/Image-dtb: $(obj)/Image $(DTB_OBJS) FORCE
$(call if_changed,cat)
$(obj)/Image.gz: $(obj)/Image FORCE
$(call if_changed,gzip)

View File

@ -143,5 +143,310 @@ pmu_a53 {
<&A53_3>;
};
etr@20070000 {
compatible = "arm,coresight-tmc", "arm,primecell";
reg = <0 0x20070000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
port {
etr_in_port: endpoint {
slave-mode;
remote-endpoint = <&replicator_out_port1>;
};
};
};
tpiu@20030000 {
compatible = "arm,coresight-tpiu", "arm,primecell";
reg = <0 0x20030000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
port {
tpiu_in_port: endpoint {
slave-mode;
remote-endpoint = <&replicator_out_port0>;
};
};
};
replicator@20020000 {
/* non-configurable replicators don't show up on the
* AMBA bus. As such no need to add "arm,primecell".
*/
compatible = "arm,coresight-replicator";
ports {
#address-cells = <1>;
#size-cells = <0>;
/* replicator output ports */
port@0 {
reg = <0>;
replicator_out_port0: endpoint {
remote-endpoint = <&tpiu_in_port>;
};
};
port@1 {
reg = <1>;
replicator_out_port1: endpoint {
remote-endpoint = <&etr_in_port>;
};
};
/* replicator input port */
port@2 {
reg = <0>;
replicator_in_port0: endpoint {
slave-mode;
remote-endpoint = <&etf_out_port>;
};
};
};
};
etf@20010000 {
compatible = "arm,coresight-tmc", "arm,primecell";
reg = <0 0x20010000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
ports {
#address-cells = <1>;
#size-cells = <0>;
/* input port */
port@0 {
reg = <0>;
etf_in_port: endpoint {
slave-mode;
remote-endpoint =
<&main_funnel_out_port>;
};
};
/* output port */
port@1 {
reg = <0>;
etf_out_port: endpoint {
remote-endpoint =
<&replicator_in_port0>;
};
};
};
};
main_funnel@20040000 {
compatible = "arm,coresight-funnel", "arm,primecell";
reg = <0 0x20040000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
main_funnel_out_port: endpoint {
remote-endpoint =
<&etf_in_port>;
};
};
port@1 {
reg = <0>;
main_funnel_in_port0: endpoint {
slave-mode;
remote-endpoint =
<&A72_57_funnel_out_port>;
};
};
port@2 {
reg = <1>;
main_funnel_in_port1: endpoint {
slave-mode;
remote-endpoint = <&A53_funnel_out_port>;
};
};
};
};
A72_57_funnel@220c0000 {
compatible = "arm,coresight-funnel", "arm,primecell";
reg = <0 0x220c0000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
A72_57_funnel_out_port: endpoint {
remote-endpoint =
<&main_funnel_in_port0>;
};
};
port@1 {
reg = <0>;
A72_57_funnel_in_port0: endpoint {
slave-mode;
remote-endpoint =
<&A72_57_etm0_out_port>;
};
};
port@2 {
reg = <1>;
A72_57_funnel_in_port1: endpoint {
slave-mode;
remote-endpoint =
<&A72_57_etm1_out_port>;
};
};
};
};
A53_funnel@220c0000 {
compatible = "arm,coresight-funnel", "arm,primecell";
reg = <0 0x230c0000 0 0x1000>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
A53_funnel_out_port: endpoint {
remote-endpoint =
<&main_funnel_in_port1>;
};
};
port@1 {
reg = <0>;
A53_funnel_in_port0: endpoint {
slave-mode;
remote-endpoint = <&A53_etm0_out_port>;
};
};
port@2 {
reg = <1>;
A53_funnel_in_port1: endpoint {
slave-mode;
remote-endpoint = <&A53_etm1_out_port>;
};
};
port@3 {
reg = <2>;
A53_funnel_in_port2: endpoint {
slave-mode;
remote-endpoint = <&A53_etm2_out_port>;
};
};
port@4 {
reg = <3>;
A53_funnel_in_port3: endpoint {
slave-mode;
remote-endpoint = <&A53_etm3_out_port>;
};
};
};
};
etm@22040000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x22040000 0 0x1000>;
cpu = <&A57_0>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
port {
A72_57_etm0_out_port: endpoint {
remote-endpoint = <&A72_57_funnel_in_port0>;
};
};
};
etm@22140000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x22140000 0 0x1000>;
cpu = <&A57_1>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
port {
A72_57_etm1_out_port: endpoint {
remote-endpoint = <&A72_57_funnel_in_port1>;
};
};
};
etm@23040000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x23040000 0 0x1000>;
cpu = <&A53_0>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
port {
A53_etm0_out_port: endpoint {
remote-endpoint = <&A53_funnel_in_port0>;
};
};
};
etm@23140000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x23140000 0 0x1000>;
cpu = <&A53_1>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
port {
A53_etm1_out_port: endpoint {
remote-endpoint = <&A53_funnel_in_port1>;
};
};
};
etm@23240000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x23240000 0 0x1000>;
cpu = <&A53_2>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
port {
A53_etm2_out_port: endpoint {
remote-endpoint = <&A53_funnel_in_port2>;
};
};
};
etm@23340000 {
compatible = "arm,coresight-etm4x", "arm,primecell";
reg = <0 0x23340000 0 0x1000>;
cpu = <&A53_3>;
clocks = <&soc_smc50mhz>;
clock-names = "apb_pclk";
port {
A53_etm3_out_port: endpoint {
remote-endpoint = <&A53_funnel_in_port3>;
};
};
};
#include "juno-base.dtsi"
};

View File

@ -160,14 +160,14 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
#endif
#ifdef CONFIG_COMPAT
#ifdef __AARCH64EB__
#define COMPAT_ELF_PLATFORM ("v8b")
#else
#define COMPAT_ELF_PLATFORM ("v8l")
#endif
#ifdef CONFIG_COMPAT
#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)
/* AArch32 registers. */

View File

@ -133,7 +133,6 @@
* Section
*/
#define PMD_SECT_VALID (_AT(pmdval_t, 1) << 0)
#define PMD_SECT_PROT_NONE (_AT(pmdval_t, 1) << 58)
#define PMD_SECT_USER (_AT(pmdval_t, 1) << 6) /* AP[1] */
#define PMD_SECT_RDONLY (_AT(pmdval_t, 1) << 7) /* AP[2] */
#define PMD_SECT_S (_AT(pmdval_t, 3) << 8)

View File

@ -348,6 +348,7 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
#define pmd_present(pmd) pte_present(pmd_pte(pmd))
#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
#define pmd_young(pmd) pte_young(pmd_pte(pmd))
#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
@ -357,7 +358,7 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
#define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd)))
#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) & ~PMD_TYPE_MASK))
#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) & ~PMD_SECT_VALID))
#define __HAVE_ARCH_PMD_WRITE
#define pmd_write(pmd) pte_write(pmd_pte(pmd))
@ -396,7 +397,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_present(pmd) (pmd_val(pmd))
#define pmd_bad(pmd) (!(pmd_val(pmd) & 2))
@ -595,6 +595,21 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
}
#ifdef CONFIG_ARM64_HW_AFDBM
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
extern int ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep,
pte_t entry, int dirty);
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp,
pmd_t entry, int dirty)
{
return ptep_set_access_flags(vma, address, (pte_t *)pmdp, pmd_pte(entry), dirty);
}
#endif
/*
* Atomic pte/pmd modifications.
*/
@ -647,9 +662,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
unsigned long address, pmd_t *pmdp)
#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
unsigned long address, pmd_t *pmdp)
{
return pte_pmd(ptep_get_and_clear(mm, address, (pte_t *)pmdp));
}

View File

@ -22,6 +22,8 @@
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/compat.h>
#include <linux/elf.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/personality.h>
@ -85,7 +87,8 @@ static const char *const compat_hwcap_str[] = {
"idivt",
"vfpd32",
"lpae",
"evtstrm"
"evtstrm",
NULL
};
static const char *const compat_hwcap2_str[] = {
@ -101,6 +104,7 @@ static const char *const compat_hwcap2_str[] = {
static int c_show(struct seq_file *m, void *v)
{
int i, j;
bool compat = personality(current->personality) == PER_LINUX32;
for_each_online_cpu(i) {
struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
@ -112,6 +116,9 @@ static int c_show(struct seq_file *m, void *v)
* "processor". Give glibc what it expects.
*/
seq_printf(m, "processor\t: %d\n", i);
if (compat)
seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
loops_per_jiffy / (500000UL/HZ),
@ -124,7 +131,7 @@ static int c_show(struct seq_file *m, void *v)
* software which does already (at least for 32-bit).
*/
seq_puts(m, "Features\t:");
if (personality(current->personality) == PER_LINUX32) {
if (compat) {
#ifdef CONFIG_COMPAT
for (j = 0; compat_hwcap_str[j]; j++)
if (compat_elf_hwcap & (1 << j))

View File

@ -130,7 +130,7 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
if (!is_iabt)
esr |= ESR_ELx_EC_DABT_LOW;
esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
vcpu_sys_reg(vcpu, ESR_EL1) = esr | ESR_ELx_FSC_EXTABT;
}

View File

@ -81,6 +81,56 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
printk("\n");
}
#ifdef CONFIG_ARM64_HW_AFDBM
/*
* This function sets the access flags (dirty, accessed), as well as write
* permission, and only to a more permissive setting.
*
* It needs to cope with hardware update of the accessed/dirty state by other
* agents in the system and can safely skip the __sync_icache_dcache() call as,
* like set_pte_at(), the PTE is never changed from no-exec to exec here.
*
* Returns whether or not the PTE actually changed.
*/
int ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep,
pte_t entry, int dirty)
{
pteval_t old_pteval;
unsigned int tmp;
if (pte_same(*ptep, entry))
return 0;
/* only preserve the access flags and write permission */
pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY;
/*
* PTE_RDONLY is cleared by default in the asm below, so set it in
* back if necessary (read-only or clean PTE).
*/
if (!pte_write(entry) || !pte_sw_dirty(entry))
pte_val(entry) |= PTE_RDONLY;
/*
* Setting the flags must be done atomically to avoid racing with the
* hardware update of the access/dirty state.
*/
asm volatile("// ptep_set_access_flags\n"
" prfm pstl1strm, %2\n"
"1: ldxr %0, %2\n"
" and %0, %0, %3 // clear PTE_RDONLY\n"
" orr %0, %0, %4 // set flags\n"
" stxr %w1, %0, %2\n"
" cbnz %w1, 1b\n"
: "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep))
: "L" (~PTE_RDONLY), "r" (pte_val(entry)));
flush_tlb_fix_spurious_fault(vma, address);
return 1;
}
#endif
/*
* The kernel tried to access some page that wasn't present.
*/

View File

@ -31,13 +31,15 @@ static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
} while (1);
}
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
static void prom_putchar_ar71xx(unsigned char ch)
{
void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
__raw_writel(ch, base + UART_TX * 4);
prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
}
static void prom_putchar_ar933x(unsigned char ch)

View File

@ -298,21 +298,21 @@
.set pop
.endm
.macro copy_u_w ws, n
.macro copy_s_w ws, n
.set push
.set mips32r2
.set fp=64
.set msa
copy_u.w $1, $w\ws[\n]
copy_s.w $1, $w\ws[\n]
.set pop
.endm
.macro copy_u_d ws, n
.macro copy_s_d ws, n
.set push
.set mips64r2
.set fp=64
.set msa
copy_u.d $1, $w\ws[\n]
copy_s.d $1, $w\ws[\n]
.set pop
.endm
@ -346,8 +346,8 @@
#define STH_MSA_INSN 0x5800081f
#define STW_MSA_INSN 0x5800082f
#define STD_MSA_INSN 0x5800083f
#define COPY_UW_MSA_INSN 0x58f00056
#define COPY_UD_MSA_INSN 0x58f80056
#define COPY_SW_MSA_INSN 0x58b00056
#define COPY_SD_MSA_INSN 0x58b80056
#define INSERT_W_MSA_INSN 0x59300816
#define INSERT_D_MSA_INSN 0x59380816
#else
@ -361,8 +361,8 @@
#define STH_MSA_INSN 0x78000825
#define STW_MSA_INSN 0x78000826
#define STD_MSA_INSN 0x78000827
#define COPY_UW_MSA_INSN 0x78f00059
#define COPY_UD_MSA_INSN 0x78f80059
#define COPY_SW_MSA_INSN 0x78b00059
#define COPY_SD_MSA_INSN 0x78b80059
#define INSERT_W_MSA_INSN 0x79300819
#define INSERT_D_MSA_INSN 0x79380819
#endif
@ -393,7 +393,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word LDB_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -402,7 +402,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word LDH_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -411,7 +411,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word LDW_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -420,7 +420,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word LDD_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -429,7 +429,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word STB_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -438,7 +438,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word STH_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -447,7 +447,7 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word STW_MSA_INSN | (\wd << 6)
.set pop
.endm
@ -456,26 +456,26 @@
.set push
.set noat
SET_HARDFLOAT
addu $1, \base, \off
PTR_ADDU $1, \base, \off
.word STD_MSA_INSN | (\wd << 6)
.set pop
.endm
.macro copy_u_w ws, n
.macro copy_s_w ws, n
.set push
.set noat
SET_HARDFLOAT
.insn
.word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
.word COPY_SW_MSA_INSN | (\n << 16) | (\ws << 11)
.set pop
.endm
.macro copy_u_d ws, n
.macro copy_s_d ws, n
.set push
.set noat
SET_HARDFLOAT
.insn
.word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
.word COPY_SD_MSA_INSN | (\n << 16) | (\ws << 11)
.set pop
.endm

View File

@ -51,7 +51,6 @@ extern void (*flush_cache_range)(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
extern void __flush_dcache_page(struct page *page);
extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page);
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
static inline void flush_dcache_page(struct page *page)
@ -77,11 +76,6 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
static inline void flush_icache_page(struct vm_area_struct *vma,
struct page *page)
{
if (!cpu_has_ic_fills_f_dc && (vma->vm_flags & VM_EXEC) &&
Page_dcache_dirty(page)) {
__flush_icache_page(vma, page);
ClearPageDcacheDirty(page);
}
}
extern void (*flush_icache_range)(unsigned long start, unsigned long end);

View File

@ -784,7 +784,7 @@ extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
uint32_t kvm_mips_read_count(struct kvm_vcpu *vcpu);
void kvm_mips_write_count(struct kvm_vcpu *vcpu, uint32_t count);
void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare);
void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack);
void kvm_mips_init_count(struct kvm_vcpu *vcpu);
int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl);
int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume);

View File

@ -147,6 +147,19 @@ static inline void restore_msa(struct task_struct *t)
_restore_msa(t);
}
static inline void init_msa_upper(void)
{
/*
* Check cpu_has_msa only if it's a constant. This will allow the
* compiler to optimise out code for CPUs without MSA without adding
* an extra redundant check for CPUs with MSA.
*/
if (__builtin_constant_p(cpu_has_msa) && !cpu_has_msa)
return;
_init_msa_upper();
}
#ifdef TOOLCHAIN_SUPPORTS_MSA
#define __BUILD_MSA_CTL_REG(name, cs) \

View File

@ -127,10 +127,14 @@ do { \
} \
} while(0)
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval);
#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
#define pte_none(pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL))
#define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT)
#define pte_no_exec(pte) ((pte).pte_low & _PAGE_NO_EXEC)
static inline void set_pte(pte_t *ptep, pte_t pte)
{
@ -148,7 +152,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
buddy->pte_high |= _PAGE_GLOBAL;
}
}
#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
@ -166,6 +169,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
#define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL))
#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
#define pte_no_exec(pte) (pte_val(pte) & _PAGE_NO_EXEC)
/*
* Certain architectures need to do special things when pte's
@ -218,7 +222,6 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
}
#endif
}
#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
@ -234,6 +237,22 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
}
#endif
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
extern void __update_cache(unsigned long address, pte_t pte);
if (!pte_present(pteval))
goto cache_sync_done;
if (pte_present(*ptep) && (pte_pfn(*ptep) == pte_pfn(pteval)))
goto cache_sync_done;
__update_cache(addr, pteval);
cache_sync_done:
set_pte(ptep, pteval);
}
/*
* (pmds are folded into puds so this doesn't get actually called,
* but the define is needed for a generic inline function.)
@ -430,15 +449,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
pte_t pte);
extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
pte_t pte);
static inline void update_mmu_cache(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep)
{
pte_t pte = *ptep;
__update_tlb(vma, address, pte);
__update_cache(vma, address, pte);
}
static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,

View File

@ -45,7 +45,7 @@ extern unsigned int vced_count, vcei_count;
* User space process size: 2GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing.
*/
#define TASK_SIZE 0x7fff8000UL
#define TASK_SIZE 0x80000000UL
#endif
#define STACK_TOP_MAX TASK_SIZE

View File

@ -105,7 +105,7 @@ do { \
__clear_software_ll_bit(); \
if (cpu_has_userlocal) \
write_c0_userlocal(task_thread_info(next)->tp_value); \
__restore_watch(); \
__restore_watch(next); \
(last) = resume(prev, next, task_thread_info(next)); \
} while (0)

View File

@ -12,21 +12,21 @@
#include <asm/mipsregs.h>
void mips_install_watch_registers(void);
void mips_install_watch_registers(struct task_struct *t);
void mips_read_watch_registers(void);
void mips_clear_watch_registers(void);
void mips_probe_watch_registers(struct cpuinfo_mips *c);
#ifdef CONFIG_HARDWARE_WATCHPOINTS
#define __restore_watch() do { \
#define __restore_watch(task) do { \
if (unlikely(test_bit(TIF_LOAD_WATCH, \
&current_thread_info()->flags))) { \
mips_install_watch_registers(); \
&task_thread_info(task)->flags))) { \
mips_install_watch_registers(task); \
} \
} while (0)
#else
#define __restore_watch() do {} while (0)
#define __restore_watch(task) do {} while (0)
#endif
#endif /* _ASM_WATCH_H */

View File

@ -28,7 +28,7 @@
#define __ARCH_SIGSYS
#include <uapi/asm-generic/siginfo.h>
#include <asm-generic/siginfo.h>
/* We can't use generic siginfo_t, because our si_code and si_errno are swapped */
typedef struct siginfo {
@ -42,13 +42,13 @@ typedef struct siginfo {
/* kill() */
struct {
pid_t _pid; /* sender's pid */
__kernel_pid_t _pid; /* sender's pid */
__ARCH_SI_UID_T _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
struct {
timer_t _tid; /* timer id */
__kernel_timer_t _tid; /* timer id */
int _overrun; /* overrun count */
char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
sigval_t _sigval; /* same as below */
@ -57,26 +57,26 @@ typedef struct siginfo {
/* POSIX.1b signals */
struct {
pid_t _pid; /* sender's pid */
__kernel_pid_t _pid; /* sender's pid */
__ARCH_SI_UID_T _uid; /* sender's uid */
sigval_t _sigval;
} _rt;
/* SIGCHLD */
struct {
pid_t _pid; /* which child */
__kernel_pid_t _pid; /* which child */
__ARCH_SI_UID_T _uid; /* sender's uid */
int _status; /* exit code */
clock_t _utime;
clock_t _stime;
__kernel_clock_t _utime;
__kernel_clock_t _stime;
} _sigchld;
/* IRIX SIGCHLD */
struct {
pid_t _pid; /* which child */
clock_t _utime;
__kernel_pid_t _pid; /* which child */
__kernel_clock_t _utime;
int _status; /* exit code */
clock_t _stime;
__kernel_clock_t _stime;
} _irix_sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
@ -118,6 +118,4 @@ typedef struct siginfo {
#define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */
#define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */
#include <asm-generic/siginfo.h>
#endif /* _UAPI_ASM_SIGINFO_H */

View File

@ -28,6 +28,7 @@
#include <asm/inst.h>
#include <asm/mips-r2-to-r6-emul.h>
#include <asm/local.h>
#include <asm/mipsregs.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
@ -1251,10 +1252,10 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
" j 10b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .word 1b,8b\n"
" .word 2b,8b\n"
" .word 3b,8b\n"
" .word 4b,8b\n"
STR(PTR) " 1b,8b\n"
STR(PTR) " 2b,8b\n"
STR(PTR) " 3b,8b\n"
STR(PTR) " 4b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@ -1326,10 +1327,10 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
" j 10b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .word 1b,8b\n"
" .word 2b,8b\n"
" .word 3b,8b\n"
" .word 4b,8b\n"
STR(PTR) " 1b,8b\n"
STR(PTR) " 2b,8b\n"
STR(PTR) " 3b,8b\n"
STR(PTR) " 4b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@ -1397,10 +1398,10 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .word 1b,8b\n"
" .word 2b,8b\n"
" .word 3b,8b\n"
" .word 4b,8b\n"
STR(PTR) " 1b,8b\n"
STR(PTR) " 2b,8b\n"
STR(PTR) " 3b,8b\n"
STR(PTR) " 4b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@ -1467,10 +1468,10 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .word 1b,8b\n"
" .word 2b,8b\n"
" .word 3b,8b\n"
" .word 4b,8b\n"
STR(PTR) " 1b,8b\n"
STR(PTR) " 2b,8b\n"
STR(PTR) " 3b,8b\n"
STR(PTR) " 4b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@ -1582,14 +1583,14 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .word 1b,8b\n"
" .word 2b,8b\n"
" .word 3b,8b\n"
" .word 4b,8b\n"
" .word 5b,8b\n"
" .word 6b,8b\n"
" .word 7b,8b\n"
" .word 0b,8b\n"
STR(PTR) " 1b,8b\n"
STR(PTR) " 2b,8b\n"
STR(PTR) " 3b,8b\n"
STR(PTR) " 4b,8b\n"
STR(PTR) " 5b,8b\n"
STR(PTR) " 6b,8b\n"
STR(PTR) " 7b,8b\n"
STR(PTR) " 0b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@ -1701,14 +1702,14 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .word 1b,8b\n"
" .word 2b,8b\n"
" .word 3b,8b\n"
" .word 4b,8b\n"
" .word 5b,8b\n"
" .word 6b,8b\n"
" .word 7b,8b\n"
" .word 0b,8b\n"
STR(PTR) " 1b,8b\n"
STR(PTR) " 2b,8b\n"
STR(PTR) " 3b,8b\n"
STR(PTR) " 4b,8b\n"
STR(PTR) " 5b,8b\n"
STR(PTR) " 6b,8b\n"
STR(PTR) " 7b,8b\n"
STR(PTR) " 0b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@ -1820,14 +1821,14 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .word 1b,8b\n"
" .word 2b,8b\n"
" .word 3b,8b\n"
" .word 4b,8b\n"
" .word 5b,8b\n"
" .word 6b,8b\n"
" .word 7b,8b\n"
" .word 0b,8b\n"
STR(PTR) " 1b,8b\n"
STR(PTR) " 2b,8b\n"
STR(PTR) " 3b,8b\n"
STR(PTR) " 4b,8b\n"
STR(PTR) " 5b,8b\n"
STR(PTR) " 6b,8b\n"
STR(PTR) " 7b,8b\n"
STR(PTR) " 0b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@ -1938,14 +1939,14 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
" j 9b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .word 1b,8b\n"
" .word 2b,8b\n"
" .word 3b,8b\n"
" .word 4b,8b\n"
" .word 5b,8b\n"
" .word 6b,8b\n"
" .word 7b,8b\n"
" .word 0b,8b\n"
STR(PTR) " 1b,8b\n"
STR(PTR) " 2b,8b\n"
STR(PTR) " 3b,8b\n"
STR(PTR) " 4b,8b\n"
STR(PTR) " 5b,8b\n"
STR(PTR) " 6b,8b\n"
STR(PTR) " 7b,8b\n"
STR(PTR) " 0b,8b\n"
" .previous\n"
" .set pop\n"
: "+&r"(rt), "=&r"(rs),
@ -2000,7 +2001,7 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
"j 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
".word 1b, 3b\n"
STR(PTR) " 1b,3b\n"
".previous\n"
: "=&r"(res), "+&r"(err)
: "r"(vaddr), "i"(SIGSEGV)
@ -2058,7 +2059,7 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
"j 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
".word 1b, 3b\n"
STR(PTR) " 1b,3b\n"
".previous\n"
: "+&r"(res), "+&r"(err)
: "r"(vaddr), "i"(SIGSEGV));
@ -2119,7 +2120,7 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
"j 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
".word 1b, 3b\n"
STR(PTR) " 1b,3b\n"
".previous\n"
: "=&r"(res), "+&r"(err)
: "r"(vaddr), "i"(SIGSEGV)
@ -2182,7 +2183,7 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
"j 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
".word 1b, 3b\n"
STR(PTR) " 1b,3b\n"
".previous\n"
: "+&r"(res), "+&r"(err)
: "r"(vaddr), "i"(SIGSEGV));

View File

@ -56,7 +56,7 @@ static void mips_cpu_restore(void)
write_c0_userlocal(current_thread_info()->tp_value);
/* Restore watch registers */
__restore_watch();
__restore_watch(current);
}
/**

View File

@ -457,7 +457,7 @@ unsigned long notrace unwind_stack_by_address(unsigned long stack_page,
*sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
regs = (struct pt_regs *)*sp;
pc = regs->cp0_epc;
if (__kernel_text_address(pc)) {
if (!user_mode(regs) && __kernel_text_address(pc)) {
*sp = regs->regs[29];
*ra = regs->regs[31];
return pc;
@ -603,6 +603,9 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6)
return -EOPNOTSUPP;
/* Proceed with the mode switch */
preempt_disable();
/* Save FP & vector context, then disable FPU & MSA */
if (task->signal == current->signal)
lose_fpu(1);
@ -661,6 +664,7 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
/* Allow threads to use FP again */
atomic_set(&task->mm->context.fp_mode_switching, 0);
preempt_enable();
return 0;
}

View File

@ -57,8 +57,7 @@ static void init_fp_ctx(struct task_struct *target)
/* Begin with data registers set to all 1s... */
memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
/* ...and FCSR zeroed */
target->thread.fpu.fcr31 = 0;
/* FCSR has been preset by `mips_set_personality_nan'. */
/*
* Record that the target has "used" math, such that the context
@ -79,6 +78,22 @@ void ptrace_disable(struct task_struct *child)
clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
}
/*
* Poke at FCSR according to its mask. Don't set the cause bits as
* this is currently not handled correctly in FP context restoration
* and will cause an oops if a corresponding enable bit is set.
*/
static void ptrace_setfcr31(struct task_struct *child, u32 value)
{
u32 fcr31;
u32 mask;
value &= ~FPU_CSR_ALL_X;
fcr31 = child->thread.fpu.fcr31;
mask = boot_cpu_data.fpu_msk31;
child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
}
/*
* Read a general register set. We always use the 64-bit format, even
* for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
@ -159,9 +174,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
{
union fpureg *fregs;
u64 fpr_val;
u32 fcr31;
u32 value;
u32 mask;
int i;
if (!access_ok(VERIFY_READ, data, 33 * 8))
@ -176,9 +189,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
}
__get_user(value, data + 64);
fcr31 = child->thread.fpu.fcr31;
mask = boot_cpu_data.fpu_msk31;
child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
ptrace_setfcr31(child, value);
/* FIR may not be written. */
@ -808,7 +819,7 @@ long arch_ptrace(struct task_struct *child, long request,
break;
#endif
case FPC_CSR:
child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X;
ptrace_setfcr31(child, data);
break;
case DSP_BASE ... DSP_BASE + 5: {
dspreg_t *dregs;

View File

@ -244,17 +244,17 @@ LEAF(\name)
.set push
.set noat
#ifdef CONFIG_64BIT
copy_u_d \wr, 1
copy_s_d \wr, 1
EX sd $1, \off(\base)
#elif defined(CONFIG_CPU_LITTLE_ENDIAN)
copy_u_w \wr, 2
copy_s_w \wr, 2
EX sw $1, \off(\base)
copy_u_w \wr, 3
copy_s_w \wr, 3
EX sw $1, (\off+4)(\base)
#else /* CONFIG_CPU_BIG_ENDIAN */
copy_u_w \wr, 2
copy_s_w \wr, 2
EX sw $1, (\off+4)(\base)
copy_u_w \wr, 3
copy_s_w \wr, 3
EX sw $1, \off(\base)
#endif
.set pop

View File

@ -706,6 +706,9 @@ static void __init arch_mem_init(char **cmdline_p)
for_each_memblock(reserved, reg)
if (reg->size != 0)
reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
reserve_bootmem_region(__pa_symbol(&__nosave_begin),
__pa_symbol(&__nosave_end)); /* Reserve for hibernation */
}
static void __init resource_init(void)

View File

@ -195,6 +195,9 @@ static int restore_msa_extcontext(void __user *buf, unsigned int size)
unsigned int csr;
int i, err;
if (!config_enabled(CONFIG_CPU_HAS_MSA))
return SIGSYS;
if (size != sizeof(*msa))
return -EINVAL;
@ -398,8 +401,8 @@ int protected_restore_fp_context(void __user *sc)
}
fp_done:
if (used & USED_EXTCONTEXT)
err |= restore_extcontext(sc_to_extcontext(sc));
if (!err && (used & USED_EXTCONTEXT))
err = restore_extcontext(sc_to_extcontext(sc));
return err ?: sig;
}
@ -767,15 +770,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
sigset_t *oldset = sigmask_to_save();
int ret;
struct mips_abi *abi = current->thread.abi;
#ifdef CONFIG_CPU_MICROMIPS
void *vdso;
unsigned long tmp = (unsigned long)current->mm->context.vdso;
set_isa16_mode(tmp);
vdso = (void *)tmp;
#else
void *vdso = current->mm->context.vdso;
#endif
if (regs->regs[0]) {
switch(regs->regs[2]) {

View File

@ -144,7 +144,7 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs)
if (!task)
task = current;
if (raw_show_trace || !__kernel_text_address(pc)) {
if (raw_show_trace || user_mode(regs) || !__kernel_text_address(pc)) {
show_raw_backtrace(sp);
return;
}
@ -1241,7 +1241,7 @@ static int enable_restore_fp_context(int msa)
err = init_fpu();
if (msa && !err) {
enable_msa();
_init_msa_upper();
init_msa_upper();
set_thread_flag(TIF_USEDMSA);
set_thread_flag(TIF_MSA_CTX_LIVE);
}
@ -1304,7 +1304,7 @@ static int enable_restore_fp_context(int msa)
*/
prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE);
if (!prior_msa && was_fpu_owner) {
_init_msa_upper();
init_msa_upper();
goto out;
}
@ -1321,7 +1321,7 @@ static int enable_restore_fp_context(int msa)
* of each vector register such that it cannot see data left
* behind by another task.
*/
_init_msa_upper();
init_msa_upper();
} else {
/* We need to restore the vector context. */
restore_msa(current);

View File

@ -15,10 +15,9 @@
* Install the watch registers for the current thread. A maximum of
* four registers are installed although the machine may have more.
*/
void mips_install_watch_registers(void)
void mips_install_watch_registers(struct task_struct *t)
{
struct mips3264_watch_reg_state *watches =
&current->thread.watch.mips3264;
struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
switch (current_cpu_data.watch_reg_use_cnt) {
default:
BUG();

View File

@ -302,12 +302,31 @@ static inline ktime_t kvm_mips_count_time(struct kvm_vcpu *vcpu)
*/
static uint32_t kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now)
{
ktime_t expires;
struct mips_coproc *cop0 = vcpu->arch.cop0;
ktime_t expires, threshold;
uint32_t count, compare;
int running;
/* Is the hrtimer pending? */
/* Calculate the biased and scaled guest CP0_Count */
count = vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
compare = kvm_read_c0_guest_compare(cop0);
/*
* Find whether CP0_Count has reached the closest timer interrupt. If
* not, we shouldn't inject it.
*/
if ((int32_t)(count - compare) < 0)
return count;
/*
* The CP0_Count we're going to return has already reached the closest
* timer interrupt. Quickly check if it really is a new interrupt by
* looking at whether the interval until the hrtimer expiry time is
* less than 1/4 of the timer period.
*/
expires = hrtimer_get_expires(&vcpu->arch.comparecount_timer);
if (ktime_compare(now, expires) >= 0) {
threshold = ktime_add_ns(now, vcpu->arch.count_period / 4);
if (ktime_before(expires, threshold)) {
/*
* Cancel it while we handle it so there's no chance of
* interference with the timeout handler.
@ -329,8 +348,7 @@ static uint32_t kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now)
}
}
/* Return the biased and scaled guest CP0_Count */
return vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
return count;
}
/**
@ -419,32 +437,6 @@ static void kvm_mips_resume_hrtimer(struct kvm_vcpu *vcpu,
hrtimer_start(&vcpu->arch.comparecount_timer, expire, HRTIMER_MODE_ABS);
}
/**
* kvm_mips_update_hrtimer() - Update next expiry time of hrtimer.
* @vcpu: Virtual CPU.
*
* Recalculates and updates the expiry time of the hrtimer. This can be used
* after timer parameters have been altered which do not depend on the time that
* the change occurs (in those cases kvm_mips_freeze_hrtimer() and
* kvm_mips_resume_hrtimer() are used directly).
*
* It is guaranteed that no timer interrupts will be lost in the process.
*
* Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is running).
*/
static void kvm_mips_update_hrtimer(struct kvm_vcpu *vcpu)
{
ktime_t now;
uint32_t count;
/*
* freeze_hrtimer takes care of a timer interrupts <= count, and
* resume_hrtimer the hrtimer takes care of a timer interrupts > count.
*/
now = kvm_mips_freeze_hrtimer(vcpu, &count);
kvm_mips_resume_hrtimer(vcpu, now, count);
}
/**
* kvm_mips_write_count() - Modify the count and update timer.
* @vcpu: Virtual CPU.
@ -540,23 +532,42 @@ int kvm_mips_set_count_hz(struct kvm_vcpu *vcpu, s64 count_hz)
* kvm_mips_write_compare() - Modify compare and update timer.
* @vcpu: Virtual CPU.
* @compare: New CP0_Compare value.
* @ack: Whether to acknowledge timer interrupt.
*
* Update CP0_Compare to a new value and update the timeout.
* If @ack, atomically acknowledge any pending timer interrupt, otherwise ensure
* any pending timer interrupt is preserved.
*/
void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare)
void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack)
{
struct mips_coproc *cop0 = vcpu->arch.cop0;
int dc;
u32 old_compare = kvm_read_c0_guest_compare(cop0);
ktime_t now;
uint32_t count;
/* if unchanged, must just be an ack */
if (kvm_read_c0_guest_compare(cop0) == compare)
if (old_compare == compare) {
if (!ack)
return;
kvm_mips_callbacks->dequeue_timer_int(vcpu);
kvm_write_c0_guest_compare(cop0, compare);
return;
}
/* freeze_hrtimer() takes care of timer interrupts <= count */
dc = kvm_mips_count_disabled(vcpu);
if (!dc)
now = kvm_mips_freeze_hrtimer(vcpu, &count);
if (ack)
kvm_mips_callbacks->dequeue_timer_int(vcpu);
/* Update compare */
kvm_write_c0_guest_compare(cop0, compare);
/* Update timeout if count enabled */
if (!kvm_mips_count_disabled(vcpu))
kvm_mips_update_hrtimer(vcpu);
/* resume_hrtimer() takes care of timer interrupts > count */
if (!dc)
kvm_mips_resume_hrtimer(vcpu, now, count);
}
/**
@ -1095,9 +1106,9 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
/* If we are writing to COMPARE */
/* Clear pending timer interrupt, if any */
kvm_mips_callbacks->dequeue_timer_int(vcpu);
kvm_mips_write_compare(vcpu,
vcpu->arch.gprs[rt]);
vcpu->arch.gprs[rt],
true);
} else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) {
unsigned int old_val, val, change;

View File

@ -547,7 +547,7 @@ static int kvm_trap_emul_set_one_reg(struct kvm_vcpu *vcpu,
kvm_mips_write_count(vcpu, v);
break;
case KVM_REG_MIPS_CP0_COMPARE:
kvm_mips_write_compare(vcpu, v);
kvm_mips_write_compare(vcpu, v, false);
break;
case KVM_REG_MIPS_CP0_CAUSE:
/*

View File

@ -2,7 +2,7 @@
#include "libgcc.h"
long long __ashldi3(long long u, word_type b)
long long notrace __ashldi3(long long u, word_type b)
{
DWunion uu, w;
word_type bm;

View File

@ -2,7 +2,7 @@
#include "libgcc.h"
long long __ashrdi3(long long u, word_type b)
long long notrace __ashrdi3(long long u, word_type b)
{
DWunion uu, w;
word_type bm;

View File

@ -1,6 +1,6 @@
#include <linux/module.h>
unsigned long long __bswapdi2(unsigned long long u)
unsigned long long notrace __bswapdi2(unsigned long long u)
{
return (((u) & 0xff00000000000000ull) >> 56) |
(((u) & 0x00ff000000000000ull) >> 40) |

View File

@ -1,6 +1,6 @@
#include <linux/module.h>
unsigned int __bswapsi2(unsigned int u)
unsigned int notrace __bswapsi2(unsigned int u)
{
return (((u) & 0xff000000) >> 24) |
(((u) & 0x00ff0000) >> 8) |

View File

@ -2,7 +2,7 @@
#include "libgcc.h"
word_type __cmpdi2(long long a, long long b)
word_type notrace __cmpdi2(long long a, long long b)
{
const DWunion au = {
.ll = a

View File

@ -2,7 +2,7 @@
#include "libgcc.h"
long long __lshrdi3(long long u, word_type b)
long long notrace __lshrdi3(long long u, word_type b)
{
DWunion uu, w;
word_type bm;

View File

@ -2,7 +2,7 @@
#include "libgcc.h"
word_type __ucmpdi2(unsigned long long a, unsigned long long b)
word_type notrace __ucmpdi2(unsigned long long a, unsigned long long b)
{
const DWunion au = {.ll = a};
const DWunion bu = {.ll = b};

View File

@ -213,10 +213,10 @@ static void __init node_mem_init(unsigned int node)
BOOTMEM_DEFAULT);
if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) {
/* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */
/* Reserve 0xfe000000~0xffffffff for RS780E integrated GPU */
reserve_bootmem_node(NODE_DATA(node),
(node_addrspace_offset | 0xff800000),
8 << 20, BOOTMEM_DEFAULT);
(node_addrspace_offset | 0xfe000000),
32 << 20, BOOTMEM_DEFAULT);
}
sparse_memory_present_with_active_regions(node);

View File

@ -445,9 +445,11 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case spec_op:
switch (insn.r_format.func) {
case jalr_op:
regs->regs[insn.r_format.rd] =
regs->cp0_epc + dec_insn.pc_inc +
dec_insn.next_pc_inc;
if (insn.r_format.rd != 0) {
regs->regs[insn.r_format.rd] =
regs->cp0_epc + dec_insn.pc_inc +
dec_insn.next_pc_inc;
}
/* Fall through */
case jr_op:
/* For R6, JR already emulated in jalr_op */

View File

@ -16,6 +16,7 @@
#include <linux/mm.h>
#include <asm/cacheflush.h>
#include <asm/highmem.h>
#include <asm/processor.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
@ -83,8 +84,6 @@ void __flush_dcache_page(struct page *page)
struct address_space *mapping = page_mapping(page);
unsigned long addr;
if (PageHighMem(page))
return;
if (mapping && !mapping_mapped(mapping)) {
SetPageDcacheDirty(page);
return;
@ -95,8 +94,15 @@ void __flush_dcache_page(struct page *page)
* case is for exec env/arg pages and those are %99 certainly going to
* get faulted into the tlb (and thus flushed) anyways.
*/
addr = (unsigned long) page_address(page);
if (PageHighMem(page))
addr = (unsigned long)kmap_atomic(page);
else
addr = (unsigned long)page_address(page);
flush_data_cache_page(addr);
if (PageHighMem(page))
__kunmap_atomic((void *)addr);
}
EXPORT_SYMBOL(__flush_dcache_page);
@ -119,33 +125,28 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
EXPORT_SYMBOL(__flush_anon_page);
void __flush_icache_page(struct vm_area_struct *vma, struct page *page)
{
unsigned long addr;
if (PageHighMem(page))
return;
addr = (unsigned long) page_address(page);
flush_data_cache_page(addr);
}
EXPORT_SYMBOL_GPL(__flush_icache_page);
void __update_cache(struct vm_area_struct *vma, unsigned long address,
pte_t pte)
void __update_cache(unsigned long address, pte_t pte)
{
struct page *page;
unsigned long pfn, addr;
int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
int exec = !pte_no_exec(pte) && !cpu_has_ic_fills_f_dc;
pfn = pte_pfn(pte);
if (unlikely(!pfn_valid(pfn)))
return;
page = pfn_to_page(pfn);
if (page_mapping(page) && Page_dcache_dirty(page)) {
addr = (unsigned long) page_address(page);
if (Page_dcache_dirty(page)) {
if (PageHighMem(page))
addr = (unsigned long)kmap_atomic(page);
else
addr = (unsigned long)page_address(page);
if (exec || pages_do_alias(addr, address & PAGE_MASK))
flush_data_cache_page(addr);
if (PageHighMem(page))
__kunmap_atomic((void *)addr);
ClearPageDcacheDirty(page);
}
}

View File

@ -5,10 +5,12 @@ obj-vdso-y := elf.o gettimeofday.o sigreturn.o
ccflags-vdso := \
$(filter -I%,$(KBUILD_CFLAGS)) \
$(filter -E%,$(KBUILD_CFLAGS)) \
$(filter -mmicromips,$(KBUILD_CFLAGS)) \
$(filter -march=%,$(KBUILD_CFLAGS))
cflags-vdso := $(ccflags-vdso) \
$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
-O2 -g -fPIC -fno-common -fno-builtin -G 0 -DDISABLE_BRANCH_PROFILING \
-O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
-DDISABLE_BRANCH_PROFILING \
$(call cc-option, -fno-stack-protector)
aflags-vdso := $(ccflags-vdso) \
$(filter -I%,$(KBUILD_CFLAGS)) \

View File

@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *regs)
break;
}
if (modify && R1(regs->iir))
if (ret == 0 && modify && R1(regs->iir))
regs->gr[R1(regs->iir)] = newbase;
@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *regs)
if (ret)
{
/*
* The unaligned handler failed.
* If we were called by __get_user() or __put_user() jump
* to it's exception fixup handler instead of crashing.
*/
if (!user_mode(regs) && fixup_exception(regs))
return;
printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
die_if_kernel("Unaligned data reference", regs, 28);

View File

@ -707,7 +707,7 @@
#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
#define SPRN_MMCR1 798
#define SPRN_MMCR2 769
#define SPRN_MMCR2 785
#define SPRN_MMCRA 0x312
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
@ -744,13 +744,13 @@
#define SPRN_PMC6 792
#define SPRN_PMC7 793
#define SPRN_PMC8 794
#define SPRN_SIAR 780
#define SPRN_SDAR 781
#define SPRN_SIER 784
#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
#define SPRN_SIAR 796
#define SPRN_SDAR 797
#define SPRN_TACR 888
#define SPRN_TCSCR 889
#define SPRN_CSIGR 890

View File

@ -1072,7 +1072,7 @@ void eeh_add_device_early(struct pci_dn *pdn)
struct pci_controller *phb;
struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
if (!edev || !eeh_enabled())
if (!edev)
return;
if (!eeh_has_flag(EEH_PROBE_MODE_DEVTREE))

View File

@ -166,6 +166,16 @@ static void *eeh_dev_save_state(void *data, void *userdata)
if (!edev)
return NULL;
/*
* We cannot access the config space on some adapters.
* Otherwise, it will cause fenced PHB. We don't save
* the content in their config space and will restore
* from the initial config space saved when the EEH
* device is created.
*/
if (edev->pe && (edev->pe->state & EEH_PE_CFG_RESTRICTED))
return NULL;
pdev = eeh_dev_to_pci_dev(edev);
if (!pdev)
return NULL;
@ -305,6 +315,19 @@ static void *eeh_dev_restore_state(void *data, void *userdata)
if (!edev)
return NULL;
/*
* The content in the config space isn't saved because
* the blocked config space on some adapters. We have
* to restore the initial saved config space when the
* EEH device is created.
*/
if (edev->pe && (edev->pe->state & EEH_PE_CFG_RESTRICTED)) {
if (list_is_last(&edev->list, &edev->pe->edevs))
eeh_pe_restore_bars(edev->pe);
return NULL;
}
pdev = eeh_dev_to_pci_dev(edev);
if (!pdev)
return NULL;
@ -504,9 +527,6 @@ int eeh_pe_reset_and_recover(struct eeh_pe *pe)
/* Save states */
eeh_pe_dev_traverse(pe, eeh_dev_save_state, NULL);
/* Report error */
eeh_pe_dev_traverse(pe, eeh_report_error, &result);
/* Issue reset */
ret = eeh_reset_pe(pe);
if (ret) {

View File

@ -962,11 +962,6 @@ hv_facility_unavailable_relon_trampoline:
#endif
STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
/* Other future vectors */
.align 7
.globl __end_interrupts
__end_interrupts:
.align 7
system_call_entry:
b system_call_common
@ -1253,6 +1248,17 @@ __end_handlers:
STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable)
/*
* The __end_interrupts marker must be past the out-of-line (OOL)
* handlers, so that they are copied to real address 0x100 when running
* a relocatable kernel. This ensures they can be reached from the short
* trampoline handlers (like 0x4f00, 0x4f20, etc.) which branch
* directly, without using LOAD_HANDLER().
*/
.align 7
.globl __end_interrupts
__end_interrupts:
#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
/*
* Data area reserved for FWNMI option.

View File

@ -655,6 +655,7 @@ unsigned char ibm_architecture_vec[] = {
W(0xffff0000), W(0x003e0000), /* POWER6 */
W(0xffff0000), W(0x003f0000), /* POWER7 */
W(0xffff0000), W(0x004b0000), /* POWER8E */
W(0xffff0000), W(0x004c0000), /* POWER8NVL */
W(0xffff0000), W(0x004d0000), /* POWER8 */
W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */

View File

@ -615,29 +615,50 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
{
int config_addr;
int ret;
/* Waiting 0.2s maximum before skipping configuration */
int max_wait = 200;
/* Figure out the PE address */
config_addr = pe->config_addr;
if (pe->addr)
config_addr = pe->addr;
/* Use new configure-pe function, if supported */
if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
config_addr, BUID_HI(pe->phb->buid),
BUID_LO(pe->phb->buid));
} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
config_addr, BUID_HI(pe->phb->buid),
BUID_LO(pe->phb->buid));
} else {
return -EFAULT;
while (max_wait > 0) {
/* Use new configure-pe function, if supported */
if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
config_addr, BUID_HI(pe->phb->buid),
BUID_LO(pe->phb->buid));
} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
config_addr, BUID_HI(pe->phb->buid),
BUID_LO(pe->phb->buid));
} else {
return -EFAULT;
}
if (!ret)
return ret;
/*
* If RTAS returns a delay value that's above 100ms, cut it
* down to 100ms in case firmware made a mistake. For more
* on how these delay values work see rtas_busy_delay_time
*/
if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
ret <= RTAS_EXTENDED_DELAY_MAX)
ret = RTAS_EXTENDED_DELAY_MIN+2;
max_wait -= rtas_busy_delay_time(ret);
if (max_wait < 0)
break;
rtas_busy_delay(ret);
}
if (ret)
pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
__func__, pe->phb->global_number, pe->addr, ret);
pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
__func__, pe->phb->global_number, pe->addr, ret);
return ret;
}

View File

@ -37,7 +37,7 @@ extern u8 sk_load_word[], sk_load_half[], sk_load_byte[];
* | | |
* +---------------+ |
* | 8 byte skbp | |
* R15+170 -> +---------------+ |
* R15+176 -> +---------------+ |
* | 8 byte hlen | |
* R15+168 -> +---------------+ |
* | 4 byte align | |
@ -58,7 +58,7 @@ extern u8 sk_load_word[], sk_load_half[], sk_load_byte[];
#define STK_OFF (STK_SPACE - STK_160_UNUSED)
#define STK_OFF_TMP 160 /* Offset of tmp buffer on stack */
#define STK_OFF_HLEN 168 /* Offset of SKB header length on stack */
#define STK_OFF_SKBP 170 /* Offset of SKB pointer on stack */
#define STK_OFF_SKBP 176 /* Offset of SKB pointer on stack */
#define STK_OFF_R6 (160 - 11 * 8) /* Offset of r6 on stack */
#define STK_OFF_TCCNT (160 - 12 * 8) /* Offset of tail_call_cnt on stack */

View File

@ -45,7 +45,7 @@ struct bpf_jit {
int labels[1]; /* Labels for local jumps */
};
#define BPF_SIZE_MAX 0x7ffff /* Max size for program (20 bit signed displ) */
#define BPF_SIZE_MAX 0xffff /* Max size for program (16 bit branches) */
#define SEEN_SKB 1 /* skb access */
#define SEEN_MEM 2 /* use mem[] for temporary storage */
@ -446,7 +446,7 @@ static void bpf_jit_prologue(struct bpf_jit *jit, bool is_classic)
emit_load_skb_data_hlen(jit);
if (jit->seen & SEEN_SKB_CHANGE)
/* stg %b1,ST_OFF_SKBP(%r0,%r15) */
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, REG_15,
EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15,
STK_OFF_SKBP);
/* Clear A (%b0) and X (%b7) registers for converted BPF programs */
if (is_classic) {

View File

@ -15,6 +15,10 @@
#define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ)
#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
#define __CHEETAH_ID 0x003e0014
#define __JALAPENO_ID 0x003e0016
#define __SERRANO_ID 0x003e0022

View File

@ -375,7 +375,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
#define pgprot_noncached pgprot_noncached
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
static inline pte_t pte_mkhuge(pte_t pte)
static inline unsigned long __pte_huge_mask(void)
{
unsigned long mask;
@ -390,8 +390,19 @@ static inline pte_t pte_mkhuge(pte_t pte)
: "=r" (mask)
: "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V));
return __pte(pte_val(pte) | mask);
return mask;
}
static inline pte_t pte_mkhuge(pte_t pte)
{
return __pte(pte_val(pte) | __pte_huge_mask());
}
static inline bool is_hugetlb_pte(pte_t pte)
{
return !!(pte_val(pte) & __pte_huge_mask());
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
static inline pmd_t pmd_mkhuge(pmd_t pmd)
{
@ -403,6 +414,11 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
return __pmd(pte_val(pte));
}
#endif
#else
static inline bool is_hugetlb_pte(pte_t pte)
{
return false;
}
#endif
static inline pte_t pte_mkdirty(pte_t pte)
@ -865,6 +881,19 @@ static inline unsigned long pud_pfn(pud_t pud)
void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
pte_t *ptep, pte_t orig, int fullmm);
static void maybe_tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
pte_t *ptep, pte_t orig, int fullmm)
{
/* It is more efficient to let flush_tlb_kernel_range()
* handle init_mm tlb flushes.
*
* SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
* and SUN4V pte layout, so this inline test is fine.
*/
if (likely(mm != &init_mm) && pte_accessible(mm, orig))
tlb_batch_add(mm, vaddr, ptep, orig, fullmm);
}
#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
unsigned long addr,
@ -881,15 +910,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t orig = *ptep;
*ptep = pte;
/* It is more efficient to let flush_tlb_kernel_range()
* handle init_mm tlb flushes.
*
* SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
* and SUN4V pte layout, so this inline test is fine.
*/
if (likely(mm != &init_mm) && pte_accessible(mm, orig))
tlb_batch_add(mm, addr, ptep, orig, fullmm);
maybe_tlb_batch_add(mm, addr, ptep, orig, fullmm);
}
#define set_pte_at(mm,addr,ptep,pte) \

View File

@ -8,6 +8,7 @@
#define TLB_BATCH_NR 192
struct tlb_batch {
bool huge;
struct mm_struct *mm;
unsigned long tlb_nr;
unsigned long active;
@ -16,7 +17,7 @@ struct tlb_batch {
void flush_tsb_kernel_range(unsigned long start, unsigned long end);
void flush_tsb_user(struct tlb_batch *tb);
void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);
void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, bool huge);
/* TLB flush operations. */

View File

@ -589,8 +589,8 @@ user_rtt_fill_64bit: \
restored; \
nop; nop; nop; nop; nop; nop; \
nop; nop; nop; nop; nop; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup_dax; \
ba,a,pt %xcc, user_rtt_fill_fixup_mna; \
ba,a,pt %xcc, user_rtt_fill_fixup;
@ -652,8 +652,8 @@ user_rtt_fill_32bit: \
restored; \
nop; nop; nop; nop; nop; \
nop; nop; nop; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup_dax; \
ba,a,pt %xcc, user_rtt_fill_fixup_mna; \
ba,a,pt %xcc, user_rtt_fill_fixup;

View File

@ -21,6 +21,7 @@ CFLAGS_REMOVE_perf_event.o := -pg
CFLAGS_REMOVE_pcr.o := -pg
endif
obj-$(CONFIG_SPARC64) += urtt_fill.o
obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o
obj-$(CONFIG_SPARC32) += etrap_32.o
obj-$(CONFIG_SPARC32) += rtrap_32.o

View File

@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
subcc %g1, %g2, %g1 ! Next cacheline
bge,pt %icc, 1b
nop
ba,pt %xcc, dcpe_icpe_tl1_common
nop
ba,a,pt %xcc, dcpe_icpe_tl1_common
do_dcpe_tl1_fatal:
sethi %hi(1f), %g7
@ -224,8 +223,7 @@ do_dcpe_tl1_fatal:
mov 0x2, %o0
call cheetah_plus_parity_error
add %sp, PTREGS_OFF, %o1
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size do_dcpe_tl1,.-do_dcpe_tl1
.globl do_icpe_tl1
@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
subcc %g1, %g2, %g1
bge,pt %icc, 1b
nop
ba,pt %xcc, dcpe_icpe_tl1_common
nop
ba,a,pt %xcc, dcpe_icpe_tl1_common
do_icpe_tl1_fatal:
sethi %hi(1f), %g7
@ -269,8 +266,7 @@ do_icpe_tl1_fatal:
mov 0x3, %o0
call cheetah_plus_parity_error
add %sp, PTREGS_OFF, %o1
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size do_icpe_tl1,.-do_icpe_tl1
.type dcpe_icpe_tl1_common,#function
@ -456,7 +452,7 @@ __cheetah_log_error:
cmp %g2, 0x63
be c_cee
nop
ba,pt %xcc, c_deferred
ba,a,pt %xcc, c_deferred
.size __cheetah_log_error,.-__cheetah_log_error
/* Cheetah FECC trap handling, we get here from tl{0,1}_fecc

View File

@ -948,7 +948,24 @@ linux_syscall_trace:
cmp %o0, 0
bne 3f
mov -ENOSYS, %o0
/* Syscall tracing can modify the registers. */
ld [%sp + STACKFRAME_SZ + PT_G1], %g1
sethi %hi(sys_call_table), %l7
ld [%sp + STACKFRAME_SZ + PT_I0], %i0
or %l7, %lo(sys_call_table), %l7
ld [%sp + STACKFRAME_SZ + PT_I1], %i1
ld [%sp + STACKFRAME_SZ + PT_I2], %i2
ld [%sp + STACKFRAME_SZ + PT_I3], %i3
ld [%sp + STACKFRAME_SZ + PT_I4], %i4
ld [%sp + STACKFRAME_SZ + PT_I5], %i5
cmp %g1, NR_syscalls
bgeu 3f
mov -ENOSYS, %o0
sll %g1, 2, %l4
mov %i0, %o0
ld [%l7 + %l4], %l7
mov %i1, %o1
mov %i2, %o2
mov %i3, %o3

View File

@ -100,8 +100,8 @@ do_fpdis:
fmuld %f0, %f2, %f26
faddd %f0, %f2, %f28
fmuld %f0, %f2, %f30
b,pt %xcc, fpdis_exit
nop
ba,a,pt %xcc, fpdis_exit
2: andcc %g5, FPRS_DU, %g0
bne,pt %icc, 3f
fzero %f32
@ -144,8 +144,8 @@ do_fpdis:
fmuld %f32, %f34, %f58
faddd %f32, %f34, %f60
fmuld %f32, %f34, %f62
ba,pt %xcc, fpdis_exit
nop
ba,a,pt %xcc, fpdis_exit
3: mov SECONDARY_CONTEXT, %g3
add %g6, TI_FPREGS, %g1
@ -197,8 +197,7 @@ fpdis_exit2:
fp_other_bounce:
call do_fpother
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size fp_other_bounce,.-fp_other_bounce
.align 32

View File

@ -461,9 +461,8 @@ sun4v_chip_type:
subcc %g3, 1, %g3
bne,pt %xcc, 41b
add %g1, 1, %g1
mov SUN4V_CHIP_SPARC64X, %g4
ba,pt %xcc, 5f
nop
mov SUN4V_CHIP_SPARC64X, %g4
49:
mov SUN4V_CHIP_UNKNOWN, %g4
@ -548,8 +547,7 @@ sun4u_init:
stxa %g0, [%g7] ASI_DMMU
membar #Sync
ba,pt %xcc, sun4u_continue
nop
ba,a,pt %xcc, sun4u_continue
sun4v_init:
/* Set ctx 0 */
@ -560,14 +558,12 @@ sun4v_init:
mov SECONDARY_CONTEXT, %g7
stxa %g0, [%g7] ASI_MMU
membar #Sync
ba,pt %xcc, niagara_tlb_fixup
nop
ba,a,pt %xcc, niagara_tlb_fixup
sun4u_continue:
BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
ba,pt %xcc, spitfire_tlb_fixup
nop
ba,a,pt %xcc, spitfire_tlb_fixup
niagara_tlb_fixup:
mov 3, %g2 /* Set TLB type to hypervisor. */
@ -639,8 +635,7 @@ niagara_patch:
call hypervisor_patch_cachetlbops
nop
ba,pt %xcc, tlb_fixup_done
nop
ba,a,pt %xcc, tlb_fixup_done
cheetah_tlb_fixup:
mov 2, %g2 /* Set TLB type to cheetah+. */
@ -659,8 +654,7 @@ cheetah_tlb_fixup:
call cheetah_patch_cachetlbops
nop
ba,pt %xcc, tlb_fixup_done
nop
ba,a,pt %xcc, tlb_fixup_done
spitfire_tlb_fixup:
/* Set TLB type to spitfire. */
@ -782,8 +776,7 @@ setup_trap_table:
call %o1
add %sp, (2047 + 128), %o0
ba,pt %xcc, 2f
nop
ba,a,pt %xcc, 2f
1: sethi %hi(sparc64_ttable_tl0), %o0
set prom_set_trap_table_name, %g2
@ -822,8 +815,7 @@ setup_trap_table:
BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
ba,pt %xcc, 2f
nop
ba,a,pt %xcc, 2f
/* Disable STICK_INT interrupts. */
1:

View File

@ -18,8 +18,7 @@ __do_privact:
109: or %g7, %lo(109b), %g7
call do_privact
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size __do_privact,.-__do_privact
.type do_mna,#function
@ -46,8 +45,7 @@ do_mna:
mov %l5, %o2
call mem_address_unaligned
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size do_mna,.-do_mna
.type do_lddfmna,#function
@ -65,8 +63,7 @@ do_lddfmna:
mov %l5, %o2
call handle_lddfmna
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size do_lddfmna,.-do_lddfmna
.type do_stdfmna,#function
@ -84,8 +81,7 @@ do_stdfmna:
mov %l5, %o2
call handle_stdfmna
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size do_stdfmna,.-do_stdfmna
.type breakpoint_trap,#function

View File

@ -994,6 +994,23 @@ void pcibios_set_master(struct pci_dev *dev)
/* No special bus mastering setup handling */
}
#ifdef CONFIG_PCI_IOV
int pcibios_add_device(struct pci_dev *dev)
{
struct pci_dev *pdev;
/* Add sriov arch specific initialization here.
* Copy dev_archdata from PF to VF
*/
if (dev->is_virtfn) {
pdev = dev->physfn;
memcpy(&dev->dev.archdata, &pdev->dev.archdata,
sizeof(struct dev_archdata));
}
return 0;
}
#endif /* CONFIG_PCI_IOV */
static int __init pcibios_init(void)
{
pci_dfl_cache_line_size = 64 >> 2;

View File

@ -14,10 +14,6 @@
#include <asm/visasm.h>
#include <asm/processor.h>
#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
#ifdef CONFIG_CONTEXT_TRACKING
# define SCHEDULE_USER schedule_user
#else
@ -242,52 +238,17 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
wrpr %g1, %cwp
ba,a,pt %xcc, user_rtt_fill_64bit
user_rtt_fill_fixup_dax:
ba,pt %xcc, user_rtt_fill_fixup_common
mov 1, %g3
user_rtt_fill_fixup_mna:
ba,pt %xcc, user_rtt_fill_fixup_common
mov 2, %g3
user_rtt_fill_fixup:
rdpr %cwp, %g1
add %g1, 1, %g1
wrpr %g1, 0x0, %cwp
rdpr %wstate, %g2
sll %g2, 3, %g2
wrpr %g2, 0x0, %wstate
/* We know %canrestore and %otherwin are both zero. */
sethi %hi(sparc64_kern_pri_context), %g2
ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2
mov PRIMARY_CONTEXT, %g1
661: stxa %g2, [%g1] ASI_DMMU
.section .sun4v_1insn_patch, "ax"
.word 661b
stxa %g2, [%g1] ASI_MMU
.previous
sethi %hi(KERNBASE), %g1
flush %g1
or %g4, FAULT_CODE_WINFIXUP, %g4
stb %g4, [%g6 + TI_FAULT_CODE]
stx %g5, [%g6 + TI_FAULT_ADDR]
mov %g6, %l1
wrpr %g0, 0x0, %tl
661: nop
.section .sun4v_1insn_patch, "ax"
.word 661b
SET_GL(0)
.previous
wrpr %g0, RTRAP_PSTATE, %pstate
mov %l1, %g6
ldx [%g6 + TI_TASK], %g4
LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
call do_sparc64_fault
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,pt %xcc, user_rtt_fill_fixup_common
clr %g3
user_rtt_pre_restore:
add %g1, 1, %g1

View File

@ -138,12 +138,24 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
return 0;
}
/* Checks if the fp is valid. We always build signal frames which are
* 16-byte aligned, therefore we can always enforce that the restore
* frame has that property as well.
*/
static bool invalid_frame_pointer(void __user *fp, int fplen)
{
if ((((unsigned long) fp) & 15) ||
((unsigned long)fp) > 0x100000000ULL - fplen)
return true;
return false;
}
void do_sigreturn32(struct pt_regs *regs)
{
struct signal_frame32 __user *sf;
compat_uptr_t fpu_save;
compat_uptr_t rwin_save;
unsigned int psr;
unsigned int psr, ufp;
unsigned pc, npc;
sigset_t set;
compat_sigset_t seta;
@ -158,11 +170,16 @@ void do_sigreturn32(struct pt_regs *regs)
sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
/* 1. Make sure we are not getting garbage from the user */
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
(((unsigned long) sf) & 3))
if (invalid_frame_pointer(sf, sizeof(*sf)))
goto segv;
if (get_user(pc, &sf->info.si_regs.pc) ||
if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
goto segv;
if (ufp & 0x7)
goto segv;
if (__get_user(pc, &sf->info.si_regs.pc) ||
__get_user(npc, &sf->info.si_regs.npc))
goto segv;
@ -227,7 +244,7 @@ void do_sigreturn32(struct pt_regs *regs)
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
{
struct rt_signal_frame32 __user *sf;
unsigned int psr, pc, npc;
unsigned int psr, pc, npc, ufp;
compat_uptr_t fpu_save;
compat_uptr_t rwin_save;
sigset_t set;
@ -242,11 +259,16 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
/* 1. Make sure we are not getting garbage from the user */
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
(((unsigned long) sf) & 3))
if (invalid_frame_pointer(sf, sizeof(*sf)))
goto segv;
if (get_user(pc, &sf->regs.pc) ||
if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
goto segv;
if (ufp & 0x7)
goto segv;
if (__get_user(pc, &sf->regs.pc) ||
__get_user(npc, &sf->regs.npc))
goto segv;
@ -307,14 +329,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
force_sig(SIGSEGV, current);
}
/* Checks if the fp is valid */
static int invalid_frame_pointer(void __user *fp, int fplen)
{
if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
return 1;
return 0;
}
static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
{
unsigned long sp;

View File

@ -60,10 +60,22 @@ struct rt_signal_frame {
#define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
/* Checks if the fp is valid. We always build signal frames which are
* 16-byte aligned, therefore we can always enforce that the restore
* frame has that property as well.
*/
static inline bool invalid_frame_pointer(void __user *fp, int fplen)
{
if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
return true;
return false;
}
asmlinkage void do_sigreturn(struct pt_regs *regs)
{
unsigned long up_psr, pc, npc, ufp;
struct signal_frame __user *sf;
unsigned long up_psr, pc, npc;
sigset_t set;
__siginfo_fpu_t __user *fpu_save;
__siginfo_rwin_t __user *rwin_save;
@ -77,10 +89,13 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
/* 1. Make sure we are not getting garbage from the user */
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
if (!invalid_frame_pointer(sf, sizeof(*sf)))
goto segv_and_exit;
if (((unsigned long) sf) & 3)
if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
goto segv_and_exit;
if (ufp & 0x7)
goto segv_and_exit;
err = __get_user(pc, &sf->info.si_regs.pc);
@ -127,7 +142,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
{
struct rt_signal_frame __user *sf;
unsigned int psr, pc, npc;
unsigned int psr, pc, npc, ufp;
__siginfo_fpu_t __user *fpu_save;
__siginfo_rwin_t __user *rwin_save;
sigset_t set;
@ -135,8 +150,13 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
synchronize_user_stack();
sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
(((unsigned long) sf) & 0x03))
if (!invalid_frame_pointer(sf, sizeof(*sf)))
goto segv;
if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
goto segv;
if (ufp & 0x7)
goto segv;
err = __get_user(pc, &sf->regs.pc);
@ -178,15 +198,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
force_sig(SIGSEGV, current);
}
/* Checks if the fp is valid */
static inline int invalid_frame_pointer(void __user *fp, int fplen)
{
if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
return 1;
return 0;
}
static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
{
unsigned long sp = regs->u_regs[UREG_FP];

View File

@ -52,7 +52,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
unsigned char fenab;
int err;
flush_user_windows();
synchronize_user_stack();
if (get_thread_wsaved() ||
(((unsigned long)ucp) & (sizeof(unsigned long)-1)) ||
(!__access_ok(ucp, sizeof(*ucp))))
@ -234,6 +234,17 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
goto out;
}
/* Checks if the fp is valid. We always build rt signal frames which
* are 16-byte aligned, therefore we can always enforce that the
* restore frame has that property as well.
*/
static bool invalid_frame_pointer(void __user *fp)
{
if (((unsigned long) fp) & 15)
return true;
return false;
}
struct rt_signal_frame {
struct sparc_stackf ss;
siginfo_t info;
@ -246,8 +257,8 @@ struct rt_signal_frame {
void do_rt_sigreturn(struct pt_regs *regs)
{
unsigned long tpc, tnpc, tstate, ufp;
struct rt_signal_frame __user *sf;
unsigned long tpc, tnpc, tstate;
__siginfo_fpu_t __user *fpu_save;
__siginfo_rwin_t __user *rwin_save;
sigset_t set;
@ -261,10 +272,16 @@ void do_rt_sigreturn(struct pt_regs *regs)
(regs->u_regs [UREG_FP] + STACK_BIAS);
/* 1. Make sure we are not getting garbage from the user */
if (((unsigned long) sf) & 3)
if (invalid_frame_pointer(sf))
goto segv;
err = get_user(tpc, &sf->regs.tpc);
if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
goto segv;
if ((ufp + STACK_BIAS) & 0x7)
goto segv;
err = __get_user(tpc, &sf->regs.tpc);
err |= __get_user(tnpc, &sf->regs.tnpc);
if (test_thread_flag(TIF_32BIT)) {
tpc &= 0xffffffff;
@ -308,14 +325,6 @@ void do_rt_sigreturn(struct pt_regs *regs)
force_sig(SIGSEGV, current);
}
/* Checks if the fp is valid */
static int invalid_frame_pointer(void __user *fp)
{
if (((unsigned long) fp) & 15)
return 1;
return 0;
}
static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
{
unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;

View File

@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
int err;
if (((unsigned long) fpu) & 3)
return -EFAULT;
#ifdef CONFIG_SMP
if (test_tsk_thread_flag(current, TIF_USEDFPU))
regs->psr &= ~PSR_EF;
@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
struct thread_info *t = current_thread_info();
int i, wsaved, err;
__get_user(wsaved, &rp->wsaved);
if (((unsigned long) rp) & 3)
return -EFAULT;
get_user(wsaved, &rp->wsaved);
if (wsaved > NSWINS)
return -EFAULT;

View File

@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
unsigned long fprs;
int err;
err = __get_user(fprs, &fpu->si_fprs);
if (((unsigned long) fpu) & 7)
return -EFAULT;
err = get_user(fprs, &fpu->si_fprs);
fprs_write(0);
regs->tstate &= ~TSTATE_PEF;
if (fprs & FPRS_DL)
@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
struct thread_info *t = current_thread_info();
int i, wsaved, err;
__get_user(wsaved, &rp->wsaved);
if (((unsigned long) rp) & 7)
return -EFAULT;
get_user(wsaved, &rp->wsaved);
if (wsaved > NSWINS)
return -EFAULT;

View File

@ -85,8 +85,7 @@ __spitfire_cee_trap_continue:
ba,pt %xcc, etraptl1
rd %pc, %g7
ba,pt %xcc, 2f
nop
ba,a,pt %xcc, 2f
1: ba,pt %xcc, etrap_irq
rd %pc, %g7
@ -100,8 +99,7 @@ __spitfire_cee_trap_continue:
mov %l5, %o2
call spitfire_access_error
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size __spitfire_access_error,.-__spitfire_access_error
/* This is the trap handler entry point for ECC correctable
@ -179,8 +177,7 @@ __spitfire_data_access_exception_tl1:
mov %l5, %o2
call spitfire_data_access_exception_tl1
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1
.type __spitfire_data_access_exception,#function
@ -200,8 +197,7 @@ __spitfire_data_access_exception:
mov %l5, %o2
call spitfire_data_access_exception
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size __spitfire_data_access_exception,.-__spitfire_data_access_exception
.type __spitfire_insn_access_exception_tl1,#function
@ -220,8 +216,7 @@ __spitfire_insn_access_exception_tl1:
mov %l5, %o2
call spitfire_insn_access_exception_tl1
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1
.type __spitfire_insn_access_exception,#function
@ -240,6 +235,5 @@ __spitfire_insn_access_exception:
mov %l5, %o2
call spitfire_insn_access_exception
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
.size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception

View File

@ -158,7 +158,25 @@ linux_syscall_trace32:
add %sp, PTREGS_OFF, %o0
brnz,pn %o0, 3f
mov -ENOSYS, %o0
/* Syscall tracing can modify the registers. */
ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
sethi %hi(sys_call_table32), %l7
ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
or %l7, %lo(sys_call_table32), %l7
ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2
ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3
ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4
ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5
cmp %g1, NR_syscalls
bgeu,pn %xcc, 3f
mov -ENOSYS, %o0
sll %g1, 2, %l4
srl %i0, 0, %o0
lduw [%l7 + %l4], %l7
srl %i4, 0, %o4
srl %i1, 0, %o1
srl %i2, 0, %o2
@ -170,7 +188,25 @@ linux_syscall_trace:
add %sp, PTREGS_OFF, %o0
brnz,pn %o0, 3f
mov -ENOSYS, %o0
/* Syscall tracing can modify the registers. */
ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
sethi %hi(sys_call_table64), %l7
ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
or %l7, %lo(sys_call_table64), %l7
ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2
ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3
ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4
ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5
cmp %g1, NR_syscalls
bgeu,pn %xcc, 3f
mov -ENOSYS, %o0
sll %g1, 2, %l4
mov %i0, %o0
lduw [%l7 + %l4], %l7
mov %i1, %o1
mov %i2, %o2
mov %i3, %o3

View File

@ -0,0 +1,98 @@
#include <asm/thread_info.h>
#include <asm/trap_block.h>
#include <asm/spitfire.h>
#include <asm/ptrace.h>
#include <asm/head.h>
.text
.align 8
.globl user_rtt_fill_fixup_common
user_rtt_fill_fixup_common:
rdpr %cwp, %g1
add %g1, 1, %g1
wrpr %g1, 0x0, %cwp
rdpr %wstate, %g2
sll %g2, 3, %g2
wrpr %g2, 0x0, %wstate
/* We know %canrestore and %otherwin are both zero. */
sethi %hi(sparc64_kern_pri_context), %g2
ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2
mov PRIMARY_CONTEXT, %g1
661: stxa %g2, [%g1] ASI_DMMU
.section .sun4v_1insn_patch, "ax"
.word 661b
stxa %g2, [%g1] ASI_MMU
.previous
sethi %hi(KERNBASE), %g1
flush %g1
mov %g4, %l4
mov %g5, %l5
brnz,pn %g3, 1f
mov %g3, %l3
or %g4, FAULT_CODE_WINFIXUP, %g4
stb %g4, [%g6 + TI_FAULT_CODE]
stx %g5, [%g6 + TI_FAULT_ADDR]
1:
mov %g6, %l1
wrpr %g0, 0x0, %tl
661: nop
.section .sun4v_1insn_patch, "ax"
.word 661b
SET_GL(0)
.previous
wrpr %g0, RTRAP_PSTATE, %pstate
mov %l1, %g6
ldx [%g6 + TI_TASK], %g4
LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
brnz,pn %l3, 1f
nop
call do_sparc64_fault
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
1: cmp %g3, 2
bne,pn %xcc, 2f
nop
sethi %hi(tlb_type), %g1
lduw [%g1 + %lo(tlb_type)], %g1
cmp %g1, 3
bne,pt %icc, 1f
add %sp, PTREGS_OFF, %o0
mov %l4, %o2
call sun4v_do_mna
mov %l5, %o1
ba,a,pt %xcc, rtrap
1: mov %l4, %o1
mov %l5, %o2
call mem_address_unaligned
nop
ba,a,pt %xcc, rtrap
2: sethi %hi(tlb_type), %g1
mov %l4, %o1
lduw [%g1 + %lo(tlb_type)], %g1
mov %l5, %o2
cmp %g1, 3
bne,pt %icc, 1f
add %sp, PTREGS_OFF, %o0
call sun4v_data_access_exception
nop
ba,a,pt %xcc, rtrap
1: call spitfire_data_access_exception
nop
ba,a,pt %xcc, rtrap

View File

@ -11,8 +11,7 @@ utrap_trap: /* %g3=handler,%g4=level */
mov %l4, %o1
call bad_trap
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
invoke_utrap:
sllx %g3, 3, %g3

View File

@ -33,6 +33,10 @@ ENTRY(_start)
jiffies = jiffies_64;
#endif
#ifdef CONFIG_SPARC64
ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large")
#endif
SECTIONS
{
#ifdef CONFIG_SPARC64

View File

@ -32,8 +32,7 @@ fill_fixup:
rd %pc, %g7
call do_sparc64_fault
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
nop
ba,a,pt %xcc, rtrap
/* Be very careful about usage of the trap globals here.
* You cannot touch %g5 as that has the fault information.

View File

@ -176,17 +176,31 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t entry)
{
int i;
pte_t orig[2];
unsigned long nptes;
if (!pte_present(*ptep) && pte_present(entry))
mm->context.huge_pte_count++;
addr &= HPAGE_MASK;
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
set_pte_at(mm, addr, ptep, entry);
nptes = 1 << HUGETLB_PAGE_ORDER;
orig[0] = *ptep;
orig[1] = *(ptep + nptes / 2);
for (i = 0; i < nptes; i++) {
*ptep = entry;
ptep++;
addr += PAGE_SIZE;
pte_val(entry) += PAGE_SIZE;
}
/* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
addr -= REAL_HPAGE_SIZE;
ptep -= nptes / 2;
maybe_tlb_batch_add(mm, addr, ptep, orig[1], 0);
addr -= REAL_HPAGE_SIZE;
ptep -= nptes / 2;
maybe_tlb_batch_add(mm, addr, ptep, orig[0], 0);
}
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
@ -194,19 +208,28 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
{
pte_t entry;
int i;
unsigned long nptes;
entry = *ptep;
if (pte_present(entry))
mm->context.huge_pte_count--;
addr &= HPAGE_MASK;
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
pte_clear(mm, addr, ptep);
nptes = 1 << HUGETLB_PAGE_ORDER;
for (i = 0; i < nptes; i++) {
*ptep = __pte(0UL);
addr += PAGE_SIZE;
ptep++;
}
/* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
addr -= REAL_HPAGE_SIZE;
ptep -= nptes / 2;
maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
addr -= REAL_HPAGE_SIZE;
ptep -= nptes / 2;
maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
return entry;
}

View File

@ -324,18 +324,6 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde
tsb_insert(tsb, tag, tte);
}
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
static inline bool is_hugetlb_pte(pte_t pte)
{
if ((tlb_type == hypervisor &&
(pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
(tlb_type != hypervisor &&
(pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U))
return true;
return false;
}
#endif
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
{
struct mm_struct *mm;
@ -1267,13 +1255,6 @@ static int __init numa_parse_mdesc(void)
int i, j, err, count;
u64 node;
/* Some sane defaults for numa latency values */
for (i = 0; i < MAX_NUMNODES; i++) {
for (j = 0; j < MAX_NUMNODES; j++)
numa_latency[i][j] = (i == j) ?
LOCAL_DISTANCE : REMOTE_DISTANCE;
}
node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups");
if (node == MDESC_NODE_NULL) {
mdesc_release(md);
@ -1369,10 +1350,18 @@ static int __init numa_parse_sun4u(void)
static int __init bootmem_init_numa(void)
{
int i, j;
int err = -1;
numadbg("bootmem_init_numa()\n");
/* Some sane defaults for numa latency values */
for (i = 0; i < MAX_NUMNODES; i++) {
for (j = 0; j < MAX_NUMNODES; j++)
numa_latency[i][j] = (i == j) ?
LOCAL_DISTANCE : REMOTE_DISTANCE;
}
if (numa_enabled) {
if (tlb_type == hypervisor)
err = numa_parse_mdesc();
@ -2832,9 +2821,10 @@ void hugetlb_setup(struct pt_regs *regs)
* the Data-TLB for huge pages.
*/
if (tlb_type == cheetah_plus) {
bool need_context_reload = false;
unsigned long ctx;
spin_lock(&ctx_alloc_lock);
spin_lock_irq(&ctx_alloc_lock);
ctx = mm->context.sparc64_ctx_val;
ctx &= ~CTX_PGSZ_MASK;
ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
@ -2853,9 +2843,12 @@ void hugetlb_setup(struct pt_regs *regs)
* also executing in this address space.
*/
mm->context.sparc64_ctx_val = ctx;
on_each_cpu(context_reload, mm, 0);
need_context_reload = true;
}
spin_unlock(&ctx_alloc_lock);
spin_unlock_irq(&ctx_alloc_lock);
if (need_context_reload)
on_each_cpu(context_reload, mm, 0);
}
}
#endif

View File

@ -67,7 +67,7 @@ void arch_leave_lazy_mmu_mode(void)
}
static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
bool exec)
bool exec, bool huge)
{
struct tlb_batch *tb = &get_cpu_var(tlb_batch);
unsigned long nr;
@ -84,13 +84,21 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
}
if (!tb->active) {
flush_tsb_user_page(mm, vaddr);
flush_tsb_user_page(mm, vaddr, huge);
global_flush_tlb_page(mm, vaddr);
goto out;
}
if (nr == 0)
if (nr == 0) {
tb->mm = mm;
tb->huge = huge;
}
if (tb->huge != huge) {
flush_tlb_pending();
tb->huge = huge;
nr = 0;
}
tb->vaddrs[nr] = vaddr;
tb->tlb_nr = ++nr;
@ -104,6 +112,8 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
pte_t *ptep, pte_t orig, int fullmm)
{
bool huge = is_hugetlb_pte(orig);
if (tlb_type != hypervisor &&
pte_dirty(orig)) {
unsigned long paddr, pfn = pte_pfn(orig);
@ -129,7 +139,7 @@ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
no_cache_flush:
if (!fullmm)
tlb_batch_add_one(mm, vaddr, pte_exec(orig));
tlb_batch_add_one(mm, vaddr, pte_exec(orig), huge);
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
@ -145,7 +155,7 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
if (pte_val(*pte) & _PAGE_VALID) {
bool exec = pte_exec(*pte);
tlb_batch_add_one(mm, vaddr, exec);
tlb_batch_add_one(mm, vaddr, exec, false);
}
pte++;
vaddr += PAGE_SIZE;
@ -185,8 +195,9 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
pte_t orig_pte = __pte(pmd_val(orig));
bool exec = pte_exec(orig_pte);
tlb_batch_add_one(mm, addr, exec);
tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec);
tlb_batch_add_one(mm, addr, exec, true);
tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec,
true);
} else {
tlb_batch_pmd_scan(mm, addr, orig);
}

View File

@ -76,14 +76,15 @@ void flush_tsb_user(struct tlb_batch *tb)
spin_lock_irqsave(&mm->context.lock, flags);
base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
if (tlb_type == cheetah_plus || tlb_type == hypervisor)
base = __pa(base);
__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
if (!tb->huge) {
base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
if (tlb_type == cheetah_plus || tlb_type == hypervisor)
base = __pa(base);
__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
}
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
if (tb->huge && mm->context.tsb_block[MM_TSB_HUGE].tsb) {
base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
if (tlb_type == cheetah_plus || tlb_type == hypervisor)
@ -94,20 +95,21 @@ void flush_tsb_user(struct tlb_batch *tb)
spin_unlock_irqrestore(&mm->context.lock, flags);
}
void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr)
void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, bool huge)
{
unsigned long nentries, base, flags;
spin_lock_irqsave(&mm->context.lock, flags);
base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
if (tlb_type == cheetah_plus || tlb_type == hypervisor)
base = __pa(base);
__flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
if (!huge) {
base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
if (tlb_type == cheetah_plus || tlb_type == hypervisor)
base = __pa(base);
__flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
}
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
if (huge && mm->context.tsb_block[MM_TSB_HUGE].tsb) {
base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
if (tlb_type == cheetah_plus || tlb_type == hypervisor)

View File

@ -694,6 +694,7 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
/* clear STOP and INT from current entry */
buf->topa_index[buf->stop_pos]->stop = 0;
buf->topa_index[buf->stop_pos]->intr = 0;
buf->topa_index[buf->intr_pos]->intr = 0;
/* how many pages till the STOP marker */
@ -718,6 +719,7 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
buf->intr_pos = idx;
buf->topa_index[buf->stop_pos]->stop = 1;
buf->topa_index[buf->stop_pos]->intr = 1;
buf->topa_index[buf->intr_pos]->intr = 1;
return 0;

Some files were not shown because too many files have changed in this diff Show More