Merge remote-tracking branch 'torvalds/master' into perf/core
To pick up fixes and get v5.10 development in sync with the main kernel sources. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
commit
717d182e41
4
.mailmap
4
.mailmap
|
@ -169,6 +169,10 @@ Juha Yrjola <juha.yrjola@solidboot.com>
|
|||
Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com>
|
||||
Kamil Konieczny <k.konieczny@samsung.com> <k.konieczny@partner.samsung.com>
|
||||
Kay Sievers <kay.sievers@vrfy.org>
|
||||
Kees Cook <keescook@chromium.org> <kees.cook@canonical.com>
|
||||
Kees Cook <keescook@chromium.org> <keescook@google.com>
|
||||
Kees Cook <keescook@chromium.org> <kees@outflux.net>
|
||||
Kees Cook <keescook@chromium.org> <kees@ubuntu.com>
|
||||
Kenneth W Chen <kenneth.w.chen@intel.com>
|
||||
Konstantin Khlebnikov <koct9i@gmail.com> <khlebnikov@yandex-team.ru>
|
||||
Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com>
|
||||
|
|
|
@ -1324,15 +1324,26 @@ PAGE_SIZE multiple when read back.
|
|||
pgmajfault
|
||||
Number of major page faults incurred
|
||||
|
||||
workingset_refault
|
||||
Number of refaults of previously evicted pages
|
||||
workingset_refault_anon
|
||||
Number of refaults of previously evicted anonymous pages.
|
||||
|
||||
workingset_activate
|
||||
Number of refaulted pages that were immediately activated
|
||||
workingset_refault_file
|
||||
Number of refaults of previously evicted file pages.
|
||||
|
||||
workingset_restore
|
||||
Number of restored pages which have been detected as an active
|
||||
workingset before they got reclaimed.
|
||||
workingset_activate_anon
|
||||
Number of refaulted anonymous pages that were immediately
|
||||
activated.
|
||||
|
||||
workingset_activate_file
|
||||
Number of refaulted file pages that were immediately activated.
|
||||
|
||||
workingset_restore_anon
|
||||
Number of restored anonymous pages which have been detected as
|
||||
an active workingset before they got reclaimed.
|
||||
|
||||
workingset_restore_file
|
||||
Number of restored file pages which have been detected as an
|
||||
active workingset before they got reclaimed.
|
||||
|
||||
workingset_nodereclaim
|
||||
Number of times a shadow node has been reclaimed
|
||||
|
|
|
@ -67,7 +67,7 @@ Parameters::
|
|||
the value passed in <key_size>.
|
||||
|
||||
<key_type>
|
||||
Either 'logon' or 'user' kernel key type.
|
||||
Either 'logon', 'user' or 'encrypted' kernel key type.
|
||||
|
||||
<key_description>
|
||||
The kernel keyring key description crypt target should look for
|
||||
|
@ -121,6 +121,14 @@ submit_from_crypt_cpus
|
|||
thread because it benefits CFQ to have writes submitted using the
|
||||
same context.
|
||||
|
||||
no_read_workqueue
|
||||
Bypass dm-crypt internal workqueue and process read requests synchronously.
|
||||
|
||||
no_write_workqueue
|
||||
Bypass dm-crypt internal workqueue and process write requests synchronously.
|
||||
This option is automatically enabled for host-managed zoned block devices
|
||||
(e.g. host-managed SMR hard-disks).
|
||||
|
||||
integrity:<bytes>:<type>
|
||||
The device requires additional <bytes> metadata per-sector stored
|
||||
in per-bio integrity structure. This metadata must by provided
|
||||
|
|
|
@ -182,9 +182,6 @@ in the order of reservations, but only after all previous records where
|
|||
already committed. It is thus possible for slow producers to temporarily hold
|
||||
off submitted records, that were reserved later.
|
||||
|
||||
Reservation/commit/consumer protocol is verified by litmus tests in
|
||||
Documentation/litmus_tests/bpf-rb/_.
|
||||
|
||||
One interesting implementation bit, that significantly simplifies (and thus
|
||||
speeds up as well) implementation of both producers and consumers is how data
|
||||
area is mapped twice contiguously back-to-back in the virtual memory. This
|
||||
|
@ -200,7 +197,7 @@ a self-pacing notifications of new data being availability.
|
|||
being available after commit only if consumer has already caught up right up to
|
||||
the record being committed. If not, consumer still has to catch up and thus
|
||||
will see new data anyways without needing an extra poll notification.
|
||||
Benchmarks (see tools/testing/selftests/bpf/benchs/bench_ringbuf.c_) show that
|
||||
Benchmarks (see tools/testing/selftests/bpf/benchs/bench_ringbufs.c) show that
|
||||
this allows to achieve a very high throughput without having to resort to
|
||||
tricks like "notify only every Nth sample", which are necessary with perf
|
||||
buffer. For extreme cases, when BPF program wants more manual control of
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
* Sony 1/2.5-Inch 8.51Mp CMOS Digital Image Sensor
|
||||
|
||||
The Sony imx274 is a 1/2.5-inch CMOS active pixel digital image sensor with
|
||||
an active array size of 3864H x 2202V. It is programmable through I2C
|
||||
interface. The I2C address is fixed to 0x1a as per sensor data sheet.
|
||||
Image data is sent through MIPI CSI-2, which is configured as 4 lanes
|
||||
at 1440 Mbps.
|
||||
|
||||
|
||||
Required Properties:
|
||||
- compatible: value should be "sony,imx274" for imx274 sensor
|
||||
- reg: I2C bus address of the device
|
||||
|
||||
Optional Properties:
|
||||
- reset-gpios: Sensor reset GPIO
|
||||
- clocks: Reference to the input clock.
|
||||
- clock-names: Should be "inck".
|
||||
- VANA-supply: Sensor 2.8v analog supply.
|
||||
- VDIG-supply: Sensor 1.8v digital core supply.
|
||||
- VDDL-supply: Sensor digital IO 1.2v supply.
|
||||
|
||||
The imx274 device node should contain one 'port' child node with
|
||||
an 'endpoint' subnode. For further reading on port node refer to
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
Example:
|
||||
sensor@1a {
|
||||
compatible = "sony,imx274";
|
||||
reg = <0x1a>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reset-gpios = <&gpio_sensor 0 0>;
|
||||
port {
|
||||
sensor_out: endpoint {
|
||||
remote-endpoint = <&csiss_in>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/sony,imx274.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sony 1/2.5-Inch 8.51MP CMOS Digital Image Sensor
|
||||
|
||||
maintainers:
|
||||
- Leon Luo <leonl@leopardimaging.com>
|
||||
|
||||
description: |
|
||||
The Sony IMX274 is a 1/2.5-inch CMOS active pixel digital image sensor with an
|
||||
active array size of 3864H x 2202V. It is programmable through I2C interface.
|
||||
Image data is sent through MIPI CSI-2, which is configured as 4 lanes at 1440
|
||||
Mbps.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sony,imx274
|
||||
|
||||
reg:
|
||||
const: 0x1a
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: inck
|
||||
|
||||
vana-supply:
|
||||
description: Sensor 2.8 V analog supply.
|
||||
maxItems: 1
|
||||
|
||||
vdig-supply:
|
||||
description: Sensor 1.8 V digital core supply.
|
||||
maxItems: 1
|
||||
|
||||
vddl-supply:
|
||||
description: Sensor digital IO 1.2 V supply.
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
type: object
|
||||
description: Output video port. See ../video-interfaces.txt.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
imx274: camera-sensor@1a {
|
||||
compatible = "sony,imx274";
|
||||
reg = <0x1a>;
|
||||
reset-gpios = <&gpio_sensor 0 0>;
|
||||
|
||||
port {
|
||||
sensor_out: endpoint {
|
||||
remote-endpoint = <&csiss_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -22,7 +22,7 @@
|
|||
| nios2: | TODO |
|
||||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| powerpc: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | ok |
|
||||
| sh: | TODO |
|
||||
|
|
|
@ -39,10 +39,10 @@ which can help simplify cross compiling. ::
|
|||
ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make CC=clang
|
||||
|
||||
``CROSS_COMPILE`` is not used to prefix the Clang compiler binary, instead
|
||||
``CROSS_COMPILE`` is used to set a command line flag: ``--target <triple>``. For
|
||||
``CROSS_COMPILE`` is used to set a command line flag: ``--target=<triple>``. For
|
||||
example: ::
|
||||
|
||||
clang --target aarch64-linux-gnu foo.c
|
||||
clang --target=aarch64-linux-gnu foo.c
|
||||
|
||||
LLVM Utilities
|
||||
--------------
|
||||
|
|
|
@ -206,6 +206,7 @@ Userspace to kernel:
|
|||
``ETHTOOL_MSG_TSINFO_GET`` get timestamping info
|
||||
``ETHTOOL_MSG_CABLE_TEST_ACT`` action start cable test
|
||||
``ETHTOOL_MSG_CABLE_TEST_TDR_ACT`` action start raw TDR cable test
|
||||
``ETHTOOL_MSG_TUNNEL_INFO_GET`` get tunnel offload info
|
||||
===================================== ================================
|
||||
|
||||
Kernel to userspace:
|
||||
|
@ -239,6 +240,7 @@ Kernel to userspace:
|
|||
``ETHTOOL_MSG_TSINFO_GET_REPLY`` timestamping info
|
||||
``ETHTOOL_MSG_CABLE_TEST_NTF`` Cable test results
|
||||
``ETHTOOL_MSG_CABLE_TEST_TDR_NTF`` Cable test TDR results
|
||||
``ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY`` tunnel offload info
|
||||
===================================== =================================
|
||||
|
||||
``GET`` requests are sent by userspace applications to retrieve device
|
||||
|
@ -1363,4 +1365,5 @@ are netlink only.
|
|||
``ETHTOOL_SFECPARAM`` n/a
|
||||
n/a ''ETHTOOL_MSG_CABLE_TEST_ACT''
|
||||
n/a ''ETHTOOL_MSG_CABLE_TEST_TDR_ACT''
|
||||
n/a ``ETHTOOL_MSG_TUNNEL_INFO_GET``
|
||||
=================================== =====================================
|
||||
|
|
|
@ -701,23 +701,6 @@ Memory Consistency Flags
|
|||
:stub-columns: 0
|
||||
:widths: 3 1 4
|
||||
|
||||
* .. _`V4L2-FLAG-MEMORY-NON-CONSISTENT`:
|
||||
|
||||
- ``V4L2_FLAG_MEMORY_NON_CONSISTENT``
|
||||
- 0x00000001
|
||||
- A buffer is allocated either in consistent (it will be automatically
|
||||
coherent between the CPU and the bus) or non-consistent memory. The
|
||||
latter can provide performance gains, for instance the CPU cache
|
||||
sync/flush operations can be avoided if the buffer is accessed by the
|
||||
corresponding device only and the CPU does not read/write to/from that
|
||||
buffer. However, this requires extra care from the driver -- it must
|
||||
guarantee memory consistency by issuing a cache flush/sync when
|
||||
consistency is needed. If this flag is set V4L2 will attempt to
|
||||
allocate the buffer in non-consistent memory. The flag takes effect
|
||||
only if the buffer is used for :ref:`memory mapping <mmap>` I/O and the
|
||||
queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
|
||||
<V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS>` capability.
|
||||
|
||||
.. c:type:: v4l2_memory
|
||||
|
||||
enum v4l2_memory
|
||||
|
|
|
@ -120,13 +120,9 @@ than the number requested.
|
|||
If you want to just query the capabilities without making any
|
||||
other changes, then set ``count`` to 0, ``memory`` to
|
||||
``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type.
|
||||
* - __u32
|
||||
- ``flags``
|
||||
- Specifies additional buffer management attributes.
|
||||
See :ref:`memory-flags`.
|
||||
|
||||
* - __u32
|
||||
- ``reserved``\ [6]
|
||||
- ``reserved``\ [7]
|
||||
- A place holder for future extensions. Drivers and applications
|
||||
must set the array to zero.
|
||||
|
||||
|
|
|
@ -112,17 +112,10 @@ aborting or finishing any DMA in progress, an implicit
|
|||
``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will
|
||||
free any previously allocated buffers, so this is typically something
|
||||
that will be done at the start of the application.
|
||||
* - union {
|
||||
- (anonymous)
|
||||
* - __u32
|
||||
- ``flags``
|
||||
- Specifies additional buffer management attributes.
|
||||
See :ref:`memory-flags`.
|
||||
* - __u32
|
||||
- ``reserved``\ [1]
|
||||
- Kept for backwards compatibility. Use ``flags`` instead.
|
||||
* - }
|
||||
-
|
||||
- A place holder for future extensions. Drivers and applications
|
||||
must set the array to zero.
|
||||
|
||||
.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}|
|
||||
|
||||
|
@ -169,7 +162,6 @@ aborting or finishing any DMA in progress, an implicit
|
|||
- This capability is set by the driver to indicate that the queue supports
|
||||
cache and memory management hints. However, it's only valid when the
|
||||
queue is used for :ref:`memory mapping <mmap>` streaming I/O. See
|
||||
:ref:`V4L2_FLAG_MEMORY_NON_CONSISTENT <V4L2-FLAG-MEMORY-NON-CONSISTENT>`,
|
||||
:ref:`V4L2_BUF_FLAG_NO_CACHE_INVALIDATE <V4L2-BUF-FLAG-NO-CACHE-INVALIDATE>` and
|
||||
:ref:`V4L2_BUF_FLAG_NO_CACHE_CLEAN <V4L2-BUF-FLAG-NO-CACHE-CLEAN>`.
|
||||
|
||||
|
|
|
@ -6173,3 +6173,23 @@ specific interfaces must be consistent, i.e. if one says the feature
|
|||
is supported, than the other should as well and vice versa. For arm64
|
||||
see Documentation/virt/kvm/devices/vcpu.rst "KVM_ARM_VCPU_PVTIME_CTRL".
|
||||
For x86 see Documentation/virt/kvm/msr.rst "MSR_KVM_STEAL_TIME".
|
||||
|
||||
8.25 KVM_CAP_S390_DIAG318
|
||||
-------------------------
|
||||
|
||||
:Architectures: s390
|
||||
|
||||
This capability enables a guest to set information about its control program
|
||||
(i.e. guest kernel type and version). The information is helpful during
|
||||
system/firmware service events, providing additional data about the guest
|
||||
environments running on the machine.
|
||||
|
||||
The information is associated with the DIAGNOSE 0x318 instruction, which sets
|
||||
an 8-byte value consisting of a one-byte Control Program Name Code (CPNC) and
|
||||
a 7-byte Control Program Version Code (CPVC). The CPNC determines what
|
||||
environment the control program is running in (e.g. Linux, z/VM...), and the
|
||||
CPVC is used for information specific to OS (e.g. Linux version, Linux
|
||||
distribution...)
|
||||
|
||||
If this capability is available, then the CPNC and CPVC can be synchronized
|
||||
between KVM and userspace via the sync regs mechanism (KVM_SYNC_DIAG318).
|
||||
|
|
17
MAINTAINERS
17
MAINTAINERS
|
@ -4408,12 +4408,6 @@ T: git git://git.infradead.org/users/hch/configfs.git
|
|||
F: fs/configfs/
|
||||
F: include/linux/configfs.h
|
||||
|
||||
CONNECTOR
|
||||
M: Evgeniy Polyakov <zbr@ioremap.net>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/connector/
|
||||
|
||||
CONSOLE SUBSYSTEM
|
||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
S: Supported
|
||||
|
@ -8329,8 +8323,9 @@ S: Supported
|
|||
F: drivers/pci/hotplug/rpaphp*
|
||||
|
||||
IBM Power SRIOV Virtual NIC Device Driver
|
||||
M: Thomas Falcon <tlfalcon@linux.ibm.com>
|
||||
M: John Allen <jallen@linux.ibm.com>
|
||||
M: Dany Madden <drt@linux.ibm.com>
|
||||
M: Lijun Pan <ljp@linux.ibm.com>
|
||||
M: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/ibm/ibmvnic.*
|
||||
|
@ -8344,7 +8339,7 @@ F: arch/powerpc/platforms/powernv/copy-paste.h
|
|||
F: arch/powerpc/platforms/powernv/vas*
|
||||
|
||||
IBM Power Virtual Ethernet Device Driver
|
||||
M: Thomas Falcon <tlfalcon@linux.ibm.com>
|
||||
M: Cristobal Forno <cforno12@linux.ibm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/ibm/ibmveth.*
|
||||
|
@ -11042,6 +11037,7 @@ F: drivers/char/hw_random/mtk-rng.c
|
|||
|
||||
MEDIATEK SWITCH DRIVER
|
||||
M: Sean Wang <sean.wang@mediatek.com>
|
||||
M: Landen Chao <Landen.Chao@mediatek.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/dsa/mt7530.*
|
||||
|
@ -12055,6 +12051,7 @@ Q: http://patchwork.ozlabs.org/project/netdev/list/
|
|||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
|
||||
F: Documentation/devicetree/bindings/net/
|
||||
F: drivers/connector/
|
||||
F: drivers/net/
|
||||
F: include/linux/etherdevice.h
|
||||
F: include/linux/fcdevice.h
|
||||
|
@ -16157,7 +16154,7 @@ M: Leon Luo <leonl@leopardimaging.com>
|
|||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/imx274.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx274.yaml
|
||||
F: drivers/media/i2c/imx274.c
|
||||
|
||||
SONY IMX290 SENSOR DRIVER
|
||||
|
|
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
|||
VERSION = 5
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -116,7 +116,6 @@
|
|||
switch0: ksz8563@0 {
|
||||
compatible = "microchip,ksz8563";
|
||||
reg = <0>;
|
||||
phy-mode = "mii";
|
||||
reset-gpios = <&pioA PIN_PD4 GPIO_ACTIVE_LOW>;
|
||||
|
||||
spi-max-frequency = <500000>;
|
||||
|
@ -140,6 +139,7 @@
|
|||
reg = <2>;
|
||||
label = "cpu";
|
||||
ethernet = <&macb0>;
|
||||
phy-mode = "mii";
|
||||
fixed-link {
|
||||
speed = <100>;
|
||||
full-duplex;
|
||||
|
|
|
@ -298,15 +298,15 @@ static __always_inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu)
|
|||
return (kvm_vcpu_get_esr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT;
|
||||
}
|
||||
|
||||
static __always_inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu)
|
||||
static __always_inline bool kvm_vcpu_abt_iss1tw(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_S1PTW);
|
||||
}
|
||||
|
||||
/* Always check for S1PTW *before* using this. */
|
||||
static __always_inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_WNR) ||
|
||||
kvm_vcpu_dabt_iss1tw(vcpu); /* AF/DBM update */
|
||||
return kvm_vcpu_get_esr(vcpu) & ESR_ELx_WNR;
|
||||
}
|
||||
|
||||
static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu)
|
||||
|
@ -335,6 +335,11 @@ static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu)
|
|||
return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_IABT_LOW;
|
||||
}
|
||||
|
||||
static inline bool kvm_vcpu_trap_is_exec_fault(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return kvm_vcpu_trap_is_iabt(vcpu) && !kvm_vcpu_abt_iss1tw(vcpu);
|
||||
}
|
||||
|
||||
static __always_inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return kvm_vcpu_get_esr(vcpu) & ESR_ELx_FSC;
|
||||
|
@ -372,6 +377,9 @@ static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
|
|||
|
||||
static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (kvm_vcpu_abt_iss1tw(vcpu))
|
||||
return true;
|
||||
|
||||
if (kvm_vcpu_trap_is_iabt(vcpu))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -910,8 +910,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
|
|||
.desc = "ARM erratum 1418040",
|
||||
.capability = ARM64_WORKAROUND_1418040,
|
||||
ERRATA_MIDR_RANGE_LIST(erratum_1418040_list),
|
||||
.type = (ARM64_CPUCAP_SCOPE_LOCAL_CPU |
|
||||
ARM64_CPUCAP_PERMITTED_FOR_LATE_CPU),
|
||||
/*
|
||||
* We need to allow affected CPUs to come in late, but
|
||||
* also need the non-affected CPUs to be able to come
|
||||
* in at any point in time. Wonderful.
|
||||
*/
|
||||
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT
|
||||
|
|
|
@ -50,16 +50,19 @@ static u64 pv_steal_clock(int cpu)
|
|||
struct pv_time_stolen_time_region *reg;
|
||||
|
||||
reg = per_cpu_ptr(&stolen_time_region, cpu);
|
||||
if (!reg->kaddr) {
|
||||
pr_warn_once("stolen time enabled but not configured for cpu %d\n",
|
||||
cpu);
|
||||
|
||||
/*
|
||||
* paravirt_steal_clock() may be called before the CPU
|
||||
* online notification callback runs. Until the callback
|
||||
* has run we just return zero.
|
||||
*/
|
||||
if (!reg->kaddr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return le64_to_cpu(READ_ONCE(reg->kaddr->stolen_time));
|
||||
}
|
||||
|
||||
static int stolen_time_dying_cpu(unsigned int cpu)
|
||||
static int stolen_time_cpu_down_prepare(unsigned int cpu)
|
||||
{
|
||||
struct pv_time_stolen_time_region *reg;
|
||||
|
||||
|
@ -73,7 +76,7 @@ static int stolen_time_dying_cpu(unsigned int cpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int init_stolen_time_cpu(unsigned int cpu)
|
||||
static int stolen_time_cpu_online(unsigned int cpu)
|
||||
{
|
||||
struct pv_time_stolen_time_region *reg;
|
||||
struct arm_smccc_res res;
|
||||
|
@ -103,19 +106,20 @@ static int init_stolen_time_cpu(unsigned int cpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pv_time_init_stolen_time(void)
|
||||
static int __init pv_time_init_stolen_time(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cpuhp_setup_state(CPUHP_AP_ARM_KVMPV_STARTING,
|
||||
"hypervisor/arm/pvtime:starting",
|
||||
init_stolen_time_cpu, stolen_time_dying_cpu);
|
||||
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
|
||||
"hypervisor/arm/pvtime:online",
|
||||
stolen_time_cpu_online,
|
||||
stolen_time_cpu_down_prepare);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool has_pv_steal_clock(void)
|
||||
static bool __init has_pv_steal_clock(void)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
|
|
|
@ -449,7 +449,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
|
|||
kvm_vcpu_trap_get_fault_type(vcpu) == FSC_FAULT &&
|
||||
kvm_vcpu_dabt_isvalid(vcpu) &&
|
||||
!kvm_vcpu_abt_issea(vcpu) &&
|
||||
!kvm_vcpu_dabt_iss1tw(vcpu);
|
||||
!kvm_vcpu_abt_iss1tw(vcpu);
|
||||
|
||||
if (valid) {
|
||||
int ret = __vgic_v2_perform_cpuif_access(vcpu);
|
||||
|
|
|
@ -1849,7 +1849,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
|
|||
struct kvm_s2_mmu *mmu = vcpu->arch.hw_mmu;
|
||||
|
||||
write_fault = kvm_is_write_fault(vcpu);
|
||||
exec_fault = kvm_vcpu_trap_is_iabt(vcpu);
|
||||
exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu);
|
||||
VM_BUG_ON(write_fault && exec_fault);
|
||||
|
||||
if (fault_status == FSC_PERM && !write_fault && !exec_fault) {
|
||||
|
@ -2131,7 +2131,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (kvm_vcpu_dabt_iss1tw(vcpu)) {
|
||||
if (kvm_vcpu_abt_iss1tw(vcpu)) {
|
||||
kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
|
||||
ret = 1;
|
||||
goto out_unlock;
|
||||
|
|
|
@ -143,14 +143,17 @@ static inline void emit_addr_mov_i64(const int reg, const u64 val,
|
|||
}
|
||||
}
|
||||
|
||||
static inline int bpf2a64_offset(int bpf_to, int bpf_from,
|
||||
static inline int bpf2a64_offset(int bpf_insn, int off,
|
||||
const struct jit_ctx *ctx)
|
||||
{
|
||||
int to = ctx->offset[bpf_to];
|
||||
/* -1 to account for the Branch instruction */
|
||||
int from = ctx->offset[bpf_from] - 1;
|
||||
|
||||
return to - from;
|
||||
/* BPF JMP offset is relative to the next instruction */
|
||||
bpf_insn++;
|
||||
/*
|
||||
* Whereas arm64 branch instructions encode the offset
|
||||
* from the branch itself, so we must subtract 1 from the
|
||||
* instruction offset.
|
||||
*/
|
||||
return ctx->offset[bpf_insn + off] - (ctx->offset[bpf_insn] - 1);
|
||||
}
|
||||
|
||||
static void jit_fill_hole(void *area, unsigned int size)
|
||||
|
@ -642,7 +645,7 @@ emit_bswap_uxt:
|
|||
|
||||
/* JUMP off */
|
||||
case BPF_JMP | BPF_JA:
|
||||
jmp_offset = bpf2a64_offset(i + off, i, ctx);
|
||||
jmp_offset = bpf2a64_offset(i, off, ctx);
|
||||
check_imm26(jmp_offset);
|
||||
emit(A64_B(jmp_offset), ctx);
|
||||
break;
|
||||
|
@ -669,7 +672,7 @@ emit_bswap_uxt:
|
|||
case BPF_JMP32 | BPF_JSLE | BPF_X:
|
||||
emit(A64_CMP(is64, dst, src), ctx);
|
||||
emit_cond_jmp:
|
||||
jmp_offset = bpf2a64_offset(i + off, i, ctx);
|
||||
jmp_offset = bpf2a64_offset(i, off, ctx);
|
||||
check_imm19(jmp_offset);
|
||||
switch (BPF_OP(code)) {
|
||||
case BPF_JEQ:
|
||||
|
@ -908,10 +911,21 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
|
|||
const struct bpf_prog *prog = ctx->prog;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* - offset[0] offset of the end of prologue,
|
||||
* start of the 1st instruction.
|
||||
* - offset[1] - offset of the end of 1st instruction,
|
||||
* start of the 2nd instruction
|
||||
* [....]
|
||||
* - offset[3] - offset of the end of 3rd instruction,
|
||||
* start of 4th instruction
|
||||
*/
|
||||
for (i = 0; i < prog->len; i++) {
|
||||
const struct bpf_insn *insn = &prog->insnsi[i];
|
||||
int ret;
|
||||
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
ret = build_insn(insn, ctx, extra_pass);
|
||||
if (ret > 0) {
|
||||
i++;
|
||||
|
@ -919,11 +933,16 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
|
|||
ctx->offset[i] = ctx->idx;
|
||||
continue;
|
||||
}
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* offset is allocated with prog->len + 1 so fill in
|
||||
* the last element with the offset after the last
|
||||
* instruction (end of program)
|
||||
*/
|
||||
if (ctx->image == NULL)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1002,7 +1021,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
|||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.prog = prog;
|
||||
|
||||
ctx.offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL);
|
||||
ctx.offset = kcalloc(prog->len + 1, sizeof(int), GFP_KERNEL);
|
||||
if (ctx.offset == NULL) {
|
||||
prog = orig_prog;
|
||||
goto out_off;
|
||||
|
@ -1089,7 +1108,7 @@ skip_init_ctx:
|
|||
prog->jited_len = prog_size;
|
||||
|
||||
if (!prog->is_func || extra_pass) {
|
||||
bpf_prog_fill_jited_linfo(prog, ctx.offset);
|
||||
bpf_prog_fill_jited_linfo(prog, ctx.offset + 1);
|
||||
out_off:
|
||||
kfree(ctx.offset);
|
||||
kfree(jit_data);
|
||||
|
|
|
@ -74,8 +74,6 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf)
|
|||
buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
|
||||
}
|
||||
|
||||
#define acpi_unlazy_tlb(x)
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
extern cpumask_t early_cpu_possible_map;
|
||||
#define for_each_possible_early_cpu(cpu) \
|
||||
|
|
|
@ -538,7 +538,7 @@ virtual_memmap_init(u64 start, u64 end, void *arg)
|
|||
if (map_start < map_end)
|
||||
memmap_init_zone((unsigned long)(map_end - map_start),
|
||||
args->nid, args->zone, page_to_pfn(map_start),
|
||||
MEMMAP_EARLY, NULL);
|
||||
MEMINIT_EARLY, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -547,8 +547,8 @@ memmap_init (unsigned long size, int nid, unsigned long zone,
|
|||
unsigned long start_pfn)
|
||||
{
|
||||
if (!vmem_map) {
|
||||
memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY,
|
||||
NULL);
|
||||
memmap_init_zone(size, nid, zone, start_pfn,
|
||||
MEMINIT_EARLY, NULL);
|
||||
} else {
|
||||
struct page *start;
|
||||
struct memmap_init_callback_data args;
|
||||
|
|
|
@ -877,6 +877,7 @@ config SNI_RM
|
|||
select I8253
|
||||
select I8259
|
||||
select ISA
|
||||
select MIPS_L1_CACHE_SHIFT_6
|
||||
select SWAP_IO_SPACE if CPU_BIG_ENDIAN
|
||||
select SYS_HAS_CPU_R4X00
|
||||
select SYS_HAS_CPU_R5000
|
||||
|
|
|
@ -148,7 +148,7 @@ void __init plat_mem_setup(void)
|
|||
{
|
||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||
|
||||
if ((c->cputype == CPU_74K) || (c->cputype == CPU_1074K)) {
|
||||
if (c->cputype == CPU_74K) {
|
||||
pr_info("Using bcma bus\n");
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
|
||||
|
|
|
@ -47,6 +47,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
|||
case CPU_34K:
|
||||
case CPU_1004K:
|
||||
case CPU_74K:
|
||||
case CPU_1074K:
|
||||
case CPU_M14KC:
|
||||
case CPU_M14KEC:
|
||||
case CPU_INTERAPTIV:
|
||||
|
|
|
@ -44,6 +44,10 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
|
|||
endif
|
||||
endif
|
||||
|
||||
# Some -march= flags enable MMI instructions, and GCC complains about that
|
||||
# support being enabled alongside -msoft-float. Thus explicitly disable MMI.
|
||||
cflags-y += $(call cc-option,-mno-loongson-mmi)
|
||||
|
||||
#
|
||||
# Loongson Machines' Support
|
||||
#
|
||||
|
|
|
@ -95,10 +95,8 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
|
|||
if (res)
|
||||
goto fault;
|
||||
|
||||
set_fpr64(current->thread.fpu.fpr,
|
||||
insn.loongson3_lswc2_format.rt, value);
|
||||
set_fpr64(current->thread.fpu.fpr,
|
||||
insn.loongson3_lswc2_format.rq, value_next);
|
||||
set_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lswc2_format.rt], 0, value);
|
||||
set_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lswc2_format.rq], 0, value_next);
|
||||
compute_return_epc(regs);
|
||||
own_fpu(1);
|
||||
}
|
||||
|
@ -130,15 +128,13 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
|
|||
goto sigbus;
|
||||
|
||||
lose_fpu(1);
|
||||
value_next = get_fpr64(current->thread.fpu.fpr,
|
||||
insn.loongson3_lswc2_format.rq);
|
||||
value_next = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lswc2_format.rq], 0);
|
||||
|
||||
StoreDW(addr + 8, value_next, res);
|
||||
if (res)
|
||||
goto fault;
|
||||
|
||||
value = get_fpr64(current->thread.fpu.fpr,
|
||||
insn.loongson3_lswc2_format.rt);
|
||||
value = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lswc2_format.rt], 0);
|
||||
|
||||
StoreDW(addr, value, res);
|
||||
if (res)
|
||||
|
@ -204,8 +200,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
|
|||
if (res)
|
||||
goto fault;
|
||||
|
||||
set_fpr64(current->thread.fpu.fpr,
|
||||
insn.loongson3_lsdc2_format.rt, value);
|
||||
set_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0, value);
|
||||
compute_return_epc(regs);
|
||||
own_fpu(1);
|
||||
|
||||
|
@ -221,8 +216,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
|
|||
if (res)
|
||||
goto fault;
|
||||
|
||||
set_fpr64(current->thread.fpu.fpr,
|
||||
insn.loongson3_lsdc2_format.rt, value);
|
||||
set_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0, value);
|
||||
compute_return_epc(regs);
|
||||
own_fpu(1);
|
||||
break;
|
||||
|
@ -286,8 +280,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
|
|||
goto sigbus;
|
||||
|
||||
lose_fpu(1);
|
||||
value = get_fpr64(current->thread.fpu.fpr,
|
||||
insn.loongson3_lsdc2_format.rt);
|
||||
value = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0);
|
||||
|
||||
StoreW(addr, value, res);
|
||||
if (res)
|
||||
|
@ -305,8 +298,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
|
|||
goto sigbus;
|
||||
|
||||
lose_fpu(1);
|
||||
value = get_fpr64(current->thread.fpu.fpr,
|
||||
insn.loongson3_lsdc2_format.rt);
|
||||
value = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0);
|
||||
|
||||
StoreDW(addr, value, res);
|
||||
if (res)
|
||||
|
|
|
@ -143,7 +143,10 @@ static struct platform_device sc26xx_pdev = {
|
|||
},
|
||||
};
|
||||
|
||||
static u32 a20r_ack_hwint(void)
|
||||
/*
|
||||
* Trigger chipset to update CPU's CAUSE IP field
|
||||
*/
|
||||
static u32 a20r_update_cause_ip(void)
|
||||
{
|
||||
u32 status = read_c0_status();
|
||||
|
||||
|
@ -205,12 +208,14 @@ static void a20r_hwint(void)
|
|||
int irq;
|
||||
|
||||
clear_c0_status(IE_IRQ0);
|
||||
status = a20r_ack_hwint();
|
||||
status = a20r_update_cause_ip();
|
||||
cause = read_c0_cause();
|
||||
|
||||
irq = ffs(((cause & status) >> 8) & 0xf8);
|
||||
if (likely(irq > 0))
|
||||
do_IRQ(SNI_A20R_IRQ_BASE + irq - 1);
|
||||
|
||||
a20r_update_cause_ip();
|
||||
set_c0_status(IE_IRQ0);
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,6 @@ config PPC
|
|||
#
|
||||
select ARCH_32BIT_OFF_T if PPC32
|
||||
select ARCH_HAS_DEBUG_VIRTUAL
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DEVMEM_IS_ALLOWED
|
||||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
select ARCH_HAS_FORTIFY_SOURCE
|
||||
|
|
|
@ -239,14 +239,14 @@ static inline void early_init_mmu_secondary(void)
|
|||
|
||||
extern void hash__setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
||||
phys_addr_t first_memblock_size);
|
||||
extern void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
||||
phys_addr_t first_memblock_size);
|
||||
static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
||||
phys_addr_t first_memblock_size)
|
||||
{
|
||||
if (early_radix_enabled())
|
||||
return radix__setup_initial_memory_limit(first_memblock_base,
|
||||
first_memblock_size);
|
||||
/*
|
||||
* Hash has more strict restrictions. At this point we don't
|
||||
* know which translations we will pick. Hence go with hash
|
||||
* restrictions.
|
||||
*/
|
||||
return hash__setup_initial_memory_limit(first_memblock_base,
|
||||
first_memblock_size);
|
||||
}
|
||||
|
|
|
@ -120,7 +120,8 @@ u64 dma_iommu_get_required_mask(struct device *dev)
|
|||
if (!tbl)
|
||||
return 0;
|
||||
|
||||
mask = 1ULL < (fls_long(tbl->it_offset + tbl->it_size) - 1);
|
||||
mask = 1ULL << (fls_long(tbl->it_offset + tbl->it_size) +
|
||||
tbl->it_page_shift - 1);
|
||||
mask += mask - 1;
|
||||
|
||||
return mask;
|
||||
|
|
|
@ -50,7 +50,7 @@ $(obj-vdso32): %.o: %.S FORCE
|
|||
|
||||
# actual build commands
|
||||
quiet_cmd_vdso32ld = VDSO32L $@
|
||||
cmd_vdso32ld = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ $(call cc-ldoption, -Wl$(comma)--orphan-handling=warn) -Wl,-T$(filter %.lds,$^) $(filter %.o,$^)
|
||||
cmd_vdso32ld = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^)
|
||||
quiet_cmd_vdso32as = VDSO32A $@
|
||||
cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) -c -o $@ $<
|
||||
|
||||
|
|
|
@ -111,7 +111,6 @@ SECTIONS
|
|||
*(.note.GNU-stack)
|
||||
*(.data .data.* .gnu.linkonce.d.* .sdata*)
|
||||
*(.bss .sbss .dynbss .dynsbss)
|
||||
*(.glink .iplt .plt .rela*)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
|
|||
|
||||
# actual build commands
|
||||
quiet_cmd_vdso64ld = VDSO64L $@
|
||||
cmd_vdso64ld = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) $(call cc-ldoption, -Wl$(comma)--orphan-handling=warn)
|
||||
cmd_vdso64ld = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^)
|
||||
|
||||
# install commands for the unstripped file
|
||||
quiet_cmd_vdso_install = INSTALL $@
|
||||
|
|
|
@ -30,7 +30,7 @@ SECTIONS
|
|||
. = ALIGN(16);
|
||||
.text : {
|
||||
*(.text .stub .text.* .gnu.linkonce.t.* __ftr_alt_*)
|
||||
*(.sfpr)
|
||||
*(.sfpr .glink)
|
||||
} :text
|
||||
PROVIDE(__etext = .);
|
||||
PROVIDE(_etext = .);
|
||||
|
@ -111,7 +111,6 @@ SECTIONS
|
|||
*(.branch_lt)
|
||||
*(.data .data.* .gnu.linkonce.d.* .sdata*)
|
||||
*(.bss .sbss .dynbss .dynsbss)
|
||||
*(.glink .iplt .plt .rela*)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -734,21 +734,6 @@ void radix__mmu_cleanup_all(void)
|
|||
}
|
||||
}
|
||||
|
||||
void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
||||
phys_addr_t first_memblock_size)
|
||||
{
|
||||
/*
|
||||
* We don't currently support the first MEMBLOCK not mapping 0
|
||||
* physical on those processors
|
||||
*/
|
||||
BUG_ON(first_memblock_base != 0);
|
||||
|
||||
/*
|
||||
* Radix mode is not limited by RMA / VRMA addressing.
|
||||
*/
|
||||
ppc64_rma_size = ULONG_MAX;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
static void free_pte_table(pte_t *pte_start, pmd_t *pmd)
|
||||
{
|
||||
|
|
|
@ -433,9 +433,16 @@ void __init mmu_early_init_devtree(void)
|
|||
if (!(mfmsr() & MSR_HV))
|
||||
early_check_vec5();
|
||||
|
||||
if (early_radix_enabled())
|
||||
if (early_radix_enabled()) {
|
||||
radix__early_init_devtree();
|
||||
else
|
||||
/*
|
||||
* We have finalized the translation we are going to use by now.
|
||||
* Radix mode is not limited by RMA / VRMA addressing.
|
||||
* Hence don't limit memblock allocations.
|
||||
*/
|
||||
ppc64_rma_size = ULONG_MAX;
|
||||
memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
|
||||
} else
|
||||
hash__early_init_devtree();
|
||||
}
|
||||
#endif /* CONFIG_PPC_BOOK3S_64 */
|
||||
|
|
|
@ -822,7 +822,7 @@ free_stats:
|
|||
kfree(stats);
|
||||
return rc ? rc : seq_buf_used(&s);
|
||||
}
|
||||
DEVICE_ATTR_RO(perf_stats);
|
||||
DEVICE_ATTR_ADMIN_RO(perf_stats);
|
||||
|
||||
static ssize_t flags_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
|
|
|
@ -32,6 +32,7 @@ config RISCV
|
|||
select ARCH_WANT_FRAME_POINTERS
|
||||
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
|
||||
select CLONE_BACKWARDS
|
||||
select CLINT_TIMER if !MMU
|
||||
select COMMON_CLK
|
||||
select EDAC_SUPPORT
|
||||
select GENERIC_ARCH_TOPOLOGY if SMP
|
||||
|
|
|
@ -95,10 +95,12 @@
|
|||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
clint0: interrupt-controller@2000000 {
|
||||
clint0: clint@2000000 {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,clint0";
|
||||
reg = <0x2000000 0xC000>;
|
||||
interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>;
|
||||
interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
|
||||
&cpu1_intc 3 &cpu1_intc 7>;
|
||||
clocks = <&sysctl K210_CLK_ACLK>;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020 Google, Inc
|
||||
*/
|
||||
|
||||
#ifndef _ASM_RISCV_CLINT_H
|
||||
#define _ASM_RISCV_CLINT_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/mmio.h>
|
||||
|
||||
#ifdef CONFIG_RISCV_M_MODE
|
||||
/*
|
||||
* This lives in the CLINT driver, but is accessed directly by timex.h to avoid
|
||||
* any overhead when accessing the MMIO timer.
|
||||
*
|
||||
* The ISA defines mtime as a 64-bit memory-mapped register that increments at
|
||||
* a constant frequency, but it doesn't define some other constraints we depend
|
||||
* on (most notably ordering constraints, but also some simpler stuff like the
|
||||
* memory layout). Thus, this is called "clint_time_val" instead of something
|
||||
* like "riscv_mtime", to signify that these non-ISA assumptions must hold.
|
||||
*/
|
||||
extern u64 __iomem *clint_time_val;
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -66,6 +66,13 @@ do { \
|
|||
* Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here.
|
||||
*/
|
||||
#define MCOUNT_INSN_SIZE 8
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
struct dyn_ftrace;
|
||||
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
|
||||
#define ftrace_init_nop ftrace_init_nop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_RISCV_FTRACE_H */
|
||||
|
|
|
@ -10,6 +10,31 @@
|
|||
|
||||
typedef unsigned long cycles_t;
|
||||
|
||||
#ifdef CONFIG_RISCV_M_MODE
|
||||
|
||||
#include <asm/clint.h>
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
static inline cycles_t get_cycles(void)
|
||||
{
|
||||
return readq_relaxed(clint_time_val);
|
||||
}
|
||||
#else /* !CONFIG_64BIT */
|
||||
static inline u32 get_cycles(void)
|
||||
{
|
||||
return readl_relaxed(((u32 *)clint_time_val));
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
static inline u32 get_cycles_hi(void)
|
||||
{
|
||||
return readl_relaxed(((u32 *)clint_time_val) + 1);
|
||||
}
|
||||
#define get_cycles_hi get_cycles_hi
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
#else /* CONFIG_RISCV_M_MODE */
|
||||
|
||||
static inline cycles_t get_cycles(void)
|
||||
{
|
||||
return csr_read(CSR_TIME);
|
||||
|
@ -41,6 +66,8 @@ static inline u64 get_cycles64(void)
|
|||
}
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
#endif /* !CONFIG_RISCV_M_MODE */
|
||||
|
||||
#define ARCH_HAS_READ_CURRENT_TIMER
|
||||
static inline int read_current_timer(unsigned long *timer_val)
|
||||
{
|
||||
|
|
|
@ -97,6 +97,25 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
|
|||
return __ftrace_modify_call(rec->ip, addr, false);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called early on, and isn't wrapped by
|
||||
* ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold
|
||||
* text_mutex, which triggers a lockdep failure. SMP isn't running so we could
|
||||
* just directly poke the text, but it's simpler to just take the lock
|
||||
* ourselves.
|
||||
*/
|
||||
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
|
||||
{
|
||||
int out;
|
||||
|
||||
ftrace_arch_code_modify_prepare();
|
||||
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
|
||||
ftrace_arch_code_modify_post_process();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int ftrace_update_ftrace_func(ftrace_func_t func)
|
||||
{
|
||||
int ret = __ftrace_modify_call((unsigned long)&ftrace_call,
|
||||
|
|
|
@ -226,12 +226,11 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
|
|||
|
||||
ptep = &fixmap_pte[pte_index(addr)];
|
||||
|
||||
if (pgprot_val(prot)) {
|
||||
if (pgprot_val(prot))
|
||||
set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
|
||||
} else {
|
||||
else
|
||||
pte_clear(&init_mm, addr, ptep);
|
||||
local_flush_tlb_page(addr);
|
||||
}
|
||||
local_flush_tlb_page(addr);
|
||||
}
|
||||
|
||||
static pte_t *__init get_pte_virt(phys_addr_t pa)
|
||||
|
|
|
@ -1260,26 +1260,44 @@ static inline pgd_t *pgd_offset_raw(pgd_t *pgd, unsigned long address)
|
|||
|
||||
#define pgd_offset(mm, address) pgd_offset_raw(READ_ONCE((mm)->pgd), address)
|
||||
|
||||
static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address)
|
||||
static inline p4d_t *p4d_offset_lockless(pgd_t *pgdp, pgd_t pgd, unsigned long address)
|
||||
{
|
||||
if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R1)
|
||||
return (p4d_t *) pgd_deref(*pgd) + p4d_index(address);
|
||||
return (p4d_t *) pgd;
|
||||
if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R1)
|
||||
return (p4d_t *) pgd_deref(pgd) + p4d_index(address);
|
||||
return (p4d_t *) pgdp;
|
||||
}
|
||||
#define p4d_offset_lockless p4d_offset_lockless
|
||||
|
||||
static inline p4d_t *p4d_offset(pgd_t *pgdp, unsigned long address)
|
||||
{
|
||||
return p4d_offset_lockless(pgdp, *pgdp, address);
|
||||
}
|
||||
|
||||
static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
|
||||
static inline pud_t *pud_offset_lockless(p4d_t *p4dp, p4d_t p4d, unsigned long address)
|
||||
{
|
||||
if ((p4d_val(*p4d) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R2)
|
||||
return (pud_t *) p4d_deref(*p4d) + pud_index(address);
|
||||
return (pud_t *) p4d;
|
||||
if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R2)
|
||||
return (pud_t *) p4d_deref(p4d) + pud_index(address);
|
||||
return (pud_t *) p4dp;
|
||||
}
|
||||
#define pud_offset_lockless pud_offset_lockless
|
||||
|
||||
static inline pud_t *pud_offset(p4d_t *p4dp, unsigned long address)
|
||||
{
|
||||
return pud_offset_lockless(p4dp, *p4dp, address);
|
||||
}
|
||||
#define pud_offset pud_offset
|
||||
|
||||
static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
|
||||
static inline pmd_t *pmd_offset_lockless(pud_t *pudp, pud_t pud, unsigned long address)
|
||||
{
|
||||
if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R3)
|
||||
return (pmd_t *) pud_deref(*pud) + pmd_index(address);
|
||||
return (pmd_t *) pud;
|
||||
if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R3)
|
||||
return (pmd_t *) pud_deref(pud) + pmd_index(address);
|
||||
return (pmd_t *) pudp;
|
||||
}
|
||||
#define pmd_offset_lockless pmd_offset_lockless
|
||||
|
||||
static inline pmd_t *pmd_offset(pud_t *pudp, unsigned long address)
|
||||
{
|
||||
return pmd_offset_lockless(pudp, *pudp, address);
|
||||
}
|
||||
#define pmd_offset pmd_offset
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ void do_protection_exception(struct pt_regs *regs);
|
|||
void do_dat_exception(struct pt_regs *regs);
|
||||
void do_secure_storage_access(struct pt_regs *regs);
|
||||
void do_non_secure_storage_access(struct pt_regs *regs);
|
||||
void do_secure_storage_violation(struct pt_regs *regs);
|
||||
|
||||
void addressing_exception(struct pt_regs *regs);
|
||||
void data_exception(struct pt_regs *regs);
|
||||
|
|
|
@ -39,14 +39,13 @@ void enabled_wait(void)
|
|||
local_irq_restore(flags);
|
||||
|
||||
/* Account time spent with enabled wait psw loaded as idle time. */
|
||||
/* XXX seqcount has tracepoints that require RCU */
|
||||
write_seqcount_begin(&idle->seqcount);
|
||||
raw_write_seqcount_begin(&idle->seqcount);
|
||||
idle_time = idle->clock_idle_exit - idle->clock_idle_enter;
|
||||
idle->clock_idle_enter = idle->clock_idle_exit = 0ULL;
|
||||
idle->idle_time += idle_time;
|
||||
idle->idle_count++;
|
||||
account_idle_time(cputime_to_nsecs(idle_time));
|
||||
write_seqcount_end(&idle->seqcount);
|
||||
raw_write_seqcount_end(&idle->seqcount);
|
||||
}
|
||||
NOKPROBE_SYMBOL(enabled_wait);
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ PGM_CHECK(do_dat_exception) /* 3b */
|
|||
PGM_CHECK_DEFAULT /* 3c */
|
||||
PGM_CHECK(do_secure_storage_access) /* 3d */
|
||||
PGM_CHECK(do_non_secure_storage_access) /* 3e */
|
||||
PGM_CHECK_DEFAULT /* 3f */
|
||||
PGM_CHECK(do_secure_storage_violation) /* 3f */
|
||||
PGM_CHECK(monitor_event_exception) /* 40 */
|
||||
PGM_CHECK_DEFAULT /* 41 */
|
||||
PGM_CHECK_DEFAULT /* 42 */
|
||||
|
|
|
@ -619,7 +619,7 @@ static struct notifier_block kdump_mem_nb = {
|
|||
/*
|
||||
* Make sure that the area behind memory_end is protected
|
||||
*/
|
||||
static void reserve_memory_end(void)
|
||||
static void __init reserve_memory_end(void)
|
||||
{
|
||||
if (memory_end_set)
|
||||
memblock_reserve(memory_end, ULONG_MAX);
|
||||
|
@ -628,7 +628,7 @@ static void reserve_memory_end(void)
|
|||
/*
|
||||
* Make sure that oldmem, where the dump is stored, is protected
|
||||
*/
|
||||
static void reserve_oldmem(void)
|
||||
static void __init reserve_oldmem(void)
|
||||
{
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
if (OLDMEM_BASE)
|
||||
|
@ -640,7 +640,7 @@ static void reserve_oldmem(void)
|
|||
/*
|
||||
* Make sure that oldmem, where the dump is stored, is protected
|
||||
*/
|
||||
static void remove_oldmem(void)
|
||||
static void __init remove_oldmem(void)
|
||||
{
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
if (OLDMEM_BASE)
|
||||
|
|
|
@ -859,6 +859,21 @@ void do_non_secure_storage_access(struct pt_regs *regs)
|
|||
}
|
||||
NOKPROBE_SYMBOL(do_non_secure_storage_access);
|
||||
|
||||
void do_secure_storage_violation(struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* Either KVM messed up the secure guest mapping or the same
|
||||
* page is mapped into multiple secure guests.
|
||||
*
|
||||
* This exception is only triggered when a guest 2 is running
|
||||
* and can therefore never occur in kernel context.
|
||||
*/
|
||||
printk_ratelimited(KERN_WARNING
|
||||
"Secure storage violation in task: %s, pid %d\n",
|
||||
current->comm, current->pid);
|
||||
send_sig(SIGSEGV, current, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
void do_secure_storage_access(struct pt_regs *regs)
|
||||
{
|
||||
|
@ -869,4 +884,9 @@ void do_non_secure_storage_access(struct pt_regs *regs)
|
|||
{
|
||||
default_trap_handler(regs);
|
||||
}
|
||||
|
||||
void do_secure_storage_violation(struct pt_regs *regs)
|
||||
{
|
||||
default_trap_handler(regs);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -668,6 +668,10 @@ EXPORT_SYMBOL_GPL(zpci_enable_device);
|
|||
int zpci_disable_device(struct zpci_dev *zdev)
|
||||
{
|
||||
zpci_dma_exit_device(zdev);
|
||||
/*
|
||||
* The zPCI function may already be disabled by the platform, this is
|
||||
* detected in clp_disable_fh() which becomes a no-op.
|
||||
*/
|
||||
return clp_disable_fh(zdev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(zpci_disable_device);
|
||||
|
|
|
@ -143,6 +143,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
|
|||
zpci_remove_device(zdev);
|
||||
}
|
||||
|
||||
zdev->fh = ccdf->fh;
|
||||
zpci_disable_device(zdev);
|
||||
zdev->state = ZPCI_FN_STATE_STANDBY;
|
||||
if (!clp_get_state(ccdf->fid, &state) &&
|
||||
state == ZPCI_FN_STATE_RESERVED) {
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/percpu.h>
|
||||
|
|
|
@ -370,7 +370,6 @@ syscall_trace_entry:
|
|||
nop
|
||||
cmp/eq #-1, r0
|
||||
bt syscall_exit
|
||||
mov.l r0, @(OFF_R0,r15) ! Save return value
|
||||
! Reload R0-R4 from kernel stack, where the
|
||||
! parent may have modified them using
|
||||
! ptrace(POKEUSR). (Note that R0-R2 are
|
||||
|
|
|
@ -455,16 +455,11 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||
|
||||
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
long ret = 0;
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs))
|
||||
/*
|
||||
* Tracing decided this syscall should not happen.
|
||||
* We'll return a bogus call number to get an ENOSYS
|
||||
* error, but leave the original number in regs->regs[0].
|
||||
*/
|
||||
ret = -1L;
|
||||
tracehook_report_syscall_entry(regs)) {
|
||||
regs->regs[0] = -ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (secure_computing() == -1)
|
||||
return -1;
|
||||
|
@ -475,7 +470,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
|||
audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5],
|
||||
regs->regs[6], regs->regs[7]);
|
||||
|
||||
return ret ?: regs->regs[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
|
|
|
@ -43,6 +43,8 @@ KBUILD_CFLAGS += -Wno-pointer-sign
|
|||
KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
|
||||
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
|
||||
KBUILD_CFLAGS += -D__DISABLE_EXPORTS
|
||||
# Disable relocation relaxation in case the link is not PIE.
|
||||
KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no)
|
||||
|
||||
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
|
||||
GCOV_PROFILE := n
|
||||
|
|
|
@ -19,6 +19,7 @@ CONFIG_CGROUP_CPUACCT=y
|
|||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
# CONFIG_64BIT is not set
|
||||
CONFIG_SMP=y
|
||||
CONFIG_X86_GENERIC=y
|
||||
CONFIG_HPET_TIMER=y
|
||||
|
|
|
@ -299,7 +299,7 @@ __visible noinstr void xen_pv_evtchn_do_upcall(struct pt_regs *regs)
|
|||
old_regs = set_irq_regs(regs);
|
||||
|
||||
instrumentation_begin();
|
||||
run_on_irqstack_cond(__xen_pv_evtchn_do_upcall, NULL, regs);
|
||||
run_on_irqstack_cond(__xen_pv_evtchn_do_upcall, regs);
|
||||
instrumentation_begin();
|
||||
|
||||
set_irq_regs(old_regs);
|
||||
|
|
|
@ -682,6 +682,8 @@ SYM_CODE_END(.Lbad_gs)
|
|||
* rdx: Function argument (can be NULL if none)
|
||||
*/
|
||||
SYM_FUNC_START(asm_call_on_stack)
|
||||
SYM_INNER_LABEL(asm_call_sysvec_on_stack, SYM_L_GLOBAL)
|
||||
SYM_INNER_LABEL(asm_call_irq_on_stack, SYM_L_GLOBAL)
|
||||
/*
|
||||
* Save the frame pointer unconditionally. This allows the ORC
|
||||
* unwinder to handle the stack switch.
|
||||
|
|
|
@ -159,8 +159,6 @@ static inline u64 x86_default_get_root_pointer(void)
|
|||
extern int x86_acpi_numa_init(void);
|
||||
#endif /* CONFIG_ACPI_NUMA */
|
||||
|
||||
#define acpi_unlazy_tlb(x) leave_mm(x)
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI
|
||||
static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
|
||||
{
|
||||
|
|
|
@ -60,12 +60,26 @@
|
|||
#define FRAME_END "pop %" _ASM_BP "\n"
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
#define ENCODE_FRAME_POINTER \
|
||||
"lea 1(%rsp), %rbp\n\t"
|
||||
|
||||
static inline unsigned long encode_frame_pointer(struct pt_regs *regs)
|
||||
{
|
||||
return (unsigned long)regs + 1;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_X86_64 */
|
||||
|
||||
#define ENCODE_FRAME_POINTER \
|
||||
"movl %esp, %ebp\n\t" \
|
||||
"andl $0x7fffffff, %ebp\n\t"
|
||||
|
||||
static inline unsigned long encode_frame_pointer(struct pt_regs *regs)
|
||||
{
|
||||
return (unsigned long)regs & 0x7fffffff;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -83,6 +97,11 @@
|
|||
|
||||
#define ENCODE_FRAME_POINTER
|
||||
|
||||
static inline unsigned long encode_frame_pointer(struct pt_regs *regs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define FRAME_BEGIN
|
||||
|
|
|
@ -242,7 +242,7 @@ __visible noinstr void func(struct pt_regs *regs) \
|
|||
instrumentation_begin(); \
|
||||
irq_enter_rcu(); \
|
||||
kvm_set_cpu_l1tf_flush_l1d(); \
|
||||
run_on_irqstack_cond(__##func, regs, regs); \
|
||||
run_sysvec_on_irqstack_cond(__##func, regs); \
|
||||
irq_exit_rcu(); \
|
||||
instrumentation_end(); \
|
||||
irqentry_exit(regs, state); \
|
||||
|
|
|
@ -12,20 +12,50 @@ static __always_inline bool irqstack_active(void)
|
|||
return __this_cpu_read(irq_count) != -1;
|
||||
}
|
||||
|
||||
void asm_call_on_stack(void *sp, void *func, void *arg);
|
||||
void asm_call_on_stack(void *sp, void (*func)(void), void *arg);
|
||||
void asm_call_sysvec_on_stack(void *sp, void (*func)(struct pt_regs *regs),
|
||||
struct pt_regs *regs);
|
||||
void asm_call_irq_on_stack(void *sp, void (*func)(struct irq_desc *desc),
|
||||
struct irq_desc *desc);
|
||||
|
||||
static __always_inline void __run_on_irqstack(void *func, void *arg)
|
||||
static __always_inline void __run_on_irqstack(void (*func)(void))
|
||||
{
|
||||
void *tos = __this_cpu_read(hardirq_stack_ptr);
|
||||
|
||||
__this_cpu_add(irq_count, 1);
|
||||
asm_call_on_stack(tos - 8, func, arg);
|
||||
asm_call_on_stack(tos - 8, func, NULL);
|
||||
__this_cpu_sub(irq_count, 1);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
__run_sysvec_on_irqstack(void (*func)(struct pt_regs *regs),
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
void *tos = __this_cpu_read(hardirq_stack_ptr);
|
||||
|
||||
__this_cpu_add(irq_count, 1);
|
||||
asm_call_sysvec_on_stack(tos - 8, func, regs);
|
||||
__this_cpu_sub(irq_count, 1);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
__run_irq_on_irqstack(void (*func)(struct irq_desc *desc),
|
||||
struct irq_desc *desc)
|
||||
{
|
||||
void *tos = __this_cpu_read(hardirq_stack_ptr);
|
||||
|
||||
__this_cpu_add(irq_count, 1);
|
||||
asm_call_irq_on_stack(tos - 8, func, desc);
|
||||
__this_cpu_sub(irq_count, 1);
|
||||
}
|
||||
|
||||
#else /* CONFIG_X86_64 */
|
||||
static inline bool irqstack_active(void) { return false; }
|
||||
static inline void __run_on_irqstack(void *func, void *arg) { }
|
||||
static inline void __run_on_irqstack(void (*func)(void)) { }
|
||||
static inline void __run_sysvec_on_irqstack(void (*func)(struct pt_regs *regs),
|
||||
struct pt_regs *regs) { }
|
||||
static inline void __run_irq_on_irqstack(void (*func)(struct irq_desc *desc),
|
||||
struct irq_desc *desc) { }
|
||||
#endif /* !CONFIG_X86_64 */
|
||||
|
||||
static __always_inline bool irq_needs_irq_stack(struct pt_regs *regs)
|
||||
|
@ -37,17 +67,40 @@ static __always_inline bool irq_needs_irq_stack(struct pt_regs *regs)
|
|||
return !user_mode(regs) && !irqstack_active();
|
||||
}
|
||||
|
||||
static __always_inline void run_on_irqstack_cond(void *func, void *arg,
|
||||
|
||||
static __always_inline void run_on_irqstack_cond(void (*func)(void),
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
void (*__func)(void *arg) = func;
|
||||
|
||||
lockdep_assert_irqs_disabled();
|
||||
|
||||
if (irq_needs_irq_stack(regs))
|
||||
__run_on_irqstack(__func, arg);
|
||||
__run_on_irqstack(func);
|
||||
else
|
||||
__func(arg);
|
||||
func();
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
run_sysvec_on_irqstack_cond(void (*func)(struct pt_regs *regs),
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
lockdep_assert_irqs_disabled();
|
||||
|
||||
if (irq_needs_irq_stack(regs))
|
||||
__run_sysvec_on_irqstack(func, regs);
|
||||
else
|
||||
func(regs);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
run_irq_on_irqstack_cond(void (*func)(struct irq_desc *desc), struct irq_desc *desc,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
lockdep_assert_irqs_disabled();
|
||||
|
||||
if (irq_needs_irq_stack(regs))
|
||||
__run_irq_on_irqstack(func, desc);
|
||||
else
|
||||
func(desc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2243,6 +2243,7 @@ static inline void __init check_timer(void)
|
|||
legacy_pic->init(0);
|
||||
legacy_pic->make_irq(0);
|
||||
apic_write(APIC_LVT0, APIC_DM_EXTINT);
|
||||
legacy_pic->unmask(0);
|
||||
|
||||
unlock_ExtINT_logic();
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ static __always_inline void handle_irq(struct irq_desc *desc,
|
|||
struct pt_regs *regs)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_64))
|
||||
run_on_irqstack_cond(desc->handle_irq, desc, regs);
|
||||
run_irq_on_irqstack_cond(desc->handle_irq, desc, regs);
|
||||
else
|
||||
__handle_irq(desc, regs);
|
||||
}
|
||||
|
|
|
@ -74,5 +74,5 @@ int irq_init_percpu_irqstack(unsigned int cpu)
|
|||
|
||||
void do_softirq_own_stack(void)
|
||||
{
|
||||
run_on_irqstack_cond(__do_softirq, NULL, NULL);
|
||||
run_on_irqstack_cond(__do_softirq, NULL);
|
||||
}
|
||||
|
|
|
@ -652,6 +652,7 @@ static void __init kvm_guest_init(void)
|
|||
}
|
||||
|
||||
if (pv_tlb_flush_supported()) {
|
||||
pv_ops.mmu.flush_tlb_others = kvm_flush_tlb_others;
|
||||
pv_ops.mmu.tlb_remove_table = tlb_remove_table;
|
||||
pr_info("KVM setup pv remote TLB flush\n");
|
||||
}
|
||||
|
@ -764,14 +765,6 @@ static __init int activate_jump_labels(void)
|
|||
}
|
||||
arch_initcall(activate_jump_labels);
|
||||
|
||||
static void kvm_free_pv_cpu_mask(void)
|
||||
{
|
||||
unsigned int cpu;
|
||||
|
||||
for_each_possible_cpu(cpu)
|
||||
free_cpumask_var(per_cpu(__pv_cpu_mask, cpu));
|
||||
}
|
||||
|
||||
static __init int kvm_alloc_cpumask(void)
|
||||
{
|
||||
int cpu;
|
||||
|
@ -790,20 +783,11 @@ static __init int kvm_alloc_cpumask(void)
|
|||
|
||||
if (alloc)
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (!zalloc_cpumask_var_node(
|
||||
per_cpu_ptr(&__pv_cpu_mask, cpu),
|
||||
GFP_KERNEL, cpu_to_node(cpu))) {
|
||||
goto zalloc_cpumask_fail;
|
||||
}
|
||||
zalloc_cpumask_var_node(per_cpu_ptr(&__pv_cpu_mask, cpu),
|
||||
GFP_KERNEL, cpu_to_node(cpu));
|
||||
}
|
||||
|
||||
apic->send_IPI_mask_allbutself = kvm_send_ipi_mask_allbutself;
|
||||
pv_ops.mmu.flush_tlb_others = kvm_flush_tlb_others;
|
||||
return 0;
|
||||
|
||||
zalloc_cpumask_fail:
|
||||
kvm_free_pv_cpu_mask();
|
||||
return -ENOMEM;
|
||||
}
|
||||
arch_initcall(kvm_alloc_cpumask);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <asm/spec-ctrl.h>
|
||||
#include <asm/io_bitmap.h>
|
||||
#include <asm/proto.h>
|
||||
#include <asm/frame.h>
|
||||
|
||||
#include "process.h"
|
||||
|
||||
|
@ -133,7 +134,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
|
|||
fork_frame = container_of(childregs, struct fork_frame, regs);
|
||||
frame = &fork_frame->frame;
|
||||
|
||||
frame->bp = 0;
|
||||
frame->bp = encode_frame_pointer(childregs);
|
||||
frame->ret_addr = (unsigned long) ret_from_fork;
|
||||
p->thread.sp = (unsigned long) fork_frame;
|
||||
p->thread.io_bitmap = NULL;
|
||||
|
|
|
@ -2183,6 +2183,12 @@ static int iret_interception(struct vcpu_svm *svm)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int invd_interception(struct vcpu_svm *svm)
|
||||
{
|
||||
/* Treat an INVD instruction as a NOP and just skip it. */
|
||||
return kvm_skip_emulated_instruction(&svm->vcpu);
|
||||
}
|
||||
|
||||
static int invlpg_interception(struct vcpu_svm *svm)
|
||||
{
|
||||
if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
|
||||
|
@ -2774,7 +2780,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
|
|||
[SVM_EXIT_RDPMC] = rdpmc_interception,
|
||||
[SVM_EXIT_CPUID] = cpuid_interception,
|
||||
[SVM_EXIT_IRET] = iret_interception,
|
||||
[SVM_EXIT_INVD] = emulate_on_interception,
|
||||
[SVM_EXIT_INVD] = invd_interception,
|
||||
[SVM_EXIT_PAUSE] = pause_interception,
|
||||
[SVM_EXIT_HLT] = halt_interception,
|
||||
[SVM_EXIT_INVLPG] = invlpg_interception,
|
||||
|
|
|
@ -129,6 +129,9 @@ static bool __read_mostly enable_preemption_timer = 1;
|
|||
module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO);
|
||||
#endif
|
||||
|
||||
extern bool __read_mostly allow_smaller_maxphyaddr;
|
||||
module_param(allow_smaller_maxphyaddr, bool, S_IRUGO);
|
||||
|
||||
#define KVM_VM_CR0_ALWAYS_OFF (X86_CR0_NW | X86_CR0_CD)
|
||||
#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR0_NE
|
||||
#define KVM_VM_CR0_ALWAYS_ON \
|
||||
|
@ -4803,6 +4806,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
|
|||
* EPT will cause page fault only if we need to
|
||||
* detect illegal GPAs.
|
||||
*/
|
||||
WARN_ON_ONCE(!allow_smaller_maxphyaddr);
|
||||
kvm_fixup_and_inject_pf_error(vcpu, cr2, error_code);
|
||||
return 1;
|
||||
} else
|
||||
|
@ -5331,7 +5335,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
|
|||
* would also use advanced VM-exit information for EPT violations to
|
||||
* reconstruct the page fault error code.
|
||||
*/
|
||||
if (unlikely(kvm_mmu_is_illegal_gpa(vcpu, gpa)))
|
||||
if (unlikely(allow_smaller_maxphyaddr && kvm_mmu_is_illegal_gpa(vcpu, gpa)))
|
||||
return kvm_emulate_instruction(vcpu, 0);
|
||||
|
||||
return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
|
||||
|
@ -8305,11 +8309,12 @@ static int __init vmx_init(void)
|
|||
vmx_check_vmcs12_offsets();
|
||||
|
||||
/*
|
||||
* Intel processors don't have problems with
|
||||
* GUEST_MAXPHYADDR < HOST_MAXPHYADDR so enable
|
||||
* it for VMX by default
|
||||
* Shadow paging doesn't have a (further) performance penalty
|
||||
* from GUEST_MAXPHYADDR < HOST_MAXPHYADDR so enable it
|
||||
* by default
|
||||
*/
|
||||
allow_smaller_maxphyaddr = true;
|
||||
if (!enable_ept)
|
||||
allow_smaller_maxphyaddr = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -552,7 +552,10 @@ static inline bool vmx_has_waitpkg(struct vcpu_vmx *vmx)
|
|||
|
||||
static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return !enable_ept || cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits;
|
||||
if (!enable_ept)
|
||||
return true;
|
||||
|
||||
return allow_smaller_maxphyaddr && cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits;
|
||||
}
|
||||
|
||||
void dump_vmcs(void);
|
||||
|
|
|
@ -188,7 +188,7 @@ static struct kvm_shared_msrs __percpu *shared_msrs;
|
|||
u64 __read_mostly host_efer;
|
||||
EXPORT_SYMBOL_GPL(host_efer);
|
||||
|
||||
bool __read_mostly allow_smaller_maxphyaddr;
|
||||
bool __read_mostly allow_smaller_maxphyaddr = 0;
|
||||
EXPORT_SYMBOL_GPL(allow_smaller_maxphyaddr);
|
||||
|
||||
static u64 __read_mostly host_xss;
|
||||
|
@ -976,6 +976,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
|||
unsigned long old_cr4 = kvm_read_cr4(vcpu);
|
||||
unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE |
|
||||
X86_CR4_SMEP;
|
||||
unsigned long mmu_role_bits = pdptr_bits | X86_CR4_SMAP | X86_CR4_PKE;
|
||||
|
||||
if (kvm_valid_cr4(vcpu, cr4))
|
||||
return 1;
|
||||
|
@ -1003,7 +1004,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
|||
if (kvm_x86_ops.set_cr4(vcpu, cr4))
|
||||
return 1;
|
||||
|
||||
if (((cr4 ^ old_cr4) & pdptr_bits) ||
|
||||
if (((cr4 ^ old_cr4) & mmu_role_bits) ||
|
||||
(!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
|
||||
kvm_mmu_reset_context(vcpu);
|
||||
|
||||
|
@ -3221,9 +3222,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
|||
case MSR_IA32_POWER_CTL:
|
||||
msr_info->data = vcpu->arch.msr_ia32_power_ctl;
|
||||
break;
|
||||
case MSR_IA32_TSC:
|
||||
msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset;
|
||||
case MSR_IA32_TSC: {
|
||||
/*
|
||||
* Intel SDM states that MSR_IA32_TSC read adds the TSC offset
|
||||
* even when not intercepted. AMD manual doesn't explicitly
|
||||
* state this but appears to behave the same.
|
||||
*
|
||||
* On userspace reads and writes, however, we unconditionally
|
||||
* operate L1's TSC value to ensure backwards-compatible
|
||||
* behavior for migration.
|
||||
*/
|
||||
u64 tsc_offset = msr_info->host_initiated ? vcpu->arch.l1_tsc_offset :
|
||||
vcpu->arch.tsc_offset;
|
||||
|
||||
msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + tsc_offset;
|
||||
break;
|
||||
}
|
||||
case MSR_MTRRcap:
|
||||
case 0x200 ... 0x2ff:
|
||||
return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data);
|
||||
|
|
|
@ -120,7 +120,7 @@ long __copy_user_flushcache(void *dst, const void __user *src, unsigned size)
|
|||
*/
|
||||
if (size < 8) {
|
||||
if (!IS_ALIGNED(dest, 4) || size != 4)
|
||||
clean_cache_range(dst, 1);
|
||||
clean_cache_range(dst, size);
|
||||
} else {
|
||||
if (!IS_ALIGNED(dest, 8)) {
|
||||
dest = ALIGN(dest, boot_cpu_data.x86_clflush_size);
|
||||
|
|
|
@ -801,6 +801,52 @@ bool blk_queue_can_use_dma_map_merging(struct request_queue *q,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(blk_queue_can_use_dma_map_merging);
|
||||
|
||||
/**
|
||||
* blk_queue_set_zoned - configure a disk queue zoned model.
|
||||
* @disk: the gendisk of the queue to configure
|
||||
* @model: the zoned model to set
|
||||
*
|
||||
* Set the zoned model of the request queue of @disk according to @model.
|
||||
* When @model is BLK_ZONED_HM (host managed), this should be called only
|
||||
* if zoned block device support is enabled (CONFIG_BLK_DEV_ZONED option).
|
||||
* If @model specifies BLK_ZONED_HA (host aware), the effective model used
|
||||
* depends on CONFIG_BLK_DEV_ZONED settings and on the existence of partitions
|
||||
* on the disk.
|
||||
*/
|
||||
void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model)
|
||||
{
|
||||
switch (model) {
|
||||
case BLK_ZONED_HM:
|
||||
/*
|
||||
* Host managed devices are supported only if
|
||||
* CONFIG_BLK_DEV_ZONED is enabled.
|
||||
*/
|
||||
WARN_ON_ONCE(!IS_ENABLED(CONFIG_BLK_DEV_ZONED));
|
||||
break;
|
||||
case BLK_ZONED_HA:
|
||||
/*
|
||||
* Host aware devices can be treated either as regular block
|
||||
* devices (similar to drive managed devices) or as zoned block
|
||||
* devices to take advantage of the zone command set, similarly
|
||||
* to host managed devices. We try the latter if there are no
|
||||
* partitions and zoned block device support is enabled, else
|
||||
* we do nothing special as far as the block layer is concerned.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED) ||
|
||||
disk_has_partitions(disk))
|
||||
model = BLK_ZONED_NONE;
|
||||
break;
|
||||
case BLK_ZONED_NONE:
|
||||
default:
|
||||
if (WARN_ON_ONCE(model != BLK_ZONED_NONE))
|
||||
model = BLK_ZONED_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
disk->queue->limits.zoned = model;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_queue_set_zoned);
|
||||
|
||||
static int __init blk_settings_init(void)
|
||||
{
|
||||
blk_max_low_pfn = max_low_pfn - 1;
|
||||
|
|
|
@ -161,18 +161,10 @@ static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)
|
|||
}
|
||||
|
||||
/* Power(C) State timer broadcast control */
|
||||
static void lapic_timer_state_broadcast(struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx,
|
||||
int broadcast)
|
||||
static bool lapic_timer_needs_broadcast(struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx)
|
||||
{
|
||||
int state = cx - pr->power.states;
|
||||
|
||||
if (state >= pr->power.timer_broadcast_on_state) {
|
||||
if (broadcast)
|
||||
tick_broadcast_enter();
|
||||
else
|
||||
tick_broadcast_exit();
|
||||
}
|
||||
return cx - pr->power.states >= pr->power.timer_broadcast_on_state;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -180,10 +172,11 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
|
|||
static void lapic_timer_check_state(int state, struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cstate) { }
|
||||
static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { }
|
||||
static void lapic_timer_state_broadcast(struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx,
|
||||
int broadcast)
|
||||
|
||||
static bool lapic_timer_needs_broadcast(struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -566,32 +559,43 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
|
|||
|
||||
/**
|
||||
* acpi_idle_enter_bm - enters C3 with proper BM handling
|
||||
* @drv: cpuidle driver
|
||||
* @pr: Target processor
|
||||
* @cx: Target state context
|
||||
* @timer_bc: Whether or not to change timer mode to broadcast
|
||||
* @index: index of target state
|
||||
*/
|
||||
static void acpi_idle_enter_bm(struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx, bool timer_bc)
|
||||
static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
|
||||
struct acpi_processor *pr,
|
||||
struct acpi_processor_cx *cx,
|
||||
int index)
|
||||
{
|
||||
acpi_unlazy_tlb(smp_processor_id());
|
||||
|
||||
/*
|
||||
* Must be done before busmaster disable as we might need to
|
||||
* access HPET !
|
||||
*/
|
||||
if (timer_bc)
|
||||
lapic_timer_state_broadcast(pr, cx, 1);
|
||||
static struct acpi_processor_cx safe_cx = {
|
||||
.entry_method = ACPI_CSTATE_HALT,
|
||||
};
|
||||
|
||||
/*
|
||||
* disable bus master
|
||||
* bm_check implies we need ARB_DIS
|
||||
* bm_control implies whether we can do ARB_DIS
|
||||
*
|
||||
* That leaves a case where bm_check is set and bm_control is
|
||||
* not set. In that case we cannot do much, we enter C3
|
||||
* without doing anything.
|
||||
* That leaves a case where bm_check is set and bm_control is not set.
|
||||
* In that case we cannot do much, we enter C3 without doing anything.
|
||||
*/
|
||||
if (pr->flags.bm_control) {
|
||||
bool dis_bm = pr->flags.bm_control;
|
||||
|
||||
/* If we can skip BM, demote to a safe state. */
|
||||
if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
|
||||
dis_bm = false;
|
||||
index = drv->safe_state_index;
|
||||
if (index >= 0) {
|
||||
cx = this_cpu_read(acpi_cstate[index]);
|
||||
} else {
|
||||
cx = &safe_cx;
|
||||
index = -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
if (dis_bm) {
|
||||
raw_spin_lock(&c3_lock);
|
||||
c3_cpu_count++;
|
||||
/* Disable bus master arbitration when all CPUs are in C3 */
|
||||
|
@ -600,18 +604,21 @@ static void acpi_idle_enter_bm(struct acpi_processor *pr,
|
|||
raw_spin_unlock(&c3_lock);
|
||||
}
|
||||
|
||||
rcu_idle_enter();
|
||||
|
||||
acpi_idle_do_entry(cx);
|
||||
|
||||
rcu_idle_exit();
|
||||
|
||||
/* Re-enable bus master arbitration */
|
||||
if (pr->flags.bm_control) {
|
||||
if (dis_bm) {
|
||||
raw_spin_lock(&c3_lock);
|
||||
acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
|
||||
c3_cpu_count--;
|
||||
raw_spin_unlock(&c3_lock);
|
||||
}
|
||||
|
||||
if (timer_bc)
|
||||
lapic_timer_state_broadcast(pr, cx, 0);
|
||||
return index;
|
||||
}
|
||||
|
||||
static int acpi_idle_enter(struct cpuidle_device *dev,
|
||||
|
@ -625,32 +632,21 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
|
|||
return -EINVAL;
|
||||
|
||||
if (cx->type != ACPI_STATE_C1) {
|
||||
if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check)
|
||||
return acpi_idle_enter_bm(drv, pr, cx, index);
|
||||
|
||||
/* C2 to C1 demotion. */
|
||||
if (acpi_idle_fallback_to_c1(pr) && num_online_cpus() > 1) {
|
||||
index = ACPI_IDLE_STATE_START;
|
||||
cx = per_cpu(acpi_cstate[index], dev->cpu);
|
||||
} else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) {
|
||||
if (cx->bm_sts_skip || !acpi_idle_bm_check()) {
|
||||
acpi_idle_enter_bm(pr, cx, true);
|
||||
return index;
|
||||
} else if (drv->safe_state_index >= 0) {
|
||||
index = drv->safe_state_index;
|
||||
cx = per_cpu(acpi_cstate[index], dev->cpu);
|
||||
} else {
|
||||
acpi_safe_halt();
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lapic_timer_state_broadcast(pr, cx, 1);
|
||||
|
||||
if (cx->type == ACPI_STATE_C3)
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
acpi_idle_do_entry(cx);
|
||||
|
||||
lapic_timer_state_broadcast(pr, cx, 0);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -666,7 +662,13 @@ static int acpi_idle_enter_s2idle(struct cpuidle_device *dev,
|
|||
return 0;
|
||||
|
||||
if (pr->flags.bm_check) {
|
||||
acpi_idle_enter_bm(pr, cx, false);
|
||||
u8 bm_sts_skip = cx->bm_sts_skip;
|
||||
|
||||
/* Don't check BM_STS, do an unconditional ARB_DIS for S2IDLE */
|
||||
cx->bm_sts_skip = 1;
|
||||
acpi_idle_enter_bm(drv, pr, cx, index);
|
||||
cx->bm_sts_skip = bm_sts_skip;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
@ -682,11 +684,13 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
|
|||
{
|
||||
int i, count = ACPI_IDLE_STATE_START;
|
||||
struct acpi_processor_cx *cx;
|
||||
struct cpuidle_state *state;
|
||||
|
||||
if (max_cstate == 0)
|
||||
max_cstate = 1;
|
||||
|
||||
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
|
||||
state = &acpi_idle_driver.states[count];
|
||||
cx = &pr->power.states[i];
|
||||
|
||||
if (!cx->valid)
|
||||
|
@ -694,6 +698,15 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
|
|||
|
||||
per_cpu(acpi_cstate[count], dev->cpu) = cx;
|
||||
|
||||
if (lapic_timer_needs_broadcast(pr, cx))
|
||||
state->flags |= CPUIDLE_FLAG_TIMER_STOP;
|
||||
|
||||
if (cx->type == ACPI_STATE_C3) {
|
||||
state->flags |= CPUIDLE_FLAG_TLB_FLUSHED;
|
||||
if (pr->flags.bm_check)
|
||||
state->flags |= CPUIDLE_FLAG_RCU_IDLE;
|
||||
}
|
||||
|
||||
count++;
|
||||
if (count == CPUIDLE_STATE_MAX)
|
||||
break;
|
||||
|
|
|
@ -2224,7 +2224,7 @@ static int eni_init_one(struct pci_dev *pci_dev,
|
|||
|
||||
rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
goto err_disable;
|
||||
|
||||
rc = -ENOMEM;
|
||||
eni_dev = kmalloc(sizeof(struct eni_dev), GFP_KERNEL);
|
||||
|
|
|
@ -761,14 +761,36 @@ static int __ref get_nid_for_pfn(unsigned long pfn)
|
|||
return pfn_to_nid(pfn);
|
||||
}
|
||||
|
||||
static int do_register_memory_block_under_node(int nid,
|
||||
struct memory_block *mem_blk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If this memory block spans multiple nodes, we only indicate
|
||||
* the last processed node.
|
||||
*/
|
||||
mem_blk->nid = nid;
|
||||
|
||||
ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
|
||||
&mem_blk->dev.kobj,
|
||||
kobject_name(&mem_blk->dev.kobj));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sysfs_create_link_nowarn(&mem_blk->dev.kobj,
|
||||
&node_devices[nid]->dev.kobj,
|
||||
kobject_name(&node_devices[nid]->dev.kobj));
|
||||
}
|
||||
|
||||
/* register memory section under specified node if it spans that node */
|
||||
static int register_mem_sect_under_node(struct memory_block *mem_blk,
|
||||
void *arg)
|
||||
static int register_mem_block_under_node_early(struct memory_block *mem_blk,
|
||||
void *arg)
|
||||
{
|
||||
unsigned long memory_block_pfns = memory_block_size_bytes() / PAGE_SIZE;
|
||||
unsigned long start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
|
||||
unsigned long end_pfn = start_pfn + memory_block_pfns - 1;
|
||||
int ret, nid = *(int *)arg;
|
||||
int nid = *(int *)arg;
|
||||
unsigned long pfn;
|
||||
|
||||
for (pfn = start_pfn; pfn <= end_pfn; pfn++) {
|
||||
|
@ -785,38 +807,33 @@ static int register_mem_sect_under_node(struct memory_block *mem_blk,
|
|||
}
|
||||
|
||||
/*
|
||||
* We need to check if page belongs to nid only for the boot
|
||||
* case, during hotplug we know that all pages in the memory
|
||||
* block belong to the same node.
|
||||
* We need to check if page belongs to nid only at the boot
|
||||
* case because node's ranges can be interleaved.
|
||||
*/
|
||||
if (system_state == SYSTEM_BOOTING) {
|
||||
page_nid = get_nid_for_pfn(pfn);
|
||||
if (page_nid < 0)
|
||||
continue;
|
||||
if (page_nid != nid)
|
||||
continue;
|
||||
}
|
||||
page_nid = get_nid_for_pfn(pfn);
|
||||
if (page_nid < 0)
|
||||
continue;
|
||||
if (page_nid != nid)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If this memory block spans multiple nodes, we only indicate
|
||||
* the last processed node.
|
||||
*/
|
||||
mem_blk->nid = nid;
|
||||
|
||||
ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj,
|
||||
&mem_blk->dev.kobj,
|
||||
kobject_name(&mem_blk->dev.kobj));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sysfs_create_link_nowarn(&mem_blk->dev.kobj,
|
||||
&node_devices[nid]->dev.kobj,
|
||||
kobject_name(&node_devices[nid]->dev.kobj));
|
||||
return do_register_memory_block_under_node(nid, mem_blk);
|
||||
}
|
||||
/* mem section does not span the specified node */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* During hotplug we know that all pages in the memory block belong to the same
|
||||
* node.
|
||||
*/
|
||||
static int register_mem_block_under_node_hotplug(struct memory_block *mem_blk,
|
||||
void *arg)
|
||||
{
|
||||
int nid = *(int *)arg;
|
||||
|
||||
return do_register_memory_block_under_node(nid, mem_blk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unregister a memory block device under the node it spans. Memory blocks
|
||||
* with multiple nodes cannot be offlined and therefore also never be removed.
|
||||
|
@ -832,11 +849,19 @@ void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
|
|||
kobject_name(&node_devices[mem_blk->nid]->dev.kobj));
|
||||
}
|
||||
|
||||
int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn)
|
||||
int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn,
|
||||
enum meminit_context context)
|
||||
{
|
||||
walk_memory_blocks_func_t func;
|
||||
|
||||
if (context == MEMINIT_HOTPLUG)
|
||||
func = register_mem_block_under_node_hotplug;
|
||||
else
|
||||
func = register_mem_block_under_node_early;
|
||||
|
||||
return walk_memory_blocks(PFN_PHYS(start_pfn),
|
||||
PFN_PHYS(end_pfn - start_pfn), (void *)&nid,
|
||||
register_mem_sect_under_node);
|
||||
func);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HUGETLBFS
|
||||
|
|
|
@ -217,7 +217,7 @@ struct regmap_field {
|
|||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
extern void regmap_debugfs_initcall(void);
|
||||
extern void regmap_debugfs_init(struct regmap *map, const char *name);
|
||||
extern void regmap_debugfs_init(struct regmap *map);
|
||||
extern void regmap_debugfs_exit(struct regmap *map);
|
||||
|
||||
static inline void regmap_debugfs_disable(struct regmap *map)
|
||||
|
@ -227,7 +227,7 @@ static inline void regmap_debugfs_disable(struct regmap *map)
|
|||
|
||||
#else
|
||||
static inline void regmap_debugfs_initcall(void) { }
|
||||
static inline void regmap_debugfs_init(struct regmap *map, const char *name) { }
|
||||
static inline void regmap_debugfs_init(struct regmap *map) { }
|
||||
static inline void regmap_debugfs_exit(struct regmap *map) { }
|
||||
static inline void regmap_debugfs_disable(struct regmap *map) { }
|
||||
#endif
|
||||
|
@ -259,7 +259,7 @@ bool regcache_set_val(struct regmap *map, void *base, unsigned int idx,
|
|||
int regcache_lookup_reg(struct regmap *map, unsigned int reg);
|
||||
|
||||
int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
||||
const void *val, size_t val_len);
|
||||
const void *val, size_t val_len, bool noinc);
|
||||
|
||||
void regmap_async_complete_cb(struct regmap_async *async, int ret);
|
||||
|
||||
|
|
|
@ -717,7 +717,7 @@ static int regcache_sync_block_raw_flush(struct regmap *map, const void **data,
|
|||
|
||||
map->cache_bypass = true;
|
||||
|
||||
ret = _regmap_raw_write(map, base, *data, count * val_bytes);
|
||||
ret = _regmap_raw_write(map, base, *data, count * val_bytes, false);
|
||||
if (ret)
|
||||
dev_err(map->dev, "Unable to sync registers %#x-%#x. %d\n",
|
||||
base, cur - map->reg_stride, ret);
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
struct regmap_debugfs_node {
|
||||
struct regmap *map;
|
||||
const char *name;
|
||||
struct list_head link;
|
||||
};
|
||||
|
||||
|
@ -544,11 +543,12 @@ static const struct file_operations regmap_cache_bypass_fops = {
|
|||
.write = regmap_cache_bypass_write_file,
|
||||
};
|
||||
|
||||
void regmap_debugfs_init(struct regmap *map, const char *name)
|
||||
void regmap_debugfs_init(struct regmap *map)
|
||||
{
|
||||
struct rb_node *next;
|
||||
struct regmap_range_node *range_node;
|
||||
const char *devname = "dummy";
|
||||
const char *name = map->name;
|
||||
|
||||
/*
|
||||
* Userspace can initiate reads from the hardware over debugfs.
|
||||
|
@ -569,7 +569,6 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
|
|||
if (!node)
|
||||
return;
|
||||
node->map = map;
|
||||
node->name = name;
|
||||
mutex_lock(®map_debugfs_early_lock);
|
||||
list_add(&node->link, ®map_debugfs_early_list);
|
||||
mutex_unlock(®map_debugfs_early_lock);
|
||||
|
@ -679,7 +678,7 @@ void regmap_debugfs_initcall(void)
|
|||
|
||||
mutex_lock(®map_debugfs_early_lock);
|
||||
list_for_each_entry_safe(node, tmp, ®map_debugfs_early_list, link) {
|
||||
regmap_debugfs_init(node->map, node->name);
|
||||
regmap_debugfs_init(node->map);
|
||||
list_del(&node->link);
|
||||
kfree(node);
|
||||
}
|
||||
|
|
|
@ -581,14 +581,34 @@ static void regmap_range_exit(struct regmap *map)
|
|||
kfree(map->selector_work_buf);
|
||||
}
|
||||
|
||||
static int regmap_set_name(struct regmap *map, const struct regmap_config *config)
|
||||
{
|
||||
if (config->name) {
|
||||
const char *name = kstrdup_const(config->name, GFP_KERNEL);
|
||||
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
kfree_const(map->name);
|
||||
map->name = name;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int regmap_attach_dev(struct device *dev, struct regmap *map,
|
||||
const struct regmap_config *config)
|
||||
{
|
||||
struct regmap **m;
|
||||
int ret;
|
||||
|
||||
map->dev = dev;
|
||||
|
||||
regmap_debugfs_init(map, config->name);
|
||||
ret = regmap_set_name(map, config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_debugfs_init(map);
|
||||
|
||||
/* Add a devres resource for dev_get_regmap() */
|
||||
m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL);
|
||||
|
@ -687,13 +707,9 @@ struct regmap *__regmap_init(struct device *dev,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (config->name) {
|
||||
map->name = kstrdup_const(config->name, GFP_KERNEL);
|
||||
if (!map->name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_map;
|
||||
}
|
||||
}
|
||||
ret = regmap_set_name(map, config);
|
||||
if (ret)
|
||||
goto err_map;
|
||||
|
||||
if (config->disable_locking) {
|
||||
map->lock = map->unlock = regmap_lock_unlock_none;
|
||||
|
@ -1137,7 +1153,7 @@ skip_format_initialization:
|
|||
if (ret != 0)
|
||||
goto err_regcache;
|
||||
} else {
|
||||
regmap_debugfs_init(map, config->name);
|
||||
regmap_debugfs_init(map);
|
||||
}
|
||||
|
||||
return map;
|
||||
|
@ -1297,6 +1313,8 @@ EXPORT_SYMBOL_GPL(regmap_field_free);
|
|||
*/
|
||||
int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
|
||||
{
|
||||
int ret;
|
||||
|
||||
regcache_exit(map);
|
||||
regmap_debugfs_exit(map);
|
||||
|
||||
|
@ -1309,7 +1327,11 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
|
|||
map->readable_noinc_reg = config->readable_noinc_reg;
|
||||
map->cache_type = config->cache_type;
|
||||
|
||||
regmap_debugfs_init(map, config->name);
|
||||
ret = regmap_set_name(map, config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_debugfs_init(map);
|
||||
|
||||
map->cache_bypass = false;
|
||||
map->cache_only = false;
|
||||
|
@ -1464,7 +1486,7 @@ static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes,
|
|||
}
|
||||
|
||||
static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
|
||||
const void *val, size_t val_len)
|
||||
const void *val, size_t val_len, bool noinc)
|
||||
{
|
||||
struct regmap_range_node *range;
|
||||
unsigned long flags;
|
||||
|
@ -1523,7 +1545,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
|
|||
win_residue, val_len / map->format.val_bytes);
|
||||
ret = _regmap_raw_write_impl(map, reg, val,
|
||||
win_residue *
|
||||
map->format.val_bytes);
|
||||
map->format.val_bytes, noinc);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
|
@ -1537,7 +1559,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
|
|||
win_residue = range->window_len - win_offset;
|
||||
}
|
||||
|
||||
ret = _regmap_select_page(map, ®, range, val_num);
|
||||
ret = _regmap_select_page(map, ®, range, noinc ? 1 : val_num);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
@ -1745,7 +1767,8 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
|
|||
map->work_buf +
|
||||
map->format.reg_bytes +
|
||||
map->format.pad_bytes,
|
||||
map->format.val_bytes);
|
||||
map->format.val_bytes,
|
||||
false);
|
||||
}
|
||||
|
||||
static inline void *_regmap_map_get_context(struct regmap *map)
|
||||
|
@ -1839,7 +1862,7 @@ int regmap_write_async(struct regmap *map, unsigned int reg, unsigned int val)
|
|||
EXPORT_SYMBOL_GPL(regmap_write_async);
|
||||
|
||||
int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
||||
const void *val, size_t val_len)
|
||||
const void *val, size_t val_len, bool noinc)
|
||||
{
|
||||
size_t val_bytes = map->format.val_bytes;
|
||||
size_t val_count = val_len / val_bytes;
|
||||
|
@ -1860,7 +1883,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
|||
|
||||
/* Write as many bytes as possible with chunk_size */
|
||||
for (i = 0; i < chunk_count; i++) {
|
||||
ret = _regmap_raw_write_impl(map, reg, val, chunk_bytes);
|
||||
ret = _regmap_raw_write_impl(map, reg, val, chunk_bytes, noinc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1871,7 +1894,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
|||
|
||||
/* Write remaining bytes */
|
||||
if (val_len)
|
||||
ret = _regmap_raw_write_impl(map, reg, val, val_len);
|
||||
ret = _regmap_raw_write_impl(map, reg, val, val_len, noinc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1904,7 +1927,7 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
|
|||
|
||||
map->lock(map->lock_arg);
|
||||
|
||||
ret = _regmap_raw_write(map, reg, val, val_len);
|
||||
ret = _regmap_raw_write(map, reg, val, val_len, false);
|
||||
|
||||
map->unlock(map->lock_arg);
|
||||
|
||||
|
@ -1962,7 +1985,7 @@ int regmap_noinc_write(struct regmap *map, unsigned int reg,
|
|||
write_len = map->max_raw_write;
|
||||
else
|
||||
write_len = val_len;
|
||||
ret = _regmap_raw_write(map, reg, val, write_len);
|
||||
ret = _regmap_raw_write(map, reg, val, write_len, true);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
val = ((u8 *)val) + write_len;
|
||||
|
@ -2439,7 +2462,7 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg,
|
|||
|
||||
map->async = true;
|
||||
|
||||
ret = _regmap_raw_write(map, reg, val, val_len);
|
||||
ret = _regmap_raw_write(map, reg, val, val_len, false);
|
||||
|
||||
map->async = false;
|
||||
|
||||
|
@ -2450,7 +2473,7 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg,
|
|||
EXPORT_SYMBOL_GPL(regmap_raw_write_async);
|
||||
|
||||
static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
||||
unsigned int val_len)
|
||||
unsigned int val_len, bool noinc)
|
||||
{
|
||||
struct regmap_range_node *range;
|
||||
int ret;
|
||||
|
@ -2463,7 +2486,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
|||
range = _regmap_range_lookup(map, reg);
|
||||
if (range) {
|
||||
ret = _regmap_select_page(map, ®, range,
|
||||
val_len / map->format.val_bytes);
|
||||
noinc ? 1 : val_len / map->format.val_bytes);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
@ -2501,7 +2524,7 @@ static int _regmap_bus_read(void *context, unsigned int reg,
|
|||
if (!map->format.parse_val)
|
||||
return -EINVAL;
|
||||
|
||||
ret = _regmap_raw_read(map, reg, work_val, map->format.val_bytes);
|
||||
ret = _regmap_raw_read(map, reg, work_val, map->format.val_bytes, false);
|
||||
if (ret == 0)
|
||||
*val = map->format.parse_val(work_val);
|
||||
|
||||
|
@ -2617,7 +2640,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
|||
|
||||
/* Read bytes that fit into whole chunks */
|
||||
for (i = 0; i < chunk_count; i++) {
|
||||
ret = _regmap_raw_read(map, reg, val, chunk_bytes);
|
||||
ret = _regmap_raw_read(map, reg, val, chunk_bytes, false);
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
|
||||
|
@ -2628,7 +2651,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
|||
|
||||
/* Read remaining bytes */
|
||||
if (val_len) {
|
||||
ret = _regmap_raw_read(map, reg, val, val_len);
|
||||
ret = _regmap_raw_read(map, reg, val, val_len, false);
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
}
|
||||
|
@ -2703,7 +2726,7 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg,
|
|||
read_len = map->max_raw_read;
|
||||
else
|
||||
read_len = val_len;
|
||||
ret = _regmap_raw_read(map, reg, val, read_len);
|
||||
ret = _regmap_raw_read(map, reg, val, read_len, true);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
val = ((u8 *)val) + read_len;
|
||||
|
|
|
@ -169,7 +169,7 @@ static int __init h8300_8timer_init(struct device_node *node)
|
|||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
ret = ENXIO;
|
||||
ret = -ENXIO;
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("failed to map registers for clockevent\n");
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
#ifndef CONFIG_RISCV_M_MODE
|
||||
#include <asm/clint.h>
|
||||
#endif
|
||||
|
||||
#define CLINT_IPI_OFF 0
|
||||
#define CLINT_TIMER_CMP_OFF 0x4000
|
||||
|
@ -31,6 +36,10 @@ static u64 __iomem *clint_timer_val;
|
|||
static unsigned long clint_timer_freq;
|
||||
static unsigned int clint_timer_irq;
|
||||
|
||||
#ifdef CONFIG_RISCV_M_MODE
|
||||
u64 __iomem *clint_time_val;
|
||||
#endif
|
||||
|
||||
static void clint_send_ipi(const struct cpumask *target)
|
||||
{
|
||||
unsigned int cpu;
|
||||
|
@ -184,6 +193,14 @@ static int __init clint_timer_init_dt(struct device_node *np)
|
|||
clint_timer_val = base + CLINT_TIMER_VAL_OFF;
|
||||
clint_timer_freq = riscv_timebase;
|
||||
|
||||
#ifdef CONFIG_RISCV_M_MODE
|
||||
/*
|
||||
* Yes, that's an odd naming scheme. time_val is public, but hopefully
|
||||
* will die in favor of something cleaner.
|
||||
*/
|
||||
clint_time_val = clint_timer_val;
|
||||
#endif
|
||||
|
||||
pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);
|
||||
|
||||
rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);
|
||||
|
|
|
@ -28,6 +28,7 @@ static irqreturn_t gx6605s_timer_interrupt(int irq, void *dev)
|
|||
void __iomem *base = timer_of_base(to_timer_of(ce));
|
||||
|
||||
writel_relaxed(GX6605S_STATUS_CLR, base + TIMER_STATUS);
|
||||
writel_relaxed(0, base + TIMER_INI);
|
||||
|
||||
ce->event_handler(ce);
|
||||
|
||||
|
|
|
@ -69,12 +69,33 @@ static bool dmtimer_systimer_revision1(struct dmtimer_systimer *t)
|
|||
return !(tidr >> 16);
|
||||
}
|
||||
|
||||
static void dmtimer_systimer_enable(struct dmtimer_systimer *t)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (dmtimer_systimer_revision1(t))
|
||||
val = DMTIMER_TYPE1_ENABLE;
|
||||
else
|
||||
val = DMTIMER_TYPE2_ENABLE;
|
||||
|
||||
writel_relaxed(val, t->base + t->sysc);
|
||||
}
|
||||
|
||||
static void dmtimer_systimer_disable(struct dmtimer_systimer *t)
|
||||
{
|
||||
if (!dmtimer_systimer_revision1(t))
|
||||
return;
|
||||
|
||||
writel_relaxed(DMTIMER_TYPE1_DISABLE, t->base + t->sysc);
|
||||
}
|
||||
|
||||
static int __init dmtimer_systimer_type1_reset(struct dmtimer_systimer *t)
|
||||
{
|
||||
void __iomem *syss = t->base + OMAP_TIMER_V1_SYS_STAT_OFFSET;
|
||||
int ret;
|
||||
u32 l;
|
||||
|
||||
dmtimer_systimer_enable(t);
|
||||
writel_relaxed(BIT(1) | BIT(2), t->base + t->ifctrl);
|
||||
ret = readl_poll_timeout_atomic(syss, l, l & BIT(0), 100,
|
||||
DMTIMER_RESET_WAIT);
|
||||
|
@ -88,6 +109,7 @@ static int __init dmtimer_systimer_type2_reset(struct dmtimer_systimer *t)
|
|||
void __iomem *sysc = t->base + t->sysc;
|
||||
u32 l;
|
||||
|
||||
dmtimer_systimer_enable(t);
|
||||
l = readl_relaxed(sysc);
|
||||
l |= BIT(0);
|
||||
writel_relaxed(l, sysc);
|
||||
|
@ -336,26 +358,6 @@ static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dmtimer_systimer_enable(struct dmtimer_systimer *t)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (dmtimer_systimer_revision1(t))
|
||||
val = DMTIMER_TYPE1_ENABLE;
|
||||
else
|
||||
val = DMTIMER_TYPE2_ENABLE;
|
||||
|
||||
writel_relaxed(val, t->base + t->sysc);
|
||||
}
|
||||
|
||||
static void dmtimer_systimer_disable(struct dmtimer_systimer *t)
|
||||
{
|
||||
if (!dmtimer_systimer_revision1(t))
|
||||
return;
|
||||
|
||||
writel_relaxed(DMTIMER_TYPE1_DISABLE, t->base + t->sysc);
|
||||
}
|
||||
|
||||
static int __init dmtimer_systimer_setup(struct device_node *np,
|
||||
struct dmtimer_systimer *t)
|
||||
{
|
||||
|
@ -409,8 +411,8 @@ static int __init dmtimer_systimer_setup(struct device_node *np,
|
|||
t->wakeup = regbase + _OMAP_TIMER_WAKEUP_EN_OFFSET;
|
||||
t->ifctrl = regbase + _OMAP_TIMER_IF_CTRL_OFFSET;
|
||||
|
||||
dmtimer_systimer_enable(t);
|
||||
dmtimer_systimer_reset(t);
|
||||
dmtimer_systimer_enable(t);
|
||||
pr_debug("dmtimer rev %08x sysc %08x\n", readl_relaxed(t->base),
|
||||
readl_relaxed(t->base + t->sysc));
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ static int psci_enter_domain_idle_state(struct cpuidle_device *dev,
|
|||
return -1;
|
||||
|
||||
/* Do runtime PM to manage a hierarchical CPU toplogy. */
|
||||
pm_runtime_put_sync_suspend(pd_dev);
|
||||
RCU_NONIDLE(pm_runtime_put_sync_suspend(pd_dev));
|
||||
|
||||
state = psci_get_domain_state();
|
||||
if (!state)
|
||||
|
@ -74,7 +74,7 @@ static int psci_enter_domain_idle_state(struct cpuidle_device *dev,
|
|||
|
||||
ret = psci_cpu_suspend_enter(state) ? -1 : idx;
|
||||
|
||||
pm_runtime_get_sync(pd_dev);
|
||||
RCU_NONIDLE(pm_runtime_get_sync(pd_dev));
|
||||
|
||||
cpu_pm_exit();
|
||||
|
||||
|
|
|
@ -361,7 +361,10 @@ static void __init fixup_cede0_latency(void)
|
|||
for (i = 0; i < nr_xcede_records; i++) {
|
||||
struct xcede_latency_record *record = &payload->records[i];
|
||||
u64 latency_tb = be64_to_cpu(record->latency_ticks);
|
||||
u64 latency_us = tb_to_ns(latency_tb) / NSEC_PER_USEC;
|
||||
u64 latency_us = DIV_ROUND_UP_ULL(tb_to_ns(latency_tb), NSEC_PER_USEC);
|
||||
|
||||
if (latency_us == 0)
|
||||
pr_warn("cpuidle: xcede record %d has an unrealistic latency of 0us.\n", i);
|
||||
|
||||
if (latency_us < min_latency_us)
|
||||
min_latency_us = latency_us;
|
||||
|
@ -378,10 +381,14 @@ static void __init fixup_cede0_latency(void)
|
|||
* Perform the fix-up.
|
||||
*/
|
||||
if (min_latency_us < dedicated_states[1].exit_latency) {
|
||||
u64 cede0_latency = min_latency_us - 1;
|
||||
/*
|
||||
* We set a minimum of 1us wakeup latency for cede0 to
|
||||
* distinguish it from snooze
|
||||
*/
|
||||
u64 cede0_latency = 1;
|
||||
|
||||
if (cede0_latency <= 0)
|
||||
cede0_latency = min_latency_us;
|
||||
if (min_latency_us > cede0_latency)
|
||||
cede0_latency = min_latency_us - 1;
|
||||
|
||||
dedicated_states[1].exit_latency = cede0_latency;
|
||||
dedicated_states[1].target_residency = 10 * (cede0_latency);
|
||||
|
|
|
@ -138,14 +138,10 @@ static void enter_s2idle_proper(struct cpuidle_driver *drv,
|
|||
struct cpuidle_device *dev, int index)
|
||||
{
|
||||
ktime_t time_start, time_end;
|
||||
struct cpuidle_state *target_state = &drv->states[index];
|
||||
|
||||
time_start = ns_to_ktime(local_clock());
|
||||
|
||||
/*
|
||||
* trace_suspend_resume() called by tick_freeze() for the last CPU
|
||||
* executing it contains RCU usage regarded as invalid in the idle
|
||||
* context, so tell RCU about that.
|
||||
*/
|
||||
tick_freeze();
|
||||
/*
|
||||
* The state used here cannot be a "coupled" one, because the "coupled"
|
||||
|
@ -153,16 +149,13 @@ static void enter_s2idle_proper(struct cpuidle_driver *drv,
|
|||
* suspended is generally unsafe.
|
||||
*/
|
||||
stop_critical_timings();
|
||||
rcu_idle_enter();
|
||||
drv->states[index].enter_s2idle(dev, drv, index);
|
||||
if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
|
||||
rcu_idle_enter();
|
||||
target_state->enter_s2idle(dev, drv, index);
|
||||
if (WARN_ON_ONCE(!irqs_disabled()))
|
||||
local_irq_disable();
|
||||
/*
|
||||
* timekeeping_resume() that will be called by tick_unfreeze() for the
|
||||
* first CPU executing it calls functions containing RCU read-side
|
||||
* critical sections, so tell RCU about that.
|
||||
*/
|
||||
rcu_idle_exit();
|
||||
if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
|
||||
rcu_idle_exit();
|
||||
tick_unfreeze();
|
||||
start_critical_timings();
|
||||
|
||||
|
@ -239,9 +232,11 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
|||
time_start = ns_to_ktime(local_clock());
|
||||
|
||||
stop_critical_timings();
|
||||
rcu_idle_enter();
|
||||
if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
|
||||
rcu_idle_enter();
|
||||
entered_state = target_state->enter(dev, drv, index);
|
||||
rcu_idle_exit();
|
||||
if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
|
||||
rcu_idle_exit();
|
||||
start_critical_timings();
|
||||
|
||||
sched_clock_idle_wakeup_event();
|
||||
|
|
|
@ -85,6 +85,12 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!dax_dev) {
|
||||
pr_debug("%s: error: dax unsupported by block device\n",
|
||||
bdevname(bdev, buf));
|
||||
return false;
|
||||
}
|
||||
|
||||
err = bdev_dax_pgoff(bdev, start, PAGE_SIZE, &pgoff);
|
||||
if (err) {
|
||||
pr_info("%s: error: unaligned partition for dax\n",
|
||||
|
@ -100,12 +106,6 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!dax_dev || !bdev_dax_supported(bdev, blocksize)) {
|
||||
pr_debug("%s: error: dax unsupported by block device\n",
|
||||
bdevname(bdev, buf));
|
||||
return false;
|
||||
}
|
||||
|
||||
id = dax_read_lock();
|
||||
len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
|
||||
len2 = dax_direct_access(dax_dev, pgoff_end, 1, &end_kaddr, &end_pfn);
|
||||
|
@ -325,11 +325,15 @@ EXPORT_SYMBOL_GPL(dax_direct_access);
|
|||
bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
|
||||
int blocksize, sector_t start, sector_t len)
|
||||
{
|
||||
if (!dax_dev)
|
||||
return false;
|
||||
|
||||
if (!dax_alive(dax_dev))
|
||||
return false;
|
||||
|
||||
return dax_dev->ops->dax_supported(dax_dev, bdev, blocksize, start, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dax_supported);
|
||||
|
||||
size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
|
||||
size_t bytes, struct iov_iter *i)
|
||||
|
|
|
@ -1766,20 +1766,23 @@ static int devfreq_summary_show(struct seq_file *s, void *data)
|
|||
struct devfreq *p_devfreq = NULL;
|
||||
unsigned long cur_freq, min_freq, max_freq;
|
||||
unsigned int polling_ms;
|
||||
unsigned int timer;
|
||||
|
||||
seq_printf(s, "%-30s %-30s %-15s %10s %12s %12s %12s\n",
|
||||
seq_printf(s, "%-30s %-30s %-15s %-10s %10s %12s %12s %12s\n",
|
||||
"dev",
|
||||
"parent_dev",
|
||||
"governor",
|
||||
"timer",
|
||||
"polling_ms",
|
||||
"cur_freq_Hz",
|
||||
"min_freq_Hz",
|
||||
"max_freq_Hz");
|
||||
seq_printf(s, "%30s %30s %15s %10s %12s %12s %12s\n",
|
||||
seq_printf(s, "%30s %30s %15s %10s %10s %12s %12s %12s\n",
|
||||
"------------------------------",
|
||||
"------------------------------",
|
||||
"---------------",
|
||||
"----------",
|
||||
"----------",
|
||||
"------------",
|
||||
"------------",
|
||||
"------------");
|
||||
|
@ -1803,13 +1806,15 @@ static int devfreq_summary_show(struct seq_file *s, void *data)
|
|||
cur_freq = devfreq->previous_freq;
|
||||
get_freq_range(devfreq, &min_freq, &max_freq);
|
||||
polling_ms = devfreq->profile->polling_ms;
|
||||
timer = devfreq->profile->timer;
|
||||
mutex_unlock(&devfreq->lock);
|
||||
|
||||
seq_printf(s,
|
||||
"%-30s %-30s %-15s %10d %12ld %12ld %12ld\n",
|
||||
"%-30s %-30s %-15s %-10s %10d %12ld %12ld %12ld\n",
|
||||
dev_name(&devfreq->dev),
|
||||
p_devfreq ? dev_name(&p_devfreq->dev) : "null",
|
||||
devfreq->governor_name,
|
||||
polling_ms ? timer_name[timer] : "null",
|
||||
polling_ms,
|
||||
cur_freq,
|
||||
min_freq,
|
||||
|
|
|
@ -836,7 +836,8 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
|
|||
rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
|
||||
if (rate < 0) {
|
||||
dev_err(&pdev->dev, "Failed to round clock rate: %ld\n", rate);
|
||||
return rate;
|
||||
err = rate;
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
tegra->max_freq = rate / KHZ;
|
||||
|
@ -897,6 +898,7 @@ remove_opps:
|
|||
dev_pm_opp_remove_all_dynamic(&pdev->dev);
|
||||
|
||||
reset_control_reset(tegra->reset);
|
||||
disable_clk:
|
||||
clk_disable_unprepare(tegra->clock);
|
||||
|
||||
return err;
|
||||
|
|
|
@ -59,6 +59,8 @@ static void dma_buf_release(struct dentry *dentry)
|
|||
struct dma_buf *dmabuf;
|
||||
|
||||
dmabuf = dentry->d_fsdata;
|
||||
if (unlikely(!dmabuf))
|
||||
return;
|
||||
|
||||
BUG_ON(dmabuf->vmapping_counter);
|
||||
|
||||
|
|
|
@ -508,6 +508,7 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
|
|||
if (!force_load && idx < 0)
|
||||
return -ENODEV;
|
||||
} else {
|
||||
force_load = true;
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
|
@ -629,9 +630,13 @@ void ghes_edac_unregister(struct ghes *ghes)
|
|||
struct mem_ctl_info *mci;
|
||||
unsigned long flags;
|
||||
|
||||
if (!force_load)
|
||||
return;
|
||||
|
||||
mutex_lock(&ghes_reg_mutex);
|
||||
|
||||
system_scanned = false;
|
||||
memset(&ghes_hw, 0, sizeof(struct ghes_hw_desc));
|
||||
|
||||
if (!refcount_dec_and_test(&ghes_refcount))
|
||||
goto unlock;
|
||||
|
|
|
@ -84,7 +84,7 @@ static int __init efibc_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (!efi_enabled(EFI_RUNTIME_SERVICES))
|
||||
if (!efivars_kobject() || !efivar_supports_writes())
|
||||
return -ENODEV;
|
||||
|
||||
ret = register_reboot_notifier(&efibc_reboot_notifier);
|
||||
|
|
|
@ -178,7 +178,7 @@ static int psp_sw_init(void *handle)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (adev->asic_type == CHIP_NAVI10) {
|
||||
if (adev->asic_type == CHIP_NAVI10 || adev->asic_type == CHIP_SIENNA_CICHLID) {
|
||||
ret= psp_sysfs_init(adev);
|
||||
if (ret) {
|
||||
return ret;
|
||||
|
|
|
@ -58,7 +58,7 @@ MODULE_FIRMWARE("amdgpu/arcturus_ta.bin");
|
|||
MODULE_FIRMWARE("amdgpu/sienna_cichlid_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/sienna_cichlid_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navy_flounder_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navy_flounder_asd.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navy_flounder_ta.bin");
|
||||
|
||||
/* address block */
|
||||
#define smnMP1_FIRMWARE_FLAGS 0x3010024
|
||||
|
|
|
@ -1216,6 +1216,8 @@ static int stop_cpsch(struct device_queue_manager *dqm)
|
|||
dqm->sched_running = false;
|
||||
dqm_unlock(dqm);
|
||||
|
||||
pm_release_ib(&dqm->packets);
|
||||
|
||||
kfd_gtt_sa_free(dqm->dev, dqm->fence_mem);
|
||||
pm_uninit(&dqm->packets, hanging);
|
||||
|
||||
|
@ -1326,7 +1328,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
|
|||
if (q->properties.is_active) {
|
||||
increment_queue_count(dqm, q->properties.type);
|
||||
|
||||
retval = execute_queues_cpsch(dqm,
|
||||
execute_queues_cpsch(dqm,
|
||||
KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue