mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 15:40:03 +02:00
Compare commits
No commits in common. "master" and "v7.3-rc1" have entirely different histories.
11
.mailmap
11
.mailmap
|
|
@ -19,8 +19,7 @@ Abhinav Kumar <quic_abhinavk@quicinc.com> <abhinavk@codeaurora.org>
|
||||||
Ahmad Masri <quic_amasri@quicinc.com> <amasri@codeaurora.org>
|
Ahmad Masri <quic_amasri@quicinc.com> <amasri@codeaurora.org>
|
||||||
Adam Oldham <oldhamca@gmail.com>
|
Adam Oldham <oldhamca@gmail.com>
|
||||||
Adam Radford <aradford@gmail.com>
|
Adam Radford <aradford@gmail.com>
|
||||||
Aditya Garg <aditya.garg@linux.dev> <gargaditya08@live.com>
|
Aditya Garg <gargaditya08@proton.me> <gargaditya08@live.com>
|
||||||
Aditya Garg <aditya.garg@linux.dev> <gargaditya08@proton.me>
|
|
||||||
Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com>
|
Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com>
|
||||||
Adrian Bunk <bunk@stusta.de>
|
Adrian Bunk <bunk@stusta.de>
|
||||||
Ajay Kaher <ajay.kaher@broadcom.com> <akaher@vmware.com>
|
Ajay Kaher <ajay.kaher@broadcom.com> <akaher@vmware.com>
|
||||||
|
|
@ -421,7 +420,6 @@ Jens Axboe <axboe@kernel.dk> <axboe@suse.de>
|
||||||
Jens Axboe <axboe@kernel.dk> <jens.axboe@oracle.com>
|
Jens Axboe <axboe@kernel.dk> <jens.axboe@oracle.com>
|
||||||
Jens Axboe <axboe@kernel.dk> <axboe@fb.com>
|
Jens Axboe <axboe@kernel.dk> <axboe@fb.com>
|
||||||
Jens Axboe <axboe@kernel.dk> <axboe@meta.com>
|
Jens Axboe <axboe@kernel.dk> <axboe@meta.com>
|
||||||
Jens Axboe <axboe@kernel.dk> <axboe@anthropic.com>
|
|
||||||
Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
|
Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
|
||||||
Jens Wiklander <jenswi@kernel.org> <jens.wiklander@linaro.org>
|
Jens Wiklander <jenswi@kernel.org> <jens.wiklander@linaro.org>
|
||||||
Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net>
|
Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net>
|
||||||
|
|
@ -552,9 +550,6 @@ Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
|
||||||
Lior David <quic_liord@quicinc.com> <liord@codeaurora.org>
|
Lior David <quic_liord@quicinc.com> <liord@codeaurora.org>
|
||||||
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@linaro.org>
|
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@linaro.org>
|
||||||
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@intel.com>
|
Loic Poulain <loic.poulain@oss.qualcomm.com> <loic.poulain@intel.com>
|
||||||
Lorenzo Bianconi <lorenzo@kernel.org> <lorenzo.bianconi@redhat.com>
|
|
||||||
Lorenzo Bianconi <lorenzo@kernel.org> <lorenzo.bianconi@st.com>
|
|
||||||
Lorenzo Bianconi <lorenzo@kernel.org> <lorenzo.bianconi83@gmail.com>
|
|
||||||
Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com>
|
Lorenzo Pieralisi <lpieralisi@kernel.org> <lorenzo.pieralisi@arm.com>
|
||||||
Lorenzo Stoakes <ljs@kernel.org> <lstoakes@gmail.com>
|
Lorenzo Stoakes <ljs@kernel.org> <lstoakes@gmail.com>
|
||||||
Lorenzo Stoakes <ljs@kernel.org> <lorenzo.stoakes@oracle.com>
|
Lorenzo Stoakes <ljs@kernel.org> <lorenzo.stoakes@oracle.com>
|
||||||
|
|
@ -704,7 +699,6 @@ Oliver Hartkopp <socketcan@hartkopp.net> <oliver.hartkopp@volkswagen.de>
|
||||||
Oliver Hartkopp <socketcan@hartkopp.net> <oliver@hartkopp.net>
|
Oliver Hartkopp <socketcan@hartkopp.net> <oliver@hartkopp.net>
|
||||||
Oliver Upton <oupton@kernel.org> <oupton@google.com>
|
Oliver Upton <oupton@kernel.org> <oupton@google.com>
|
||||||
Oliver Upton <oupton@kernel.org> <oliver.upton@linux.dev>
|
Oliver Upton <oupton@kernel.org> <oliver.upton@linux.dev>
|
||||||
Ondrej Mosnáček <omosnacek@gmail.com> <omosnace@redhat.com>
|
|
||||||
Ondřej Jirman <megi@xff.cz> <megous@megous.com>
|
Ondřej Jirman <megi@xff.cz> <megous@megous.com>
|
||||||
Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org>
|
Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org>
|
||||||
Pali Rohár <pali@kernel.org> <pali.rohar@gmail.com>
|
Pali Rohár <pali@kernel.org> <pali.rohar@gmail.com>
|
||||||
|
|
@ -904,8 +898,7 @@ Thomas Graf <tgraf@suug.ch>
|
||||||
Thomas Gleixner <tglx@kernel.org> <tglx@linutronix.de>
|
Thomas Gleixner <tglx@kernel.org> <tglx@linutronix.de>
|
||||||
Thomas Körper <socketcan@esd.eu> <thomas.koerper@esd.eu>
|
Thomas Körper <socketcan@esd.eu> <thomas.koerper@esd.eu>
|
||||||
Thomas Pedersen <twp@codeaurora.org>
|
Thomas Pedersen <twp@codeaurora.org>
|
||||||
Thorsten Blum <blum@kernel.org> <thorsten.blum@toblux.com>
|
Thorsten Blum <thorsten.blum@linux.dev> <thorsten.blum@toblux.com>
|
||||||
Thorsten Blum <blum@kernel.org> <thorsten.blum@linux.dev>
|
|
||||||
Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com>
|
Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com>
|
||||||
Tingwei Zhang <quic_tingwei@quicinc.com> <tingwei@codeaurora.org>
|
Tingwei Zhang <quic_tingwei@quicinc.com> <tingwei@codeaurora.org>
|
||||||
Tirupathi Reddy <quic_tirupath@quicinc.com> <tirupath@codeaurora.org>
|
Tirupathi Reddy <quic_tirupath@quicinc.com> <tirupath@codeaurora.org>
|
||||||
|
|
|
||||||
8
CREDITS
8
CREDITS
|
|
@ -1512,10 +1512,6 @@ N: Andy Gross
|
||||||
E: agross@kernel.org
|
E: agross@kernel.org
|
||||||
D: Qualcomm SoC subsystem and drivers
|
D: Qualcomm SoC subsystem and drivers
|
||||||
|
|
||||||
N: Mark Gross
|
|
||||||
E: markgross@kernel.org
|
|
||||||
D: x86/mellanox platform maintenance and various x86 specific drivers
|
|
||||||
|
|
||||||
N: Grant Grundler
|
N: Grant Grundler
|
||||||
E: grantgrundler@gmail.com
|
E: grantgrundler@gmail.com
|
||||||
W: http://obmouse.sourceforge.net/
|
W: http://obmouse.sourceforge.net/
|
||||||
|
|
@ -4309,10 +4305,6 @@ N: Juergen Weigert
|
||||||
E: jnweiger@immd4.informatik.uni-erlangen.de
|
E: jnweiger@immd4.informatik.uni-erlangen.de
|
||||||
D: The Linux Support Team Erlangen
|
D: The Linux Support Team Erlangen
|
||||||
|
|
||||||
N: Russ Weight
|
|
||||||
E: russ.weight@gmail.com
|
|
||||||
D: Added support for Firmware Upload to the Firmware Loader
|
|
||||||
|
|
||||||
N: David Weinehall
|
N: David Weinehall
|
||||||
E: tao@acc.umu.se
|
E: tao@acc.umu.se
|
||||||
P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16
|
P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16
|
||||||
|
|
|
||||||
|
|
@ -108,9 +108,6 @@ Description:
|
||||||
# NSFS_MAGIC
|
# NSFS_MAGIC
|
||||||
dont_measure fsmagic=0x6e736673
|
dont_measure fsmagic=0x6e736673
|
||||||
dont_appraise fsmagic=0x6e736673
|
dont_appraise fsmagic=0x6e736673
|
||||||
# CONFIGFS_MAGIC
|
|
||||||
dont_measure fsmagic=0x62656570
|
|
||||||
dont_appraise fsmagic=0x62656570
|
|
||||||
|
|
||||||
measure func=BPRM_CHECK
|
measure func=BPRM_CHECK
|
||||||
measure func=FILE_MMAP mask=MAY_EXEC
|
measure func=FILE_MMAP mask=MAY_EXEC
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
What: /sys/class/firmware/.../data
|
What: /sys/class/firmware/.../data
|
||||||
Date: July 2022
|
Date: July 2022
|
||||||
KernelVersion: 5.19
|
KernelVersion: 5.19
|
||||||
Contact: driver-core@lists.linux.dev
|
Contact: Russ Weight <russ.weight@linux.dev>
|
||||||
Description: The data sysfs file is used for firmware-fallback and for
|
Description: The data sysfs file is used for firmware-fallback and for
|
||||||
firmware uploads. Cat a firmware image to this sysfs file
|
firmware uploads. Cat a firmware image to this sysfs file
|
||||||
after you echo 1 to the loading sysfs file. When the firmware
|
after you echo 1 to the loading sysfs file. When the firmware
|
||||||
|
|
@ -13,7 +13,7 @@ Description: The data sysfs file is used for firmware-fallback and for
|
||||||
What: /sys/class/firmware/.../cancel
|
What: /sys/class/firmware/.../cancel
|
||||||
Date: July 2022
|
Date: July 2022
|
||||||
KernelVersion: 5.19
|
KernelVersion: 5.19
|
||||||
Contact: driver-core@lists.linux.dev
|
Contact: Russ Weight <russ.weight@linux.dev>
|
||||||
Description: Write-only. For firmware uploads, write a "1" to this file to
|
Description: Write-only. For firmware uploads, write a "1" to this file to
|
||||||
request that the transfer of firmware data to the lower-level
|
request that the transfer of firmware data to the lower-level
|
||||||
device be canceled. This request will be rejected (EBUSY) if
|
device be canceled. This request will be rejected (EBUSY) if
|
||||||
|
|
@ -23,7 +23,7 @@ Description: Write-only. For firmware uploads, write a "1" to this file to
|
||||||
What: /sys/class/firmware/.../error
|
What: /sys/class/firmware/.../error
|
||||||
Date: July 2022
|
Date: July 2022
|
||||||
KernelVersion: 5.19
|
KernelVersion: 5.19
|
||||||
Contact: driver-core@lists.linux.dev
|
Contact: Russ Weight <russ.weight@linux.dev>
|
||||||
Description: Read-only. Returns a string describing a failed firmware
|
Description: Read-only. Returns a string describing a failed firmware
|
||||||
upload. This string will be in the form of <STATUS>:<ERROR>,
|
upload. This string will be in the form of <STATUS>:<ERROR>,
|
||||||
where <STATUS> will be one of the status strings described
|
where <STATUS> will be one of the status strings described
|
||||||
|
|
@ -37,7 +37,7 @@ Description: Read-only. Returns a string describing a failed firmware
|
||||||
What: /sys/class/firmware/.../loading
|
What: /sys/class/firmware/.../loading
|
||||||
Date: July 2022
|
Date: July 2022
|
||||||
KernelVersion: 5.19
|
KernelVersion: 5.19
|
||||||
Contact: driver-core@lists.linux.dev
|
Contact: Russ Weight <russ.weight@linux.dev>
|
||||||
Description: The loading sysfs file is used for both firmware-fallback and
|
Description: The loading sysfs file is used for both firmware-fallback and
|
||||||
for firmware uploads. Echo 1 onto the loading file to indicate
|
for firmware uploads. Echo 1 onto the loading file to indicate
|
||||||
you are writing a firmware file to the data sysfs node. Echo
|
you are writing a firmware file to the data sysfs node. Echo
|
||||||
|
|
@ -49,7 +49,7 @@ Description: The loading sysfs file is used for both firmware-fallback and
|
||||||
What: /sys/class/firmware/.../remaining_size
|
What: /sys/class/firmware/.../remaining_size
|
||||||
Date: July 2022
|
Date: July 2022
|
||||||
KernelVersion: 5.19
|
KernelVersion: 5.19
|
||||||
Contact: driver-core@lists.linux.dev
|
Contact: Russ Weight <russ.weight@linux.dev>
|
||||||
Description: Read-only. For firmware upload, this file contains the size
|
Description: Read-only. For firmware upload, this file contains the size
|
||||||
of the firmware data that remains to be transferred to the
|
of the firmware data that remains to be transferred to the
|
||||||
lower-level device driver. The size value is initialized to
|
lower-level device driver. The size value is initialized to
|
||||||
|
|
@ -62,7 +62,7 @@ Description: Read-only. For firmware upload, this file contains the size
|
||||||
What: /sys/class/firmware/.../status
|
What: /sys/class/firmware/.../status
|
||||||
Date: July 2022
|
Date: July 2022
|
||||||
KernelVersion: 5.19
|
KernelVersion: 5.19
|
||||||
Contact: driver-core@lists.linux.dev
|
Contact: Russ Weight <russ.weight@linux.dev>
|
||||||
Description: Read-only. Returns a string describing the current status of
|
Description: Read-only. Returns a string describing the current status of
|
||||||
a firmware upload. The string will be one of the following:
|
a firmware upload. The string will be one of the following:
|
||||||
idle, "receiving", "preparing", "transferring", "programming".
|
idle, "receiving", "preparing", "transferring", "programming".
|
||||||
|
|
@ -70,7 +70,7 @@ Description: Read-only. Returns a string describing the current status of
|
||||||
What: /sys/class/firmware/.../timeout
|
What: /sys/class/firmware/.../timeout
|
||||||
Date: July 2022
|
Date: July 2022
|
||||||
KernelVersion: 5.19
|
KernelVersion: 5.19
|
||||||
Contact: driver-core@lists.linux.dev
|
Contact: Russ Weight <russ.weight@linux.dev>
|
||||||
Description: This file supports the timeout mechanism for firmware
|
Description: This file supports the timeout mechanism for firmware
|
||||||
fallback. This file has no affect on firmware uploads. For
|
fallback. This file has no affect on firmware uploads. For
|
||||||
more information on timeouts please see the documentation
|
more information on timeouts please see the documentation
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Description: Shows all enabled kernel features.
|
||||||
Supported features:
|
Supported features:
|
||||||
compr_cfgs, big_pcluster, chunked_file, device_table,
|
compr_cfgs, big_pcluster, chunked_file, device_table,
|
||||||
compr_head2, sb_chksum, ztailpacking, dedupe, fragments,
|
compr_head2, sb_chksum, ztailpacking, dedupe, fragments,
|
||||||
xattr_prefixes, 48bit, metabox.
|
48bit, metabox.
|
||||||
|
|
||||||
What: /sys/fs/erofs/<disk>/sync_decompress
|
What: /sys/fs/erofs/<disk>/sync_decompress
|
||||||
Date: November 2021
|
Date: November 2021
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ Features:
|
||||||
- pages are linked to per-memcg LRU exclusively, and there is no global LRU.
|
- pages are linked to per-memcg LRU exclusively, and there is no global LRU.
|
||||||
- optionally, memory+swap usage can be accounted and limited.
|
- optionally, memory+swap usage can be accounted and limited.
|
||||||
- hierarchical accounting
|
- hierarchical accounting
|
||||||
|
- soft limit
|
||||||
- moving (recharging) account at moving a task is selectable.
|
- moving (recharging) account at moving a task is selectable.
|
||||||
- usage threshold notifier
|
- usage threshold notifier
|
||||||
- memory pressure notifier
|
- memory pressure notifier
|
||||||
|
|
@ -75,9 +76,10 @@ Brief summary of control files.
|
||||||
memory.memsw.failcnt show the number of memory+Swap hits limits
|
memory.memsw.failcnt show the number of memory+Swap hits limits
|
||||||
memory.max_usage_in_bytes show max memory usage recorded
|
memory.max_usage_in_bytes show max memory usage recorded
|
||||||
memory.memsw.max_usage_in_bytes show max memory+Swap usage recorded
|
memory.memsw.max_usage_in_bytes show max memory+Swap usage recorded
|
||||||
memory.soft_limit_in_bytes This knob is deprecated and has no effect.
|
memory.soft_limit_in_bytes set/show soft limit of memory usage
|
||||||
Writes are ignored and reads always
|
This knob is not available on CONFIG_PREEMPT_RT systems.
|
||||||
return the maximum value.
|
This knob is deprecated and shouldn't be
|
||||||
|
used.
|
||||||
memory.stat show various statistics
|
memory.stat show various statistics
|
||||||
memory.use_hierarchy set/show hierarchical account enabled
|
memory.use_hierarchy set/show hierarchical account enabled
|
||||||
This knob is deprecated and shouldn't be
|
This knob is deprecated and shouldn't be
|
||||||
|
|
@ -338,6 +340,9 @@ memory.kmem.usage_in_bytes, or in a separate counter when it makes sense.
|
||||||
The main "kmem" counter is fed into the main counter, so kmem charges will
|
The main "kmem" counter is fed into the main counter, so kmem charges will
|
||||||
also be visible from the user counter.
|
also be visible from the user counter.
|
||||||
|
|
||||||
|
Currently no soft limit is implemented for kernel memory. It is future work
|
||||||
|
to trigger slab reclaim when those limits are reached.
|
||||||
|
|
||||||
2.7.1 Current Kernel Memory resources accounted
|
2.7.1 Current Kernel Memory resources accounted
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
|
|
@ -705,10 +710,42 @@ For compatibility reasons writing 1 to memory.use_hierarchy will always pass::
|
||||||
|
|
||||||
THIS IS DEPRECATED!
|
THIS IS DEPRECATED!
|
||||||
|
|
||||||
Writing to memory.soft_limit_in_bytes has no effect and reading it will
|
Soft limits allow for greater sharing of memory. The idea behind soft limits
|
||||||
always return the maximum value.
|
is to allow control groups to use as much of the memory as needed, provided
|
||||||
|
|
||||||
Use memory.low and memory.min in cgroup v2 instead.
|
a. There is no memory contention
|
||||||
|
b. They do not exceed their hard limit
|
||||||
|
|
||||||
|
When the system detects memory contention or low memory, control groups
|
||||||
|
are pushed back to their soft limits. If the soft limit of each control
|
||||||
|
group is very high, they are pushed back as much as possible to make
|
||||||
|
sure that one control group does not starve the others of memory.
|
||||||
|
|
||||||
|
Please note that soft limits is a best-effort feature; it comes with
|
||||||
|
no guarantees, but it does its best to make sure that when memory is
|
||||||
|
heavily contended for, memory is allocated based on the soft limit
|
||||||
|
hints/setup. Currently soft limit based reclaim is set up such that
|
||||||
|
it gets invoked from balance_pgdat (kswapd).
|
||||||
|
|
||||||
|
7.1 Interface
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Soft limits can be setup by using the following commands (in this example we
|
||||||
|
assume a soft limit of 256 MiB)::
|
||||||
|
|
||||||
|
# echo 256M > memory.soft_limit_in_bytes
|
||||||
|
|
||||||
|
If we want to change this to 1G, we can at any time use::
|
||||||
|
|
||||||
|
# echo 1G > memory.soft_limit_in_bytes
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Soft limits take effect over a long period of time, since they involve
|
||||||
|
reclaiming memory for balancing between memory cgroups
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
It is recommended to set the soft limit always below the hard limit,
|
||||||
|
otherwise the hard limit will take precedence.
|
||||||
|
|
||||||
.. _cgroup-v1-memory-move-charges:
|
.. _cgroup-v1-memory-move-charges:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1130,9 +1130,9 @@ policy and the underlying scheduler. From the point of view of the cpu controlle
|
||||||
processes can be categorized as follows:
|
processes can be categorized as follows:
|
||||||
|
|
||||||
* Processes under the fair-class scheduler
|
* Processes under the fair-class scheduler
|
||||||
* Processes under a BPF scheduler with the corresponding ``cgroup_set_*`` callback
|
* Processes under a BPF scheduler with the ``cgroup_set_weight`` callback
|
||||||
* Everything else: ``SCHED_{FIFO,RR,DEADLINE}`` and processes under a BPF scheduler
|
* Everything else: ``SCHED_{FIFO,RR,DEADLINE}`` and processes under a BPF scheduler
|
||||||
without the corresponding ``cgroup_set_*`` callback
|
without the ``cgroup_set_weight`` callback
|
||||||
|
|
||||||
For details on when a process is under the fair-class scheduler or a BPF scheduler,
|
For details on when a process is under the fair-class scheduler or a BPF scheduler,
|
||||||
check out :ref:`Documentation/scheduler/sched-ext.rst <sched-ext>`.
|
check out :ref:`Documentation/scheduler/sched-ext.rst <sched-ext>`.
|
||||||
|
|
@ -1223,9 +1223,7 @@ will be referred to. All time durations are in microseconds.
|
||||||
$PERIOD duration. "max" for $MAX indicates no limit. If only
|
$PERIOD duration. "max" for $MAX indicates no limit. If only
|
||||||
one number is written, $MAX is updated.
|
one number is written, $MAX is updated.
|
||||||
|
|
||||||
This file affects only processes under the fair-class scheduler and a BPF
|
This file affects only processes under the fair-class scheduler.
|
||||||
scheduler with the ``cgroup_set_bandwidth`` callback depending on what
|
|
||||||
the callback actually does.
|
|
||||||
|
|
||||||
cpu.max.burst
|
cpu.max.burst
|
||||||
A read-write single value file which exists on non-root
|
A read-write single value file which exists on non-root
|
||||||
|
|
@ -1233,9 +1231,7 @@ will be referred to. All time durations are in microseconds.
|
||||||
|
|
||||||
The burst in the range [0, $MAX].
|
The burst in the range [0, $MAX].
|
||||||
|
|
||||||
This file affects only processes under the fair-class scheduler and a BPF
|
This file affects only processes under the fair-class scheduler.
|
||||||
scheduler with the ``cgroup_set_bandwidth`` callback depending on what
|
|
||||||
the callback actually does.
|
|
||||||
|
|
||||||
cpu.pressure
|
cpu.pressure
|
||||||
A read-write nested-keyed file.
|
A read-write nested-keyed file.
|
||||||
|
|
@ -1287,9 +1283,7 @@ will be referred to. All time durations are in microseconds.
|
||||||
own relative priorities, but the cgroup itself will be treated as
|
own relative priorities, but the cgroup itself will be treated as
|
||||||
very low priority relative to its peers.
|
very low priority relative to its peers.
|
||||||
|
|
||||||
This file affects only processes under the fair-class scheduler and a BPF
|
This file affects only processes under the fair-class scheduler.
|
||||||
scheduler with the ``cgroup_set_idle`` callback depending on what the
|
|
||||||
callback actually does.
|
|
||||||
|
|
||||||
Memory
|
Memory
|
||||||
------
|
------
|
||||||
|
|
@ -3070,7 +3064,7 @@ resources (res_a and res_b) are registered then:
|
||||||
change in this file generates a file modified event. All fields in
|
change in this file generates a file modified event. All fields in
|
||||||
this file are hierarchical.
|
this file are hierarchical.
|
||||||
|
|
||||||
<res>.max
|
max
|
||||||
The number of times the cgroup's resource usage was
|
The number of times the cgroup's resource usage was
|
||||||
about to go over the max boundary.
|
about to go over the max boundary.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4987,6 +4987,18 @@ Kernel parameters
|
||||||
Set to non-zero if a chip is present that snoops speed
|
Set to non-zero if a chip is present that snoops speed
|
||||||
changes. Disabled by default.
|
changes. Disabled by default.
|
||||||
|
|
||||||
|
pata_legacy.ht6560a= [HW,LIBATA]
|
||||||
|
Format: <int>
|
||||||
|
Set to 1, 2, or 3 for HT 6560A on the primary channel,
|
||||||
|
the secondary channel, or both channels respectively.
|
||||||
|
Disabled by default.
|
||||||
|
|
||||||
|
pata_legacy.ht6560b= [HW,LIBATA]
|
||||||
|
Format: <int>
|
||||||
|
Set to 1, 2, or 3 for HT 6560B on the primary channel,
|
||||||
|
the secondary channel, or both channels respectively.
|
||||||
|
Disabled by default.
|
||||||
|
|
||||||
pata_legacy.iordy_mask= [HW,LIBATA]
|
pata_legacy.iordy_mask= [HW,LIBATA]
|
||||||
Format: <int>
|
Format: <int>
|
||||||
IORDY enable mask. Set individual bits to allow IORDY
|
IORDY enable mask. Set individual bits to allow IORDY
|
||||||
|
|
@ -4999,6 +5011,18 @@ Kernel parameters
|
||||||
with the sequence. By default IORDY is allowed across
|
with the sequence. By default IORDY is allowed across
|
||||||
all channels.
|
all channels.
|
||||||
|
|
||||||
|
pata_legacy.opti82c46x= [HW,LIBATA]
|
||||||
|
Format: <int>
|
||||||
|
Set to 1, 2, or 3 for Opti 82c611A on the primary
|
||||||
|
channel, the secondary channel, or both channels
|
||||||
|
respectively. Disabled by default.
|
||||||
|
|
||||||
|
pata_legacy.opti82c611a= [HW,LIBATA]
|
||||||
|
Format: <int>
|
||||||
|
Set to 1, 2, or 3 for Opti 82c465MV on the primary
|
||||||
|
channel, the secondary channel, or both channels
|
||||||
|
respectively. Disabled by default.
|
||||||
|
|
||||||
pata_legacy.pio_mask= [HW,LIBATA]
|
pata_legacy.pio_mask= [HW,LIBATA]
|
||||||
Format: <int>
|
Format: <int>
|
||||||
PIO mode mask for autospeed devices. Set individual
|
PIO mode mask for autospeed devices. Set individual
|
||||||
|
|
@ -5022,6 +5046,19 @@ Kernel parameters
|
||||||
the first port in the list above (0x1f0), and so on.
|
the first port in the list above (0x1f0), and so on.
|
||||||
By default all supported ports are probed.
|
By default all supported ports are probed.
|
||||||
|
|
||||||
|
pata_legacy.qdi= [HW,LIBATA]
|
||||||
|
Format: <int>
|
||||||
|
Set to non-zero to probe QDI controllers. By default
|
||||||
|
set to 1 if CONFIG_PATA_QDI_MODULE, 0 otherwise.
|
||||||
|
|
||||||
|
pata_legacy.winbond= [HW,LIBATA]
|
||||||
|
Format: <int>
|
||||||
|
Set to non-zero to probe Winbond controllers. Use
|
||||||
|
the standard I/O port (0x130) if 1, otherwise the
|
||||||
|
value given is the I/O port to use (typically 0x1b0).
|
||||||
|
By default set to 1 if CONFIG_PATA_WINBOND_VLB_MODULE,
|
||||||
|
0 otherwise.
|
||||||
|
|
||||||
pata_platform.pio_mask= [HW,LIBATA]
|
pata_platform.pio_mask= [HW,LIBATA]
|
||||||
Format: <int>
|
Format: <int>
|
||||||
Supported PIO mode mask. Set individual bits to allow
|
Supported PIO mode mask. Set individual bits to allow
|
||||||
|
|
|
||||||
|
|
@ -1416,7 +1416,7 @@ Controls whether userspace may arm Syscall User Dispatch via
|
||||||
== ===================================================================
|
== ===================================================================
|
||||||
|
|
||||||
Only present when the kernel is built with ``CONFIG_SYSCALL_USER_DISPATCH``
|
Only present when the kernel is built with ``CONFIG_SYSCALL_USER_DISPATCH``
|
||||||
and ``CONFIG_SYSCTL``.
|
and ``CONFIG_PROC_SYSCTL``.
|
||||||
|
|
||||||
|
|
||||||
sysctl_writes_strict
|
sysctl_writes_strict
|
||||||
|
|
|
||||||
|
|
@ -155,8 +155,7 @@ The following keys are defined:
|
||||||
defined in version 1.0 of the RISC-V Cryptography Extensions Volume II.
|
defined in version 1.0 of the RISC-V Cryptography Extensions Volume II.
|
||||||
|
|
||||||
* :c:macro:`RISCV_HWPROBE_EXT_ZFH`: The Zfh extension version 1.0 is supported
|
* :c:macro:`RISCV_HWPROBE_EXT_ZFH`: The Zfh extension version 1.0 is supported
|
||||||
as defined in the RISC-V ISA manual. Zfh is a superset of Zfhmin, so
|
as defined in the RISC-V ISA manual.
|
||||||
RISCV_HWPROBE_EXT_ZFHMIN is reported whenever RISCV_HWPROBE_EXT_ZFH is.
|
|
||||||
|
|
||||||
* :c:macro:`RISCV_HWPROBE_EXT_ZFHMIN`: The Zfhmin extension version 1.0 is
|
* :c:macro:`RISCV_HWPROBE_EXT_ZFHMIN`: The Zfhmin extension version 1.0 is
|
||||||
supported as defined in the RISC-V ISA manual.
|
supported as defined in the RISC-V ISA manual.
|
||||||
|
|
@ -165,9 +164,8 @@ The following keys are defined:
|
||||||
is supported as defined in the RISC-V ISA manual.
|
is supported as defined in the RISC-V ISA manual.
|
||||||
|
|
||||||
* :c:macro:`RISCV_HWPROBE_EXT_ZVFH`: The Zvfh extension is supported as
|
* :c:macro:`RISCV_HWPROBE_EXT_ZVFH`: The Zvfh extension is supported as
|
||||||
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c
|
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c
|
||||||
("Remove draft warnings from Zvfh[min]"). Zvfh is a superset of Zvfhmin,
|
("Remove draft warnings from Zvfh[min]").
|
||||||
so RISCV_HWPROBE_EXT_ZVFHMIN is reported whenever RISCV_HWPROBE_EXT_ZVFH is.
|
|
||||||
|
|
||||||
* :c:macro:`RISCV_HWPROBE_EXT_ZVFHMIN`: The Zvfhmin extension is supported as
|
* :c:macro:`RISCV_HWPROBE_EXT_ZVFHMIN`: The Zvfhmin extension is supported as
|
||||||
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c
|
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ properties:
|
||||||
- silergy,syr827
|
- silergy,syr827
|
||||||
- silergy,syr828
|
- silergy,syr828
|
||||||
- tcs,tcs4525
|
- tcs,tcs4525
|
||||||
- tcs,tcs4526
|
|
||||||
- items:
|
- items:
|
||||||
- const: rockchip,rk8601
|
- const: rockchip,rk8601
|
||||||
- const: rockchip,rk8600
|
- const: rockchip,rk8600
|
||||||
|
|
|
||||||
|
|
@ -117,8 +117,8 @@ properties:
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
description:
|
description:
|
||||||
VLEN/8, the vector register length in bytes. This property is required on
|
VLEN/8, the vector register length in bytes. This property is required on
|
||||||
thead systems where the vector register length is not identical on all
|
thead systems where the vector register length is not identical on all harts, or
|
||||||
harts, or the vlenb CSR is not available.
|
the vlenb CSR is not available.
|
||||||
|
|
||||||
# RISC-V has multiple properties for cache op block sizes as the sizes
|
# RISC-V has multiple properties for cache op block sizes as the sizes
|
||||||
# differ between individual CBO extensions
|
# differ between individual CBO extensions
|
||||||
|
|
@ -151,8 +151,8 @@ anyOf:
|
||||||
- riscv,isa-base
|
- riscv,isa-base
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
riscv,isa-base: ["riscv,isa-extensions"]
|
riscv,isa-base: [ "riscv,isa-extensions" ]
|
||||||
riscv,isa-extensions: ["riscv,isa-base"]
|
riscv,isa-extensions: [ "riscv,isa-base" ]
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- interrupt-controller
|
- interrupt-controller
|
||||||
|
|
|
||||||
|
|
@ -44,21 +44,6 @@ allOf:
|
||||||
else:
|
else:
|
||||||
properties:
|
properties:
|
||||||
starfive,sfc-filter-syscon: false
|
starfive,sfc-filter-syscon: false
|
||||||
- if:
|
|
||||||
properties:
|
|
||||||
compatible:
|
|
||||||
contains:
|
|
||||||
const: ultrarisc,dp1000-spi
|
|
||||||
then:
|
|
||||||
properties:
|
|
||||||
reg:
|
|
||||||
maxItems: 1
|
|
||||||
clocks:
|
|
||||||
minItems: 2
|
|
||||||
clock-names:
|
|
||||||
minItems: 2
|
|
||||||
required:
|
|
||||||
- clock-names
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
|
|
@ -78,7 +63,6 @@ properties:
|
||||||
- mscc,jaguar2-spi
|
- mscc,jaguar2-spi
|
||||||
- sophgo,sg2042-spi
|
- sophgo,sg2042-spi
|
||||||
- thead,th1520-spi
|
- thead,th1520-spi
|
||||||
- ultrarisc,dp1000-spi
|
|
||||||
- const: snps,dw-apb-ssi
|
- const: snps,dw-apb-ssi
|
||||||
- description: Vendor controllers compatible with v1.01a
|
- description: Vendor controllers compatible with v1.01a
|
||||||
items:
|
items:
|
||||||
|
|
|
||||||
|
|
@ -176,68 +176,3 @@ Message from dmesg::
|
||||||
secondary_startup_64+0xa4/0xb0
|
secondary_startup_64+0xa4/0xb0
|
||||||
nvme nvme0: Could not set queue count (16385)
|
nvme nvme0: Could not set queue count (16385)
|
||||||
nvme nvme0: IO queues not created
|
nvme nvme0: IO queues not created
|
||||||
|
|
||||||
Example 4: Inject an error into the first write command
|
|
||||||
-------------------------------------------------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
echo 0x01 > /sys/kernel/debug/nvme0n1/fault_inject/opcode
|
|
||||||
echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times
|
|
||||||
echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability
|
|
||||||
dd if=/dev/zero of=/dev/nvme0n1 oflag=direct bs=512 count=1
|
|
||||||
|
|
||||||
Expected Result::
|
|
||||||
|
|
||||||
The first write command sent to nvme0n1 fails
|
|
||||||
|
|
||||||
Message from dmesg::
|
|
||||||
|
|
||||||
FAULT_INJECTION: forcing a failure.
|
|
||||||
name fault_inject, interval 1, probability 100, space 0, times 1
|
|
||||||
CPU: 4 UID: 0 PID: 0 Comm: swapper/4 Not tainted 7.1.0+ #5 PREEMPT(full)
|
|
||||||
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-20240910_120124-localhost 04/01/2014
|
|
||||||
Call Trace:
|
|
||||||
<IRQ>
|
|
||||||
dump_stack_lvl+0x6e/0xa0
|
|
||||||
dump_stack+0x10/0x16
|
|
||||||
should_fail_ex+0x461/0x510
|
|
||||||
should_fail+0xb/0x20
|
|
||||||
nvme_should_fail+0x11b/0x240 [nvme_core]
|
|
||||||
nvme_poll_cq+0x6ad/0xb30 [nvme]
|
|
||||||
nvme_irq+0x84/0xe0 [nvme]
|
|
||||||
? __pfx_nvme_irq+0x10/0x10 [nvme]
|
|
||||||
? rcu_core+0xa40/0xa90
|
|
||||||
? __pfx_sched_balance_softirq+0x10/0x10
|
|
||||||
? debug_smp_processor_id+0x17/0x20
|
|
||||||
? rcu_is_watching+0x13/0xa0
|
|
||||||
__handle_irq_event_percpu+0x396/0x610
|
|
||||||
handle_irq_event_percpu+0xf/0x90
|
|
||||||
handle_irq_event+0xab/0x110
|
|
||||||
handle_edge_irq+0x1a3/0x210
|
|
||||||
__common_interrupt+0xff/0x170
|
|
||||||
common_interrupt+0x90/0xc0
|
|
||||||
</IRQ>
|
|
||||||
<TASK>
|
|
||||||
asm_common_interrupt+0x27/0x40
|
|
||||||
RIP: 0010:pv_native_safe_halt+0x13/0x20
|
|
||||||
Code: 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 8b 05 0a 2a 58 01 85 c0 7e 07 0f 00 2d ff cc 0d 00 fb f4 <c3> cc 0
|
|
||||||
RSP: 0018:ffff888100a67e40 EFLAGS: 00000242
|
|
||||||
RAX: 0000000000000001 RBX: ffff888100a49c40 RCX: ffffed102b6c645b
|
|
||||||
RDX: ffffed102b6c645b RSI: ffffffff82a0d3c0 RDI: ffffffff81428b9b
|
|
||||||
RBP: ffff888100a67e48 R08: ffffed102b6c645b R09: 0000000000000004
|
|
||||||
R10: ffffed102b6c645a R11: 0000000000000001 R12: 0000000000000000
|
|
||||||
R13: 0000000000000000 R14: ffffed1020149388 R15: dffffc0000000000
|
|
||||||
? do_idle+0x19b/0x2c0
|
|
||||||
? default_idle+0x9/0x20
|
|
||||||
arch_cpu_idle+0x9/0x10
|
|
||||||
default_idle_call+0x6b/0xa0
|
|
||||||
do_idle+0x19b/0x2c0
|
|
||||||
? __pfx_do_idle+0x10/0x10
|
|
||||||
? complete_with_flags+0x63/0x70
|
|
||||||
cpu_startup_entry+0x55/0x60
|
|
||||||
start_secondary+0x1df/0x1e0
|
|
||||||
common_startup_64+0x13e/0x158
|
|
||||||
</TASK>
|
|
||||||
nvme0n1: Write(0x1) @ LBA 0, 1 blocks, Invalid Command Opcode (sct 0x0 / sc 0x1) DNR
|
|
||||||
operation not supported error, dev nvme0n1, sector 0 op 0x1:(WRITE) flags 0x8800 phys_seg 1 prio class 2
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ pwm1_enable
|
||||||
at full speed. Write "1" to set to manual, write "2" to let the EC control
|
at full speed. Write "1" to set to manual, write "2" to let the EC control
|
||||||
decide fan speed. Read this attribute to see current status.
|
decide fan speed. Read this attribute to see current status.
|
||||||
|
|
||||||
NB: In consideration of the safety of the device, when setting to manual mode,
|
NB:In consideration of the safety of the device, when setting to manual mode,
|
||||||
the pwm speed will be set to the maximum value (255) by default. You can set
|
the pwm speed will be set to the maximum value (255) by default. You can set
|
||||||
a different value by writing pwm1 later.
|
a different value by writing pwm1 later.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,6 @@ register/unregister functions::
|
||||||
|
|
||||||
char *devm_hwmon_sanitize_name(struct device *dev, const char *name);
|
char *devm_hwmon_sanitize_name(struct device *dev, const char *name);
|
||||||
|
|
||||||
int hwmon_notify_event(struct device *dev, enum hwmon_sensor_types type,
|
|
||||||
u32 attr, int channel);
|
|
||||||
|
|
||||||
void hwmon_lock(struct device *dev);
|
void hwmon_lock(struct device *dev);
|
||||||
void hwmon_unlock(struct device *dev);
|
void hwmon_unlock(struct device *dev);
|
||||||
|
|
||||||
|
|
@ -93,18 +90,6 @@ implemented in the driver, or debugfs functions, hwmon_lock() and hwmon_unlock()
|
||||||
can be used to ensure that calls to those functions are serialized. Those
|
can be used to ensure that calls to those functions are serialized. Those
|
||||||
functions also support guard() and scoped_guard() variants.
|
functions also support guard() and scoped_guard() variants.
|
||||||
|
|
||||||
Drivers can call hwmon_notify_event() to notify userspace and the thermal
|
|
||||||
subsystem when a hardware monitoring event (such as an alarm or a fault
|
|
||||||
condition) occurs or clears. The parameters are the hwmon device, the sensor
|
|
||||||
type, the attribute identifier associated with the event (such as
|
|
||||||
hwmon_temp_max_alarm or hwmon_fan_fault), and the sensor channel number.
|
|
||||||
hwmon_notify_event() generates a sysfs event (calling sysfs_notify()) and a
|
|
||||||
udev event with the attribute name passed in the NAME environment property
|
|
||||||
(e.g., "NAME=temp1_max_alarm"). If the event is for a temperature sensor and
|
|
||||||
the sensor is attached to a thermal zone, it also notifies the thermal
|
|
||||||
subsystem to update the thermal zone. hwmon_notify_event() returns 0 on
|
|
||||||
success or a negative error code on failure.
|
|
||||||
|
|
||||||
Using devm_hwmon_device_register_with_info()
|
Using devm_hwmon_device_register_with_info()
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -360,17 +360,6 @@ attribute-sets:
|
||||||
name: tsoff
|
name: tsoff
|
||||||
type: u32
|
type: u32
|
||||||
byte-order: big-endian
|
byte-order: big-endian
|
||||||
-
|
|
||||||
name: filter-attrs
|
|
||||||
attributes:
|
|
||||||
-
|
|
||||||
name: orig-flags
|
|
||||||
type: u32
|
|
||||||
doc: bitmask of tuple fields to filter on, original direction
|
|
||||||
-
|
|
||||||
name: reply-flags
|
|
||||||
type: u32
|
|
||||||
doc: bitmask of tuple fields to filter on, reply direction
|
|
||||||
-
|
-
|
||||||
name: conntrack-attrs
|
name: conntrack-attrs
|
||||||
attributes:
|
attributes:
|
||||||
|
|
@ -477,7 +466,7 @@ attribute-sets:
|
||||||
-
|
-
|
||||||
name: filter
|
name: filter
|
||||||
type: nest
|
type: nest
|
||||||
nested-attributes: filter-attrs
|
nested-attributes: tuple-attrs
|
||||||
-
|
-
|
||||||
name: status-mask
|
name: status-mask
|
||||||
type: u32
|
type: u32
|
||||||
|
|
@ -602,14 +591,10 @@ operations:
|
||||||
request:
|
request:
|
||||||
value: 0x101
|
value: 0x101
|
||||||
attributes:
|
attributes:
|
||||||
- tuple-orig
|
|
||||||
- tuple-reply
|
|
||||||
- status
|
|
||||||
- mark
|
- mark
|
||||||
- zone
|
|
||||||
- mark-mask
|
|
||||||
- filter
|
- filter
|
||||||
- status-mask
|
- status
|
||||||
|
- zone
|
||||||
reply:
|
reply:
|
||||||
value: 0x100
|
value: 0x100
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
||||||
|
|
@ -898,8 +898,6 @@ attribute-sets:
|
||||||
-
|
-
|
||||||
name: txqlen
|
name: txqlen
|
||||||
type: u32
|
type: u32
|
||||||
checks:
|
|
||||||
max: 32767
|
|
||||||
-
|
-
|
||||||
name: map
|
name: map
|
||||||
type: binary
|
type: binary
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ optional. The following modified excerpt is from
|
||||||
|
|
||||||
void BPF_STRUCT_OPS(simple_exit, struct scx_exit_info *ei)
|
void BPF_STRUCT_OPS(simple_exit, struct scx_exit_info *ei)
|
||||||
{
|
{
|
||||||
exit_type = ei->kind;
|
exit_type = ei->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEC(".struct_ops")
|
SEC(".struct_ops")
|
||||||
|
|
@ -242,21 +242,6 @@ optional. The following modified excerpt is from
|
||||||
.name = "simple",
|
.name = "simple",
|
||||||
};
|
};
|
||||||
|
|
||||||
Scheduler-Dependent Knobs
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
The fair-class scheduler enforces CPU controller settings such as
|
|
||||||
``cpu.max``, ``cpu.weight`` and ``cpu.idle``. For sched_ext tasks, the
|
|
||||||
scheduler core communicates these settings to the BPF scheduler
|
|
||||||
through ``ops.cgroup_init()`` and reports subsequent changes through
|
|
||||||
the corresponding ``ops.cgroup_set_*()`` callbacks. Similarly, per-task
|
|
||||||
nice changes are converted to weights and reported through
|
|
||||||
``ops.set_weight()``.
|
|
||||||
|
|
||||||
Each BPF scheduler is responsible for implementing the scheduling
|
|
||||||
semantics of these settings and may choose to ignore them. Consult the
|
|
||||||
loaded scheduler's documentation before relying on these controls.
|
|
||||||
|
|
||||||
Dispatch Queues
|
Dispatch Queues
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,41 +15,19 @@ arch/riscv 开发者维护指南
|
||||||
|
|
||||||
概述
|
概述
|
||||||
----
|
----
|
||||||
RISC-V 指令集体系结构是公开开发的:
|
RISC-V指令集体系结构是公开开发的:
|
||||||
正在进行的草案可供所有人查看和测试实现。新模块或者扩展草案可能会在开发过程中发
|
正在进行的草案可供所有人查看和测试实现。新模块或者扩展草案可能会在开发过程中发
|
||||||
生更改 --- 有时以不兼容的方式对以前的草案进行更改。这种灵活性可能会给 RISC-V
|
生更改---有时以不兼容的方式对以前的草案进行更改。这种灵活性可能会给RISC-V Linux
|
||||||
Linux 维护者带来挑战。Linux 维护者不赞成频繁的变更,且 Linux 开发过程更喜欢经过
|
维护者带来挑战。Linux开发过程更喜欢经过良好检查和测试的代码,而不是试验代码。我
|
||||||
良好检查和测试的代码,而不是试验代码。我们希望推广同样的规则到即将被内核合并的
|
们希望推广同样的规则到即将被内核合并的RISC-V相关代码。
|
||||||
RISC-V 相关代码。
|
|
||||||
|
|
||||||
Patchwork
|
|
||||||
---------
|
|
||||||
|
|
||||||
RISC-V 有一个 patchwork 实例,可以在那里查看补丁的状态:
|
|
||||||
|
|
||||||
https://patchwork.kernel.org/project/linux-riscv/list/
|
|
||||||
|
|
||||||
如果你的补丁不在默认视图中出现,那么 RISC-V 维护者很有可能已要求修改,或者希望
|
|
||||||
将其应用到另一个代码树上。
|
|
||||||
|
|
||||||
自动化流程会在该 patchwork 实例上运行,在每个补丁到达时立刻对其进行构建/测试。
|
|
||||||
自动化流程会根据补丁是否被识别为修复,选用 RISC-V `for-next` 或 `fixes` 分支
|
|
||||||
当前的 HEAD;若上述均应用失败,则使用 RISC-V `master` 分支。补丁系列被应用到的具
|
|
||||||
体提交将标注在 patchwork 上。任何检查未通过的补丁通常不会被应用,并且在大多数情
|
|
||||||
况下将需要重新提交。
|
|
||||||
|
|
||||||
附加的提交检查单
|
附加的提交检查单
|
||||||
----------------
|
----------------
|
||||||
我们仅接受针对新模块或扩展的补丁,前提是这些模块或扩展的规范被列为未来不太可能发
|
我们仅接受相关标准已经被RISC-V基金会标准为“已批准”或“已冻结”的扩展或模块的补丁。
|
||||||
生不兼容的变更。对于来自 RISC-V 基金会的规范,这意味着“已冻结”或“已批准”,对于
|
(开发者当然可以维护自己的Linux内核树,其中包含所需代码扩展草案的代码。)
|
||||||
UEFI 论坛的规范,这意味着已发布的 ECR。(开发者当然可以维护自己的 Linux 内核树,
|
|
||||||
其中包含他们所需的任何扩展草案的代码。)
|
|
||||||
|
|
||||||
此外,RISC-V 规范允许实现者创建自己的自定义扩展。这些自定义扩展不需要通过 RISC-V
|
此外,RISC-V规范允许爱好者创建自己的自定义扩展。这些自定义拓展不需要通过RISC-V
|
||||||
基金会的任何审核或批准流程。为了避免因添加实现者特定的 RISC-V 扩展带来的维护复杂
|
基金会的任何审核或批准。为了避免将爱好者一些特别的RISC-V拓展添加进内核代码带来
|
||||||
性和对性能的潜在影响,我们将只考虑符合以下任一条件的扩展补丁:
|
的维护复杂性和对性能的潜在影响,我们将只接受RISC-V基金会正式冻结或批准的的扩展
|
||||||
|
补丁。(开发者当然可以维护自己的Linux内核树,其中包含他们想要的任何自定义扩展
|
||||||
- 已由 RISC-V 基金会正式冻结或批准
|
的代码。)
|
||||||
- 已按照标准 Linux 惯例,在广泛可用的硬件中实现
|
|
||||||
|
|
||||||
(实现者当然可以维护自己的 Linux 内核树,其中包含他们所需的任何自定义扩展的代码。)
|
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,10 @@ irq_domain映射的类型
|
||||||
映射的优点是固定时间查找IRQ号,而且irq_descs只分配给在用的IRQ。 缺点是该表
|
映射的优点是固定时间查找IRQ号,而且irq_descs只分配给在用的IRQ。 缺点是该表
|
||||||
必须尽可能大的hwirq号。
|
必须尽可能大的hwirq号。
|
||||||
|
|
||||||
|
irq_domain_add_linear()和irq_domain_create_linear()在功能上是等价的,
|
||||||
|
除了第一个参数不同--前者接受一个Open Firmware特定的 'struct device_node' 而
|
||||||
|
后者接受一个更通用的抽象 'struct fwnode_handle' 。
|
||||||
|
|
||||||
大多数驱动应该使用线性映射
|
大多数驱动应该使用线性映射
|
||||||
|
|
||||||
树状映射
|
树状映射
|
||||||
|
|
|
||||||
62
MAINTAINERS
62
MAINTAINERS
|
|
@ -4512,7 +4512,7 @@ AYANEO PLATFORM EC DRIVER
|
||||||
M: Antheas Kapenekakis <lkml@antheas.dev>
|
M: Antheas Kapenekakis <lkml@antheas.dev>
|
||||||
L: platform-driver-x86@vger.kernel.org
|
L: platform-driver-x86@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/ABI/testing/sysfs-platform-ayaneo-ec
|
F: Documentation/ABI/testing/sysfs-platform-ayaneo
|
||||||
F: drivers/platform/x86/ayaneo-ec.c
|
F: drivers/platform/x86/ayaneo-ec.c
|
||||||
|
|
||||||
AZ6007 DVB DRIVER
|
AZ6007 DVB DRIVER
|
||||||
|
|
@ -5671,8 +5671,8 @@ W: http://bu3sch.de/btgpio.php
|
||||||
F: drivers/gpio/gpio-bt8xx.c
|
F: drivers/gpio/gpio-bt8xx.c
|
||||||
|
|
||||||
BTRFS FILE SYSTEM
|
BTRFS FILE SYSTEM
|
||||||
|
M: Chris Mason <clm@fb.com>
|
||||||
M: David Sterba <dsterba@suse.com>
|
M: David Sterba <dsterba@suse.com>
|
||||||
R: Chris Mason <mason@kernel.org>
|
|
||||||
L: linux-btrfs@vger.kernel.org
|
L: linux-btrfs@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
W: https://btrfs.readthedocs.io
|
W: https://btrfs.readthedocs.io
|
||||||
|
|
@ -8039,7 +8039,7 @@ F: drivers/gpu/drm/sun4i/sun8i*
|
||||||
|
|
||||||
DRM DRIVER FOR APPLE TOUCH BARS
|
DRM DRIVER FOR APPLE TOUCH BARS
|
||||||
M: Aun-Ali Zaidi <admin@kodeit.net>
|
M: Aun-Ali Zaidi <admin@kodeit.net>
|
||||||
M: Aditya Garg <aditya.garg@linux.dev>
|
M: Aditya Garg <gargaditya08@proton.me>
|
||||||
L: dri-devel@lists.freedesktop.org
|
L: dri-devel@lists.freedesktop.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||||
|
|
@ -9387,8 +9387,9 @@ S: Maintained
|
||||||
F: drivers/edac/octeon_edac*
|
F: drivers/edac/octeon_edac*
|
||||||
|
|
||||||
EDAC-CAVIUM THUNDERX
|
EDAC-CAVIUM THUNDERX
|
||||||
|
M: Robert Richter <rric@kernel.org>
|
||||||
L: linux-edac@vger.kernel.org
|
L: linux-edac@vger.kernel.org
|
||||||
S: Orphan
|
S: Odd Fixes
|
||||||
F: drivers/edac/thunderx_edac*
|
F: drivers/edac/thunderx_edac*
|
||||||
|
|
||||||
EDAC-CORE
|
EDAC-CORE
|
||||||
|
|
@ -9415,8 +9416,9 @@ S: Supported
|
||||||
F: drivers/edac/dmc520_edac.c
|
F: drivers/edac/dmc520_edac.c
|
||||||
|
|
||||||
EDAC-E752X
|
EDAC-E752X
|
||||||
|
M: Mark Gross <markgross@kernel.org>
|
||||||
L: linux-edac@vger.kernel.org
|
L: linux-edac@vger.kernel.org
|
||||||
S: Orphan
|
S: Maintained
|
||||||
F: drivers/edac/e752x_edac.c
|
F: drivers/edac/e752x_edac.c
|
||||||
|
|
||||||
EDAC-E7XXX
|
EDAC-E7XXX
|
||||||
|
|
@ -9491,8 +9493,9 @@ S: Maintained
|
||||||
F: drivers/edac/igen6_edac.c
|
F: drivers/edac/igen6_edac.c
|
||||||
|
|
||||||
EDAC-MPC85XX
|
EDAC-MPC85XX
|
||||||
|
M: Johannes Thumshirn <morbidrsa@gmail.com>
|
||||||
L: linux-edac@vger.kernel.org
|
L: linux-edac@vger.kernel.org
|
||||||
S: Orphan
|
S: Maintained
|
||||||
F: drivers/edac/mpc85xx_edac.[ch]
|
F: drivers/edac/mpc85xx_edac.[ch]
|
||||||
|
|
||||||
EDAC-NPCM
|
EDAC-NPCM
|
||||||
|
|
@ -10190,6 +10193,7 @@ F: include/linux/arm_ffa.h
|
||||||
|
|
||||||
FIRMWARE LOADER (request_firmware)
|
FIRMWARE LOADER (request_firmware)
|
||||||
M: Luis Chamberlain <mcgrof@kernel.org>
|
M: Luis Chamberlain <mcgrof@kernel.org>
|
||||||
|
M: Russ Weight <russ.weight@linux.dev>
|
||||||
M: Danilo Krummrich <dakr@kernel.org>
|
M: Danilo Krummrich <dakr@kernel.org>
|
||||||
L: driver-core@lists.linux.dev
|
L: driver-core@lists.linux.dev
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
@ -12220,7 +12224,7 @@ F: drivers/tty/hvc/
|
||||||
|
|
||||||
HUNG TASK DETECTOR
|
HUNG TASK DETECTOR
|
||||||
M: Andrew Morton <akpm@linux-foundation.org>
|
M: Andrew Morton <akpm@linux-foundation.org>
|
||||||
M: Lance Yang <lance.yang@linux.dev>
|
R: Lance Yang <lance.yang@linux.dev>
|
||||||
R: Masami Hiramatsu <mhiramat@kernel.org>
|
R: Masami Hiramatsu <mhiramat@kernel.org>
|
||||||
R: Petr Mladek <pmladek@suse.com>
|
R: Petr Mladek <pmladek@suse.com>
|
||||||
L: linux-kernel@vger.kernel.org
|
L: linux-kernel@vger.kernel.org
|
||||||
|
|
@ -13279,6 +13283,7 @@ F: drivers/crypto/intel/keembay/ocs-aes.h
|
||||||
|
|
||||||
INTEL KEEM BAY OCS ECC CRYPTO DRIVER
|
INTEL KEEM BAY OCS ECC CRYPTO DRIVER
|
||||||
M: Prabhjot Khurana <prabhjot.khurana@intel.com>
|
M: Prabhjot Khurana <prabhjot.khurana@intel.com>
|
||||||
|
M: Mark Gross <mgross@linux.intel.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/crypto/intel,keembay-ocs-ecc.yaml
|
F: Documentation/devicetree/bindings/crypto/intel,keembay-ocs-ecc.yaml
|
||||||
F: drivers/crypto/intel/keembay/Kconfig
|
F: drivers/crypto/intel/keembay/Kconfig
|
||||||
|
|
@ -14235,6 +14240,8 @@ F: tools/testing/selftests/
|
||||||
KERNEL SMB3 SERVER (KSMBD)
|
KERNEL SMB3 SERVER (KSMBD)
|
||||||
M: Namjae Jeon <linkinjeon@kernel.org>
|
M: Namjae Jeon <linkinjeon@kernel.org>
|
||||||
M: Namjae Jeon <linkinjeon@samba.org>
|
M: Namjae Jeon <linkinjeon@samba.org>
|
||||||
|
M: Steve French <smfrench@gmail.com>
|
||||||
|
M: Steve French <sfrench@samba.org>
|
||||||
R: Sergey Senozhatsky <senozhatsky@chromium.org>
|
R: Sergey Senozhatsky <senozhatsky@chromium.org>
|
||||||
R: Tom Talpey <tom@talpey.com>
|
R: Tom Talpey <tom@talpey.com>
|
||||||
R: ChenXiaoSong <chenxiaosong@chenxiaosong.com>
|
R: ChenXiaoSong <chenxiaosong@chenxiaosong.com>
|
||||||
|
|
@ -15020,8 +15027,6 @@ M: Madhavan Srinivasan <maddy@linux.ibm.com>
|
||||||
R: Michael Ellerman <mpe@ellerman.id.au>
|
R: Michael Ellerman <mpe@ellerman.id.au>
|
||||||
R: Nicholas Piggin <npiggin@gmail.com>
|
R: Nicholas Piggin <npiggin@gmail.com>
|
||||||
R: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
|
R: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
|
||||||
R: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
|
|
||||||
R: Shrikanth Hegde <sshegde@linux.ibm.com>
|
|
||||||
L: linuxppc-dev@lists.ozlabs.org
|
L: linuxppc-dev@lists.ozlabs.org
|
||||||
S: Supported
|
S: Supported
|
||||||
W: https://github.com/linuxppc/wiki/wiki
|
W: https://github.com/linuxppc/wiki/wiki
|
||||||
|
|
@ -17411,6 +17416,7 @@ F: mm/swapfile.c
|
||||||
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
|
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
|
||||||
M: Andrew Morton <akpm@linux-foundation.org>
|
M: Andrew Morton <akpm@linux-foundation.org>
|
||||||
M: David Hildenbrand <david@kernel.org>
|
M: David Hildenbrand <david@kernel.org>
|
||||||
|
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||||
R: Zi Yan <ziy@nvidia.com>
|
R: Zi Yan <ziy@nvidia.com>
|
||||||
R: Baolin Wang <baolin.wang@linux.alibaba.com>
|
R: Baolin Wang <baolin.wang@linux.alibaba.com>
|
||||||
R: Liam R. Howlett <liam@infradead.org>
|
R: Liam R. Howlett <liam@infradead.org>
|
||||||
|
|
@ -17420,7 +17426,6 @@ R: Dev Jain <dev.jain@arm.com>
|
||||||
R: Barry Song <baohua@kernel.org>
|
R: Barry Song <baohua@kernel.org>
|
||||||
R: Lance Yang <lance.yang@linux.dev>
|
R: Lance Yang <lance.yang@linux.dev>
|
||||||
R: Usama Arif <usama.arif@linux.dev>
|
R: Usama Arif <usama.arif@linux.dev>
|
||||||
R: Kiryl Shutsemau <kas@kernel.org>
|
|
||||||
L: linux-mm@kvack.org
|
L: linux-mm@kvack.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
W: http://www.linux-mm.org
|
W: http://www.linux-mm.org
|
||||||
|
|
@ -17693,7 +17698,7 @@ F: Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
|
||||||
F: drivers/spi/spi-at91-usart.c
|
F: drivers/spi/spi-at91-usart.c
|
||||||
|
|
||||||
MICROCHIP ATSHA204A DRIVER
|
MICROCHIP ATSHA204A DRIVER
|
||||||
M: Thorsten Blum <blum@kernel.org>
|
M: Thorsten Blum <thorsten.blum@linux.dev>
|
||||||
L: linux-crypto@vger.kernel.org
|
L: linux-crypto@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/crypto/atmel-sha204a.c
|
F: drivers/crypto/atmel-sha204a.c
|
||||||
|
|
@ -17717,7 +17722,7 @@ F: Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
|
||||||
F: drivers/media/platform/microchip/microchip-csi2dc.c
|
F: drivers/media/platform/microchip/microchip-csi2dc.c
|
||||||
|
|
||||||
MICROCHIP ECC DRIVER
|
MICROCHIP ECC DRIVER
|
||||||
M: Thorsten Blum <blum@kernel.org>
|
M: Thorsten Blum <thorsten.blum@linux.dev>
|
||||||
L: linux-crypto@vger.kernel.org
|
L: linux-crypto@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/crypto/atmel-ecc.c
|
F: drivers/crypto/atmel-ecc.c
|
||||||
|
|
@ -19564,7 +19569,7 @@ F: include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h
|
||||||
|
|
||||||
NVM EXPRESS DRIVER
|
NVM EXPRESS DRIVER
|
||||||
M: Keith Busch <kbusch@kernel.org>
|
M: Keith Busch <kbusch@kernel.org>
|
||||||
M: Jens Axboe <axboe@kernel.dk>
|
M: Jens Axboe <axboe@fb.com>
|
||||||
M: Christoph Hellwig <hch@lst.de>
|
M: Christoph Hellwig <hch@lst.de>
|
||||||
M: Sagi Grimberg <sagi@grimberg.me>
|
M: Sagi Grimberg <sagi@grimberg.me>
|
||||||
L: linux-nvme@lists.infradead.org
|
L: linux-nvme@lists.infradead.org
|
||||||
|
|
@ -24773,7 +24778,7 @@ K: \bsecurity_[a-z_0-9]\+\b
|
||||||
SELINUX SECURITY MODULE
|
SELINUX SECURITY MODULE
|
||||||
M: Paul Moore <paul@paul-moore.com>
|
M: Paul Moore <paul@paul-moore.com>
|
||||||
M: Stephen Smalley <stephen.smalley.work@gmail.com>
|
M: Stephen Smalley <stephen.smalley.work@gmail.com>
|
||||||
R: Ondrej Mosnáček <omosnacek@gmail.com>
|
R: Ondrej Mosnacek <omosnace@redhat.com>
|
||||||
L: selinux@vger.kernel.org
|
L: selinux@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
W: https://github.com/SELinuxProject
|
W: https://github.com/SELinuxProject
|
||||||
|
|
@ -25231,9 +25236,10 @@ F: Documentation/admin-guide/LSM/Smack.rst
|
||||||
F: security/smack/
|
F: security/smack/
|
||||||
|
|
||||||
SMBDIRECT (RDMA Stream Transport with Read/Write-Offload, MS-SMBD)
|
SMBDIRECT (RDMA Stream Transport with Read/Write-Offload, MS-SMBD)
|
||||||
|
M: Steve French <smfrench@gmail.com>
|
||||||
|
M: Steve French <sfrench@samba.org>
|
||||||
M: Namjae Jeon <linkinjeon@kernel.org>
|
M: Namjae Jeon <linkinjeon@kernel.org>
|
||||||
M: Namjae Jeon <linkinjeon@samba.org>
|
M: Namjae Jeon <linkinjeon@samba.org>
|
||||||
M: Paulo Alcantara <pc@manguebit.org>
|
|
||||||
R: Stefan Metzmacher <metze@samba.org>
|
R: Stefan Metzmacher <metze@samba.org>
|
||||||
R: Tom Talpey <tom@talpey.com>
|
R: Tom Talpey <tom@talpey.com>
|
||||||
L: linux-cifs@vger.kernel.org
|
L: linux-cifs@vger.kernel.org
|
||||||
|
|
@ -25336,8 +25342,8 @@ F: Documentation/networking/timestamping.rst
|
||||||
F: include/linux/net_tstamp.h
|
F: include/linux/net_tstamp.h
|
||||||
F: include/uapi/linux/net_tstamp.h
|
F: include/uapi/linux/net_tstamp.h
|
||||||
F: tools/testing/selftests/bpf/*/net_timestamping*
|
F: tools/testing/selftests/bpf/*/net_timestamping*
|
||||||
F: tools/testing/selftests/drivers/net/so_txtime.*
|
|
||||||
F: tools/testing/selftests/net/*timestamp*
|
F: tools/testing/selftests/net/*timestamp*
|
||||||
|
F: tools/testing/selftests/net/so_txtime.c
|
||||||
|
|
||||||
SOEKRIS NET48XX LED SUPPORT
|
SOEKRIS NET48XX LED SUPPORT
|
||||||
M: Chris Boot <bootc@bootc.net>
|
M: Chris Boot <bootc@bootc.net>
|
||||||
|
|
@ -25404,7 +25410,7 @@ F: drivers/md/md*
|
||||||
F: drivers/md/raid*
|
F: drivers/md/raid*
|
||||||
F: include/linux/raid/
|
F: include/linux/raid/
|
||||||
F: include/uapi/linux/raid/
|
F: include/uapi/linux/raid/
|
||||||
F: lib/raid/
|
F: lib/raid/raid6/
|
||||||
|
|
||||||
SOLIDRUN CLEARFOG SUPPORT
|
SOLIDRUN CLEARFOG SUPPORT
|
||||||
M: Russell King <linux@armlinux.org.uk>
|
M: Russell King <linux@armlinux.org.uk>
|
||||||
|
|
@ -26948,7 +26954,8 @@ S: Maintained
|
||||||
F: drivers/net/ethernet/tehuti/tn40*
|
F: drivers/net/ethernet/tehuti/tn40*
|
||||||
|
|
||||||
TELECOM CLOCK DRIVER FOR MCPL0010
|
TELECOM CLOCK DRIVER FOR MCPL0010
|
||||||
S: Orphan
|
M: Mark Gross <markgross@kernel.org>
|
||||||
|
S: Supported
|
||||||
F: drivers/char/tlclk.c
|
F: drivers/char/tlclk.c
|
||||||
|
|
||||||
TEMPO SEMICONDUCTOR DRIVERS
|
TEMPO SEMICONDUCTOR DRIVERS
|
||||||
|
|
@ -28609,6 +28616,7 @@ L: iommu@lists.linux.dev
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml
|
F: Documentation/devicetree/bindings/iommu/verisilicon,iommu.yaml
|
||||||
F: drivers/iommu/vsi-iommu.c
|
F: drivers/iommu/vsi-iommu.c
|
||||||
|
F: include/linux/vsi-iommu.h
|
||||||
|
|
||||||
VF610 NAND DRIVER
|
VF610 NAND DRIVER
|
||||||
M: Stefan Agner <stefan@agner.ch>
|
M: Stefan Agner <stefan@agner.ch>
|
||||||
|
|
@ -28868,8 +28876,8 @@ F: include/uapi/linux/virtio_console.h
|
||||||
VIRTIO CORE
|
VIRTIO CORE
|
||||||
M: "Michael S. Tsirkin" <mst@redhat.com>
|
M: "Michael S. Tsirkin" <mst@redhat.com>
|
||||||
M: Jason Wang <jasowangio@gmail.com>
|
M: Jason Wang <jasowangio@gmail.com>
|
||||||
M: Eugenio Pérez <eperezma@redhat.com>
|
|
||||||
R: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
|
R: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
|
||||||
|
R: Eugenio Pérez <eperezma@redhat.com>
|
||||||
L: virtualization@lists.linux.dev
|
L: virtualization@lists.linux.dev
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/ABI/testing/sysfs-bus-vdpa
|
F: Documentation/ABI/testing/sysfs-bus-vdpa
|
||||||
|
|
@ -28946,7 +28954,7 @@ F: include/uapi/linux/virtio_gpu.h
|
||||||
VIRTIO HOST (VHOST)
|
VIRTIO HOST (VHOST)
|
||||||
M: "Michael S. Tsirkin" <mst@redhat.com>
|
M: "Michael S. Tsirkin" <mst@redhat.com>
|
||||||
M: Jason Wang <jasowangio@gmail.com>
|
M: Jason Wang <jasowangio@gmail.com>
|
||||||
M: Eugenio Pérez <eperezma@redhat.com>
|
R: Eugenio Pérez <eperezma@redhat.com>
|
||||||
L: kvm@vger.kernel.org
|
L: kvm@vger.kernel.org
|
||||||
L: virtualization@lists.linux.dev
|
L: virtualization@lists.linux.dev
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
|
|
@ -29001,8 +29009,8 @@ F: include/uapi/linux/virtio_mem.h
|
||||||
VIRTIO NET DRIVER
|
VIRTIO NET DRIVER
|
||||||
M: "Michael S. Tsirkin" <mst@redhat.com>
|
M: "Michael S. Tsirkin" <mst@redhat.com>
|
||||||
M: Jason Wang <jasowangio@gmail.com>
|
M: Jason Wang <jasowangio@gmail.com>
|
||||||
M: Eugenio Pérez <eperezma@redhat.com>
|
|
||||||
R: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
|
R: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
|
||||||
|
R: Eugenio Pérez <eperezma@redhat.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
L: virtualization@lists.linux.dev
|
L: virtualization@lists.linux.dev
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
@ -29018,13 +29026,6 @@ S: Maintained
|
||||||
F: drivers/nvdimm/nd_virtio.c
|
F: drivers/nvdimm/nd_virtio.c
|
||||||
F: drivers/nvdimm/virtio_pmem.c
|
F: drivers/nvdimm/virtio_pmem.c
|
||||||
|
|
||||||
VIRTIO RNG DRIVER
|
|
||||||
M: Laurent Vivier <lvivier@redhat.com>
|
|
||||||
L: virtualization@lists.linux.dev
|
|
||||||
S: Maintained
|
|
||||||
F: drivers/char/hw_random/virtio-rng.c
|
|
||||||
F: include/uapi/linux/virtio_rng.h
|
|
||||||
|
|
||||||
VIRTIO RTC DRIVER
|
VIRTIO RTC DRIVER
|
||||||
M: Peter Hilber <peter.hilber@oss.qualcomm.com>
|
M: Peter Hilber <peter.hilber@oss.qualcomm.com>
|
||||||
L: virtualization@lists.linux.dev
|
L: virtualization@lists.linux.dev
|
||||||
|
|
@ -29356,7 +29357,7 @@ M: Guenter Roeck <linux@roeck-us.net>
|
||||||
L: linux-watchdog@vger.kernel.org
|
L: linux-watchdog@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
W: http://www.linux-watchdog.org/
|
W: http://www.linux-watchdog.org/
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
|
T: git git://www.linux-watchdog.org/linux-watchdog.git
|
||||||
F: Documentation/devicetree/bindings/watchdog/
|
F: Documentation/devicetree/bindings/watchdog/
|
||||||
F: Documentation/watchdog/
|
F: Documentation/watchdog/
|
||||||
F: drivers/watchdog/
|
F: drivers/watchdog/
|
||||||
|
|
@ -29936,14 +29937,12 @@ F: include/uapi/linux/xilinx-v4l2-controls.h
|
||||||
XILINX VERSAL EDAC DRIVER
|
XILINX VERSAL EDAC DRIVER
|
||||||
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
|
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
|
||||||
M: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
|
M: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
|
||||||
R: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-ddrmc-edac.yaml
|
F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-ddrmc-edac.yaml
|
||||||
F: drivers/edac/versal_edac.c
|
F: drivers/edac/versal_edac.c
|
||||||
|
|
||||||
XILINX VERSALNET EDAC DRIVER
|
XILINX VERSALNET EDAC DRIVER
|
||||||
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
|
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
|
||||||
R: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-net-ddrmc5.yaml
|
F: Documentation/devicetree/bindings/memory-controllers/xlnx,versal-net-ddrmc5.yaml
|
||||||
F: drivers/edac/versalnet_edac.c
|
F: drivers/edac/versalnet_edac.c
|
||||||
|
|
@ -29989,7 +29988,6 @@ F: include/dt-bindings/dma/xlnx-zynqmp-dpdma.h
|
||||||
XILINX ZYNQMP OCM EDAC DRIVER
|
XILINX ZYNQMP OCM EDAC DRIVER
|
||||||
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
|
M: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
|
||||||
M: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
|
M: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com>
|
||||||
R: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
|
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/memory-controllers/xlnx,zynqmp-ocmc-1.0.yaml
|
F: Documentation/devicetree/bindings/memory-controllers/xlnx,zynqmp-ocmc-1.0.yaml
|
||||||
F: drivers/edac/zynqmp_edac.c
|
F: drivers/edac/zynqmp_edac.c
|
||||||
|
|
|
||||||
2
Makefile
2
Makefile
|
|
@ -2,7 +2,7 @@
|
||||||
VERSION = 7
|
VERSION = 7
|
||||||
PATCHLEVEL = 3
|
PATCHLEVEL = 3
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc2
|
EXTRAVERSION = -rc1
|
||||||
NAME = Baby Opossum Posse
|
NAME = Baby Opossum Posse
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ static int aesbs_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
|
||||||
struct crypto_aes_ctx *rk;
|
struct crypto_aes_ctx *rk;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
rk = kmalloc_obj(*rk);
|
rk = kmalloc(sizeof(*rk), GFP_KERNEL);
|
||||||
if (!rk)
|
if (!rk)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@ static int aesbs_cbc_ctr_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
|
||||||
struct crypto_aes_ctx *rk;
|
struct crypto_aes_ctx *rk;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
rk = kmalloc_obj(*rk);
|
rk = kmalloc(sizeof(*rk), GFP_KERNEL);
|
||||||
if (!rk)
|
if (!rk)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,5 @@ void __init cpuinfo_store_boot_cpu(void);
|
||||||
void __init init_cpu_features(struct cpuinfo_arm64 *info);
|
void __init init_cpu_features(struct cpuinfo_arm64 *info);
|
||||||
void update_cpu_features(int cpu, struct cpuinfo_arm64 *info,
|
void update_cpu_features(int cpu, struct cpuinfo_arm64 *info,
|
||||||
struct cpuinfo_arm64 *boot);
|
struct cpuinfo_arm64 *boot);
|
||||||
bool gmid_el1_accessible(const struct cpuinfo_arm64 *info);
|
|
||||||
|
|
||||||
#endif /* __ASM_CPU_H */
|
#endif /* __ASM_CPU_H */
|
||||||
|
|
|
||||||
|
|
@ -627,6 +627,13 @@ static inline bool id_aa64pfr1_mpamfrac(u64 pfr1)
|
||||||
return val > 0;
|
return val > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool id_aa64pfr1_mte(u64 pfr1)
|
||||||
|
{
|
||||||
|
u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_EL1_MTE_SHIFT);
|
||||||
|
|
||||||
|
return val >= ID_AA64PFR1_EL1_MTE_MTE2;
|
||||||
|
}
|
||||||
|
|
||||||
void __init setup_boot_cpu_features(void);
|
void __init setup_boot_cpu_features(void);
|
||||||
void __init setup_system_features(void);
|
void __init setup_system_features(void);
|
||||||
void __init setup_user_features(void);
|
void __init setup_user_features(void);
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
|
||||||
|
|
||||||
for (i = 0; i < target_impl_cpu_num; i++) {
|
for (i = 0; i < target_impl_cpu_num; i++) {
|
||||||
if (__is_affected_midr_range(entry, target_impl_cpus[i].midr,
|
if (__is_affected_midr_range(entry, target_impl_cpus[i].midr,
|
||||||
target_impl_cpus[i].revidr))
|
target_impl_cpus[i].midr))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1178,33 +1178,6 @@ static bool detect_ftr_has_mpam(void)
|
||||||
return id_aa64pfr0_mpam(pfr0) || id_aa64pfr1_mpamfrac(pfr1);
|
return id_aa64pfr0_mpam(pfr0) || id_aa64pfr1_mpamfrac(pfr1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gmid_el1_accessible(const struct cpuinfo_arm64 *info)
|
|
||||||
{
|
|
||||||
const struct arm64_ftr_bits *ftrp;
|
|
||||||
s64 mte, ovr;
|
|
||||||
u64 ftr_mask;
|
|
||||||
|
|
||||||
/* No ID register reflects CONFIG_ARM64_MTE. */
|
|
||||||
if (!IS_ENABLED(CONFIG_ARM64_MTE))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (ftrp = ftr_id_aa64pfr1; ftrp->width; ftrp++) {
|
|
||||||
if (ftrp->shift == ID_AA64PFR1_EL1_MTE_SHIFT)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ftr_mask = arm64_ftr_mask(ftrp);
|
|
||||||
mte = arm64_ftr_value(ftrp, info->reg_id_aa64pfr1);
|
|
||||||
|
|
||||||
/* The boot CPU runs before init_cpu_ftr_reg() strips unsafe overrides. */
|
|
||||||
if ((id_aa64pfr1_override.mask & ftr_mask) == ftr_mask) {
|
|
||||||
ovr = arm64_ftr_value(ftrp, id_aa64pfr1_override.val);
|
|
||||||
mte = arm64_ftr_safe_value(ftrp, ovr, mte);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mte >= ID_AA64PFR1_EL1_MTE_MTE2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||||
{
|
{
|
||||||
/* Before we start using the tables, make sure it is sorted */
|
/* Before we start using the tables, make sure it is sorted */
|
||||||
|
|
@ -1257,7 +1230,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||||
init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr);
|
init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gmid_el1_accessible(info))
|
if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
|
||||||
init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);
|
init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1519,9 +1492,11 @@ void update_cpu_features(int cpu,
|
||||||
* they read/write depends on the GMID_EL1.BS field. Check that the
|
* they read/write depends on the GMID_EL1.BS field. Check that the
|
||||||
* value is the same on all CPUs.
|
* value is the same on all CPUs.
|
||||||
*/
|
*/
|
||||||
if (gmid_el1_accessible(info))
|
if (IS_ENABLED(CONFIG_ARM64_MTE) &&
|
||||||
|
id_aa64pfr1_mte(info->reg_id_aa64pfr1)) {
|
||||||
taint |= check_update_ftr_reg(SYS_GMID_EL1, cpu,
|
taint |= check_update_ftr_reg(SYS_GMID_EL1, cpu,
|
||||||
info->reg_gmid, boot->reg_gmid);
|
info->reg_gmid, boot->reg_gmid);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we don't have AArch32 at all then skip the checks entirely
|
* If we don't have AArch32 at all then skip the checks entirely
|
||||||
|
|
|
||||||
|
|
@ -502,7 +502,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
|
||||||
info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1);
|
info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1);
|
||||||
info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1);
|
info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1);
|
||||||
|
|
||||||
if (gmid_el1_accessible(info))
|
if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
|
||||||
info->reg_gmid = read_cpuid(GMID_EL1);
|
info->reg_gmid = read_cpuid(GMID_EL1);
|
||||||
|
|
||||||
if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
|
if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
|
||||||
|
|
|
||||||
|
|
@ -129,8 +129,7 @@ int machine_kexec_post_load(struct kimage *kimage)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a copy of the linear map */
|
/* Create a copy of the linear map */
|
||||||
rc = trans_pgd_create_copy(&info, &trans_pgd,
|
rc = trans_pgd_create_copy(&info, &trans_pgd, PAGE_OFFSET, PAGE_END);
|
||||||
_PAGE_OFFSET(vabits_actual), PAGE_END);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
kimage->arch.ttbr1 = __pa(trans_pgd);
|
kimage->arch.ttbr1 = __pa(trans_pgd);
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
|
||||||
num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU;
|
num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU;
|
||||||
|
|
||||||
if (num_mmus > kvm->arch.nested_mmus_size) {
|
if (num_mmus > kvm->arch.nested_mmus_size) {
|
||||||
tmp = kvzalloc_objs(*tmp, num_mmus, GFP_KERNEL_ACCOUNT);
|
tmp = kvcalloc(num_mmus, sizeof(*tmp), GFP_KERNEL_ACCOUNT);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/hardirq.h>
|
#include <linux/hardirq.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/irqflags.h>
|
|
||||||
#include <linux/kasan.h>
|
#include <linux/kasan.h>
|
||||||
#include <linux/kprobes.h>
|
#include <linux/kprobes.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
@ -155,9 +154,6 @@ static void show_pte(unsigned long addr)
|
||||||
pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n",
|
pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n",
|
||||||
mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
|
mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
|
||||||
vabits_actual, mm_to_pgd_phys(mm));
|
vabits_actual, mm_to_pgd_phys(mm));
|
||||||
|
|
||||||
guard(irqsave)();
|
|
||||||
|
|
||||||
pgdp = pgd_offset(mm, addr);
|
pgdp = pgd_offset(mm, addr);
|
||||||
pgd = READ_ONCE(*pgdp);
|
pgd = READ_ONCE(*pgdp);
|
||||||
pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
|
pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
|
||||||
|
|
@ -171,25 +167,25 @@ static void show_pte(unsigned long addr)
|
||||||
if (pgd_none(pgd) || pgd_bad(pgd))
|
if (pgd_none(pgd) || pgd_bad(pgd))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
p4dp = p4d_offset_lockless(pgdp, pgd, addr);
|
p4dp = p4d_offset(pgdp, addr);
|
||||||
p4d = READ_ONCE(*p4dp);
|
p4d = READ_ONCE(*p4dp);
|
||||||
pr_cont(", p4d=%016llx", p4d_val(p4d));
|
pr_cont(", p4d=%016llx", p4d_val(p4d));
|
||||||
if (p4d_none(p4d) || p4d_bad(p4d))
|
if (p4d_none(p4d) || p4d_bad(p4d))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pudp = pud_offset_lockless(p4dp, p4d, addr);
|
pudp = pud_offset(p4dp, addr);
|
||||||
pud = READ_ONCE(*pudp);
|
pud = READ_ONCE(*pudp);
|
||||||
pr_cont(", pud=%016llx", pud_val(pud));
|
pr_cont(", pud=%016llx", pud_val(pud));
|
||||||
if (pud_none(pud) || pud_bad(pud))
|
if (pud_none(pud) || pud_bad(pud))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pmdp = pmd_offset_lockless(pudp, pud, addr);
|
pmdp = pmd_offset(pudp, addr);
|
||||||
pmd = READ_ONCE(*pmdp);
|
pmd = READ_ONCE(*pmdp);
|
||||||
pr_cont(", pmd=%016llx", pmd_val(pmd));
|
pr_cont(", pmd=%016llx", pmd_val(pmd));
|
||||||
if (pmd_none(pmd) || pmd_bad(pmd))
|
if (pmd_none(pmd) || pmd_bad(pmd))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ptep = pte_offset_map(&pmd, addr);
|
ptep = pte_offset_map(pmdp, addr);
|
||||||
if (!ptep)
|
if (!ptep)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ config LOONGARCH
|
||||||
select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC
|
select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC
|
||||||
select HAVE_RETHOOK
|
select HAVE_RETHOOK
|
||||||
select HAVE_RSEQ
|
select HAVE_RSEQ
|
||||||
select HAVE_RUST if !KASAN
|
select HAVE_RUST
|
||||||
select HAVE_SAMPLE_FTRACE_DIRECT
|
select HAVE_SAMPLE_FTRACE_DIRECT
|
||||||
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
|
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
|
||||||
select HAVE_SETUP_PER_CPU_AREA if NUMA
|
select HAVE_SETUP_PER_CPU_AREA if NUMA
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ struct dmsintc_state {
|
||||||
};
|
};
|
||||||
|
|
||||||
int kvm_loongarch_register_dmsintc_device(void);
|
int kvm_loongarch_register_dmsintc_device(void);
|
||||||
void kvm_loongarch_unregister_dmsintc_device(void);
|
|
||||||
void dmsintc_inject_irq(struct kvm_vcpu *vcpu);
|
void dmsintc_inject_irq(struct kvm_vcpu *vcpu);
|
||||||
int dmsintc_set_irq(struct kvm *kvm, u64 addr, int data, int level);
|
int dmsintc_set_irq(struct kvm *kvm, u64 addr, int data, int level);
|
||||||
int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 vector, int level);
|
int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 vector, int level);
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ struct loongarch_eiointc {
|
||||||
};
|
};
|
||||||
|
|
||||||
int kvm_loongarch_register_eiointc_device(void);
|
int kvm_loongarch_register_eiointc_device(void);
|
||||||
void kvm_loongarch_unregister_eiointc_device(void);
|
|
||||||
void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level);
|
void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level);
|
||||||
|
|
||||||
#endif /* __ASM_KVM_EIOINTC_H */
|
#endif /* __ASM_KVM_EIOINTC_H */
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,6 @@ struct kvm_arch {
|
||||||
unsigned int pte_shifts[MAX_PGTABLE_LEVELS];
|
unsigned int pte_shifts[MAX_PGTABLE_LEVELS];
|
||||||
unsigned int root_level;
|
unsigned int root_level;
|
||||||
spinlock_t phyid_map_lock;
|
spinlock_t phyid_map_lock;
|
||||||
spinlock_t pv_setting_lock;
|
|
||||||
struct kvm_phyid_map *phyid_map;
|
struct kvm_phyid_map *phyid_map;
|
||||||
/* Enabled PV features */
|
/* Enabled PV features */
|
||||||
unsigned long pv_features;
|
unsigned long pv_features;
|
||||||
|
|
@ -351,6 +350,7 @@ static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
|
||||||
static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {}
|
static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {}
|
||||||
void kvm_check_vpid(struct kvm_vcpu *vcpu);
|
void kvm_check_vpid(struct kvm_vcpu *vcpu);
|
||||||
enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer);
|
enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer);
|
||||||
|
void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm, const struct kvm_memory_slot *memslot);
|
||||||
void kvm_init_vmcs(struct kvm *kvm);
|
void kvm_init_vmcs(struct kvm *kvm);
|
||||||
void kvm_exc_entry(void);
|
void kvm_exc_entry(void);
|
||||||
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,5 @@ struct ipi_state {
|
||||||
#define IOCSR_ANY_SEND 0x158
|
#define IOCSR_ANY_SEND 0x158
|
||||||
|
|
||||||
int kvm_loongarch_register_ipi_device(void);
|
int kvm_loongarch_register_ipi_device(void);
|
||||||
void kvm_loongarch_unregister_ipi_device(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ struct loongarch_pch_pic {
|
||||||
|
|
||||||
struct kvm_kernel_irq_routing_entry;
|
struct kvm_kernel_irq_routing_entry;
|
||||||
int kvm_loongarch_register_pch_pic_device(void);
|
int kvm_loongarch_register_pch_pic_device(void);
|
||||||
void kvm_loongarch_unregister_pch_pic_device(void);
|
|
||||||
void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level);
|
void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level);
|
||||||
int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int level);
|
int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int level);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -275,9 +275,6 @@ bool kprobe_singlestep_handler(struct pt_regs *regs)
|
||||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||||
unsigned long addr = instruction_pointer(regs);
|
unsigned long addr = instruction_pointer(regs);
|
||||||
|
|
||||||
if (!cur)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
|
if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
|
||||||
((unsigned long)&cur->ainsn.insn[1] == addr)) {
|
((unsigned long)&cur->ainsn.insn[1] == addr)) {
|
||||||
restore_local_irqflag(kcb, regs);
|
restore_local_irqflag(kcb, regs);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
cfi_st t6, PT_R18
|
cfi_st t6, PT_R18
|
||||||
cfi_st t7, PT_R19
|
cfi_st t7, PT_R19
|
||||||
cfi_st t8, PT_R20
|
cfi_st t8, PT_R20
|
||||||
|
cfi_st u0, PT_R21
|
||||||
cfi_st fp, PT_R22
|
cfi_st fp, PT_R22
|
||||||
cfi_st s0, PT_R23
|
cfi_st s0, PT_R23
|
||||||
cfi_st s1, PT_R24
|
cfi_st s1, PT_R24
|
||||||
|
|
@ -58,6 +59,7 @@
|
||||||
cfi_ld t6, PT_R18
|
cfi_ld t6, PT_R18
|
||||||
cfi_ld t7, PT_R19
|
cfi_ld t7, PT_R19
|
||||||
cfi_ld t8, PT_R20
|
cfi_ld t8, PT_R20
|
||||||
|
cfi_ld u0, PT_R21
|
||||||
cfi_ld fp, PT_R22
|
cfi_ld fp, PT_R22
|
||||||
cfi_ld s0, PT_R23
|
cfi_ld s0, PT_R23
|
||||||
cfi_ld s1, PT_R24
|
cfi_ld s1, PT_R24
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq_work.h>
|
#include <linux/irq_work.h>
|
||||||
|
#include <linux/profile.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
|
|
@ -715,6 +716,13 @@ void smp_send_stop(void)
|
||||||
smp_call_function(stop_this_cpu, NULL, 0);
|
smp_call_function(stop_this_cpu, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROFILING
|
||||||
|
int setup_profiling_timer(unsigned int multiplier)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void flush_tlb_all_ipi(void *info)
|
static void flush_tlb_all_ipi(void *info)
|
||||||
{
|
{
|
||||||
local_flush_tlb_all();
|
local_flush_tlb_all();
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#include "image-vars.h"
|
#include "image-vars.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Max available Page Size is 64K, so we set SectionAlignment
|
* Max avaliable Page Size is 64K, so we set SectionAlignment
|
||||||
* field of EFI application to 64K.
|
* field of EFI application to 64K.
|
||||||
*/
|
*/
|
||||||
PECOFF_FILE_ALIGN = 0x200;
|
PECOFF_FILE_ALIGN = 0x200;
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ static int kvm_dmsintc_create(struct kvm_device *dev, u32 type)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = kzalloc_obj(struct loongarch_dmsintc);
|
s = kzalloc(sizeof(struct loongarch_dmsintc), GFP_KERNEL);
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
@ -180,8 +180,3 @@ int kvm_loongarch_register_dmsintc_device(void)
|
||||||
{
|
{
|
||||||
return kvm_register_device_ops(&kvm_dmsintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DMSINTC);
|
return kvm_register_device_ops(&kvm_dmsintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DMSINTC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvm_loongarch_unregister_dmsintc_device(void)
|
|
||||||
{
|
|
||||||
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_DMSINTC);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -695,8 +695,3 @@ int kvm_loongarch_register_eiointc_device(void)
|
||||||
{
|
{
|
||||||
return kvm_register_device_ops(&kvm_eiointc_dev_ops, KVM_DEV_TYPE_LOONGARCH_EIOINTC);
|
return kvm_register_device_ops(&kvm_eiointc_dev_ops, KVM_DEV_TYPE_LOONGARCH_EIOINTC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvm_loongarch_unregister_eiointc_device(void)
|
|
||||||
{
|
|
||||||
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_EIOINTC);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -463,8 +463,3 @@ int kvm_loongarch_register_ipi_device(void)
|
||||||
{
|
{
|
||||||
return kvm_register_device_ops(&kvm_ipi_dev_ops, KVM_DEV_TYPE_LOONGARCH_IPI);
|
return kvm_register_device_ops(&kvm_ipi_dev_ops, KVM_DEV_TYPE_LOONGARCH_IPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvm_loongarch_unregister_ipi_device(void)
|
|
||||||
{
|
|
||||||
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_IPI);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -78,9 +78,6 @@ int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int
|
||||||
return dmsintc_set_irq(kvm, msg_addr, e->msi.data, level);
|
return dmsintc_set_irq(kvm, msg_addr, e->msi.data, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->msi.data >= EIOINTC_IRQS)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
eiointc_set_irq(kvm->arch.eiointc, e->msi.data, level);
|
eiointc_set_irq(kvm->arch.eiointc, e->msi.data, level);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -503,8 +500,3 @@ int kvm_loongarch_register_pch_pic_device(void)
|
||||||
{
|
{
|
||||||
return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC);
|
return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvm_loongarch_unregister_pch_pic_device(void)
|
|
||||||
{
|
|
||||||
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_PCHPIC);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -385,52 +385,27 @@ static int kvm_loongarch_env_init(void)
|
||||||
/* Register LoongArch IPI interrupt controller interface. */
|
/* Register LoongArch IPI interrupt controller interface. */
|
||||||
ret = kvm_loongarch_register_ipi_device();
|
ret = kvm_loongarch_register_ipi_device();
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_env;
|
return ret;
|
||||||
|
|
||||||
/* Register LoongArch EIOINTC interrupt controller interface. */
|
/* Register LoongArch EIOINTC interrupt controller interface. */
|
||||||
ret = kvm_loongarch_register_eiointc_device();
|
ret = kvm_loongarch_register_eiointc_device();
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_ipi;
|
return ret;
|
||||||
|
|
||||||
/* Register LoongArch PCH-PIC interrupt controller interface. */
|
/* Register LoongArch PCH-PIC interrupt controller interface. */
|
||||||
ret = kvm_loongarch_register_pch_pic_device();
|
ret = kvm_loongarch_register_pch_pic_device();
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_eiointc;
|
return ret;
|
||||||
|
|
||||||
/* Register LoongArch DMSINTC interrupt contrroller interface */
|
/* Register LoongArch DMSINTC interrupt contrroller interface */
|
||||||
if (cpu_has_msgint) {
|
if (cpu_has_msgint)
|
||||||
ret = kvm_loongarch_register_dmsintc_device();
|
ret = kvm_loongarch_register_dmsintc_device();
|
||||||
if (ret)
|
|
||||||
goto err_pch_pic;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_pch_pic:
|
|
||||||
kvm_loongarch_unregister_pch_pic_device();
|
|
||||||
err_eiointc:
|
|
||||||
kvm_loongarch_unregister_eiointc_device();
|
|
||||||
err_ipi:
|
|
||||||
kvm_loongarch_unregister_ipi_device();
|
|
||||||
err_env:
|
|
||||||
kvm_unregister_perf_callbacks();
|
|
||||||
kfree(kvm_loongarch_ops);
|
|
||||||
kvm_loongarch_ops = NULL;
|
|
||||||
free_percpu(vmcs);
|
|
||||||
vmcs = NULL;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvm_loongarch_env_exit(void)
|
static void kvm_loongarch_env_exit(void)
|
||||||
{
|
{
|
||||||
if (cpu_has_msgint)
|
|
||||||
kvm_loongarch_unregister_dmsintc_device();
|
|
||||||
|
|
||||||
kvm_loongarch_unregister_pch_pic_device();
|
|
||||||
kvm_loongarch_unregister_eiointc_device();
|
|
||||||
kvm_loongarch_unregister_ipi_device();
|
|
||||||
|
|
||||||
if (vmcs)
|
if (vmcs)
|
||||||
free_percpu(vmcs);
|
free_percpu(vmcs);
|
||||||
|
|
||||||
|
|
@ -453,11 +428,7 @@ static int kvm_loongarch_init(void)
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
return kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
||||||
if (r)
|
|
||||||
kvm_loongarch_env_exit();
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvm_loongarch_exit(void)
|
static void kvm_loongarch_exit(void)
|
||||||
|
|
|
||||||
|
|
@ -383,16 +383,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, const struct kvm_memory_slot
|
||||||
hva_t hva_start;
|
hva_t hva_start;
|
||||||
size_t size, gpa_offset, hva_offset;
|
size_t size, gpa_offset, hva_offset;
|
||||||
|
|
||||||
/*
|
|
||||||
* The generic code allocates a fresh, zeroed memslot for every change,
|
|
||||||
* so the arch flags computed below must be carried over when only the
|
|
||||||
* userspace flags change, e.g. when dirty logging is toggled.
|
|
||||||
*/
|
|
||||||
if (change == KVM_MR_FLAGS_ONLY) {
|
|
||||||
new->arch = old->arch;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((change != KVM_MR_MOVE) && (change != KVM_MR_CREATE))
|
if ((change != KVM_MR_MOVE) && (change != KVM_MR_CREATE))
|
||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
|
|
@ -949,3 +939,9 @@ int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long gpa, bool write, in
|
||||||
void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
|
void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm,
|
||||||
|
const struct kvm_memory_slot *memslot)
|
||||||
|
{
|
||||||
|
kvm_flush_remote_tlbs(kvm);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1165,14 +1165,10 @@ static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* All vCPUs need set the same PV features */
|
/* All vCPUs need set the same PV features */
|
||||||
spin_lock(&kvm->arch.pv_setting_lock);
|
|
||||||
if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED)
|
if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED)
|
||||||
&& ((kvm->arch.pv_features & valid) != val)) {
|
&& ((kvm->arch.pv_features & valid) != val))
|
||||||
spin_unlock(&kvm->arch.pv_setting_lock);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
|
||||||
kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED;
|
kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED;
|
||||||
spin_unlock(&kvm->arch.pv_setting_lock);
|
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
spin_lock_init(&kvm->arch.phyid_map_lock);
|
spin_lock_init(&kvm->arch.phyid_map_lock);
|
||||||
spin_lock_init(&kvm->arch.pv_setting_lock);
|
|
||||||
|
|
||||||
kvm_init_vmcs(kvm);
|
kvm_init_vmcs(kvm);
|
||||||
kvm_vm_init_features(kvm);
|
kvm_vm_init_features(kvm);
|
||||||
|
|
|
||||||
|
|
@ -717,7 +717,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
||||||
move_reg(ctx, t1, src);
|
move_reg(ctx, t1, src);
|
||||||
emit_zext_32(ctx, t1, true);
|
emit_zext_32(ctx, t1, true);
|
||||||
move_imm(ctx, dst, (ctx->user_vm_start >> 32) << 32, false);
|
move_imm(ctx, dst, (ctx->user_vm_start >> 32) << 32, false);
|
||||||
emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 2);
|
emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 1);
|
||||||
emit_insn(ctx, or, t1, dst, t1);
|
emit_insn(ctx, or, t1, dst, t1);
|
||||||
move_reg(ctx, dst, t1);
|
move_reg(ctx, dst, t1);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -523,24 +523,24 @@ bcm47xx_buttons_add(const struct bcm47xx_gpio_key *buttons, int nbuttons)
|
||||||
|
|
||||||
/* 1 node for gpio-keys device, 1 node for each button, 1 terminator */
|
/* 1 node for gpio-keys device, 1 node for each button, 1 terminator */
|
||||||
const struct software_node **node_group __free(kfree) =
|
const struct software_node **node_group __free(kfree) =
|
||||||
kzalloc_objs(*node_group, 1 + nbuttons + 1);
|
kcalloc(1 + nbuttons + 1, sizeof(*node_group), GFP_KERNEL);
|
||||||
if (!node_group)
|
if (!node_group)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* 1 code property, 1 gpio property, 1 terminator */
|
/* 1 code property, 1 gpio property, 1 terminator */
|
||||||
struct property_entry *props __free(kfree) =
|
struct property_entry *props __free(kfree) =
|
||||||
kzalloc_objs(*props, nbuttons * 3);
|
kcalloc(nbuttons * 3, sizeof(*props), GFP_KERNEL);
|
||||||
if (!props)
|
if (!props)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* 1 node for gpio-keys device, 1 node for each button */
|
/* 1 node for gpio-keys device, 1 node for each button */
|
||||||
struct software_node *nodes __free(kfree) =
|
struct software_node *nodes __free(kfree) =
|
||||||
kzalloc_objs(*nodes, 1 + nbuttons);
|
kcalloc(1 + nbuttons, sizeof(*nodes), GFP_KERNEL);
|
||||||
if (!nodes)
|
if (!nodes)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
struct software_node_ref_args *ref_args __free(kfree) =
|
struct software_node_ref_args *ref_args __free(kfree) =
|
||||||
kzalloc_objs(*ref_args, nbuttons);
|
kcalloc(nbuttons, sizeof(*ref_args), GFP_KERNEL);
|
||||||
if (!ref_args)
|
if (!ref_args)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,8 @@ static inline void arch_interrupt_enter_prepare(struct pt_regs *regs)
|
||||||
|
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
kuap_lock();
|
kuap_lock();
|
||||||
|
account_cpu_user_entry();
|
||||||
|
account_stolen_time();
|
||||||
} else {
|
} else {
|
||||||
kuap_save_and_lock(regs);
|
kuap_save_and_lock(regs);
|
||||||
/*
|
/*
|
||||||
|
|
@ -268,7 +270,7 @@ static inline void arch_interrupt_exit_prepare(struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* irqentry_exit expects to be called with interrupts disabled */
|
/* irqentry_exit expects to be called with interrupts disabled */
|
||||||
hard_irq_disable();
|
local_irq_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void arch_interrupt_async_enter_prepare(struct pt_regs *regs)
|
static inline void arch_interrupt_async_enter_prepare(struct pt_regs *regs)
|
||||||
|
|
@ -513,14 +515,8 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
|
||||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||||
local_paca->tm_scratch = regs->msr;
|
local_paca->tm_scratch = regs->msr;
|
||||||
#endif
|
#endif
|
||||||
/*
|
/* Restore user access locks last */
|
||||||
* Do not restore KUAP here. Generic entry might treat this as the last
|
kuap_user_restore(regs);
|
||||||
* arch step before userspace but PowerPC still has kernel work after
|
|
||||||
* irqentry_exit()/syscall_exit_to_user_mode() i.e. in
|
|
||||||
* interrupt_exit_user_prepare() / syscall_exit_prepare() may enable
|
|
||||||
* IRQs and retry. Those functions restore KUAP immediately before rfi,
|
|
||||||
* which is where it should belong.
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
|
#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
|
||||||
|
|
|
||||||
|
|
@ -533,7 +533,9 @@ static void eeh_rmv_device(struct eeh_dev *edev, void *userdata)
|
||||||
if (rmv_data)
|
if (rmv_data)
|
||||||
list_add(&edev->rmv_entry, &rmv_data->removed_vf_list);
|
list_add(&edev->rmv_entry, &rmv_data->removed_vf_list);
|
||||||
} else {
|
} else {
|
||||||
|
pci_lock_rescan_remove();
|
||||||
pci_stop_and_remove_bus_device(dev);
|
pci_stop_and_remove_bus_device(dev);
|
||||||
|
pci_unlock_rescan_remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ notrace unsigned long syscall_exit_restart(unsigned long r3, struct pt_regs *reg
|
||||||
current_thread_info()->exit_flags &= ~_TIF_RESTOREALL;
|
current_thread_info()->exit_flags &= ~_TIF_RESTOREALL;
|
||||||
regs->exit_result |= ret;
|
regs->exit_result |= ret;
|
||||||
|
|
||||||
return regs->exit_result;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -824,6 +824,7 @@ void __init early_init_devtree(void *params)
|
||||||
fadump_append_bootargs();
|
fadump_append_bootargs();
|
||||||
|
|
||||||
/* Scan memory nodes and rebuild MEMBLOCKs */
|
/* Scan memory nodes and rebuild MEMBLOCKs */
|
||||||
|
early_init_dt_scan_root();
|
||||||
early_init_dt_scan_memory_ppc();
|
early_init_dt_scan_memory_ppc();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,6 @@ int rtas_pci_dn_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
|
||||||
if (!config_access_valid(pdn, where))
|
if (!config_access_valid(pdn, where))
|
||||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
#ifdef CONFIG_EEH
|
#ifdef CONFIG_EEH
|
||||||
if (pdn->edev &&
|
|
||||||
(pdn->edev->mode & EEH_DEV_REMOVED))
|
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
|
||||||
|
|
||||||
if (pdn->edev && pdn->edev->pe &&
|
if (pdn->edev && pdn->edev->pe &&
|
||||||
(pdn->edev->pe->state & EEH_PE_CFG_BLOCKED))
|
(pdn->edev->pe->state & EEH_PE_CFG_BLOCKED))
|
||||||
return PCIBIOS_SET_FAILED;
|
return PCIBIOS_SET_FAILED;
|
||||||
|
|
@ -109,10 +105,6 @@ int rtas_pci_dn_write_config(struct pci_dn *pdn, int where, int size, u32 val)
|
||||||
if (!config_access_valid(pdn, where))
|
if (!config_access_valid(pdn, where))
|
||||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
#ifdef CONFIG_EEH
|
#ifdef CONFIG_EEH
|
||||||
if (pdn->edev &&
|
|
||||||
(pdn->edev->mode & EEH_DEV_REMOVED))
|
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
|
||||||
|
|
||||||
if (pdn->edev && pdn->edev->pe &&
|
if (pdn->edev && pdn->edev->pe &&
|
||||||
(pdn->edev->pe->state & EEH_PE_CFG_BLOCKED))
|
(pdn->edev->pe->state & EEH_PE_CFG_BLOCKED))
|
||||||
return PCIBIOS_SET_FAILED;
|
return PCIBIOS_SET_FAILED;
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,8 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)
|
||||||
long ret;
|
long ret;
|
||||||
syscall_fn f;
|
syscall_fn f;
|
||||||
|
|
||||||
if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0))) {
|
if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0)))
|
||||||
clear_thread_flag(TIF_SYSCALL_RET);
|
|
||||||
return syscall_get_error(current, regs);
|
return syscall_get_error(current, regs);
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(test_and_clear_thread_flag(TIF_SYSCALL_RET)))
|
if (unlikely(test_and_clear_thread_flag(TIF_SYSCALL_RET)))
|
||||||
return syscall_get_error(current, regs);
|
return syscall_get_error(current, regs);
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,6 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
|
||||||
cmdline = modified_cmdline;
|
cmdline = modified_cmdline;
|
||||||
}
|
}
|
||||||
|
|
||||||
kexec_dprintk("Command line: %s", cmdline ? cmdline : "");
|
|
||||||
|
|
||||||
if (initrd != NULL) {
|
if (initrd != NULL) {
|
||||||
kbuf.buffer = initrd;
|
kbuf.buffer = initrd;
|
||||||
kbuf.bufsz = kbuf.memsz = initrd_len;
|
kbuf.bufsz = kbuf.memsz = initrd_len;
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ int arch_check_excluded_range(struct kimage *image, unsigned long start,
|
||||||
|
|
||||||
emem = image->arch.exclude_ranges;
|
emem = image->arch.exclude_ranges;
|
||||||
for (i = 0; i < emem->nr_ranges; i++)
|
for (i = 0; i < emem->nr_ranges; i++)
|
||||||
if (start <= emem->ranges[i].end && end >= emem->ranges[i].start)
|
if (start < emem->ranges[i].end && end > emem->ranges[i].start)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -113,7 +113,7 @@ static int add_usable_mem(struct umem_info *um_info, u64 base, u64 end)
|
||||||
loc_end = um_info->ranges[i].end;
|
loc_end = um_info->ranges[i].end;
|
||||||
if (loc_base >= base && loc_end <= end)
|
if (loc_base >= base && loc_end <= end)
|
||||||
add = true;
|
add = true;
|
||||||
else if (base <= loc_end && end >= loc_base) {
|
else if (base < loc_end && end > loc_base) {
|
||||||
if (loc_base < base)
|
if (loc_base < base)
|
||||||
loc_base = base;
|
loc_base = base;
|
||||||
if (loc_end > end)
|
if (loc_end > end)
|
||||||
|
|
@ -377,12 +377,16 @@ static int load_backup_segment(struct kimage *image, struct kexec_buf *kbuf)
|
||||||
static unsigned int kdump_extra_elfcorehdr_size(struct crash_mem *cmem)
|
static unsigned int kdump_extra_elfcorehdr_size(struct crash_mem *cmem)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_CRASH_HOTPLUG) && defined(CONFIG_MEMORY_HOTPLUG)
|
#if defined(CONFIG_CRASH_HOTPLUG) && defined(CONFIG_MEMORY_HOTPLUG)
|
||||||
|
unsigned int extra_sz = 0;
|
||||||
|
|
||||||
if (CONFIG_CRASH_MAX_MEMORY_RANGES > (unsigned int)PN_XNUM)
|
if (CONFIG_CRASH_MAX_MEMORY_RANGES > (unsigned int)PN_XNUM)
|
||||||
pr_warn("Number of Phdrs %u exceeds max\n", CONFIG_CRASH_MAX_MEMORY_RANGES);
|
pr_warn("Number of Phdrs %u exceeds max\n", CONFIG_CRASH_MAX_MEMORY_RANGES);
|
||||||
else if (cmem->nr_ranges >= CONFIG_CRASH_MAX_MEMORY_RANGES)
|
else if (cmem->nr_ranges >= CONFIG_CRASH_MAX_MEMORY_RANGES)
|
||||||
pr_warn("Configured crash mem ranges may not be enough\n");
|
pr_warn("Configured crash mem ranges may not be enough\n");
|
||||||
else
|
else
|
||||||
return (CONFIG_CRASH_MAX_MEMORY_RANGES - cmem->nr_ranges) * sizeof(Elf64_Phdr);
|
extra_sz = (CONFIG_CRASH_MAX_MEMORY_RANGES - cmem->nr_ranges) * sizeof(Elf64_Phdr);
|
||||||
|
|
||||||
|
return extra_sz;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6140,12 +6140,12 @@ static int kvmppc_irq_bypass_add_producer_hv(struct irq_bypass_consumer *cons,
|
||||||
struct kvm_kernel_irqfd *irqfd =
|
struct kvm_kernel_irqfd *irqfd =
|
||||||
container_of(cons, struct kvm_kernel_irqfd, consumer);
|
container_of(cons, struct kvm_kernel_irqfd, consumer);
|
||||||
|
|
||||||
|
irqfd->producer = prod;
|
||||||
|
|
||||||
ret = kvmppc_set_passthru_irq(irqfd->kvm, prod->irq, irqfd->gsi);
|
ret = kvmppc_set_passthru_irq(irqfd->kvm, prod->irq, irqfd->gsi);
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_info("kvmppc_set_passthru_irq (irq %d, gsi %d) fails: %d\n",
|
pr_info("kvmppc_set_passthru_irq (irq %d, gsi %d) fails: %d\n",
|
||||||
prod->irq, irqfd->gsi, ret);
|
prod->irq, irqfd->gsi, ret);
|
||||||
else
|
|
||||||
irqfd->producer = prod;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -165,8 +165,6 @@ static int __init pas_setup_mce_regs(void)
|
||||||
while (dev && reg < MAX_MCE_REGS) {
|
while (dev && reg < MAX_MCE_REGS) {
|
||||||
mce_regs[reg].name = kasprintf(GFP_KERNEL,
|
mce_regs[reg].name = kasprintf(GFP_KERNEL,
|
||||||
"mc%d_mcdebug_errsta", reg);
|
"mc%d_mcdebug_errsta", reg);
|
||||||
if (!mce_regs[reg].name)
|
|
||||||
return -ENOMEM;
|
|
||||||
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x730);
|
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x730);
|
||||||
dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa00a, dev);
|
dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa00a, dev);
|
||||||
reg++;
|
reg++;
|
||||||
|
|
|
||||||
|
|
@ -1623,13 +1623,15 @@ int64_t pnv_opal_pci_msi_eoi(struct irq_data *d)
|
||||||
return opal_pci_msi_eoi(phb->opal_id, d->parent_data->hwirq);
|
return opal_pci_msi_eoi(phb->opal_id, d->parent_data->hwirq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct irq_chip pnv_pci_msi_irq_chip;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns true iff chip is something that we could call
|
* Returns true iff chip is something that we could call
|
||||||
* pnv_opal_pci_msi_eoi for.
|
* pnv_opal_pci_msi_eoi for.
|
||||||
*/
|
*/
|
||||||
bool is_pnv_opal_msi(struct irq_chip *chip)
|
bool is_pnv_opal_msi(struct irq_chip *chip)
|
||||||
{
|
{
|
||||||
return chip && chip->name && str_has_prefix(chip->name, "PNV-");
|
return chip == &pnv_pci_msi_irq_chip;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(is_pnv_opal_msi);
|
EXPORT_SYMBOL_GPL(is_pnv_opal_msi);
|
||||||
|
|
||||||
|
|
@ -1726,7 +1728,7 @@ static const struct msi_parent_ops pnv_msi_parent_ops = {
|
||||||
.chip_flags = MSI_CHIP_FLAG_SET_EOI,
|
.chip_flags = MSI_CHIP_FLAG_SET_EOI,
|
||||||
.bus_select_token = DOMAIN_BUS_NEXUS,
|
.bus_select_token = DOMAIN_BUS_NEXUS,
|
||||||
.bus_select_mask = MATCH_PCI_MSI,
|
.bus_select_mask = MATCH_PCI_MSI,
|
||||||
.prefix = "PNV-", /* Note: is_pnv_opal_msi() uses this */
|
.prefix = "PNV-",
|
||||||
.init_dev_msi_info = pnv_init_dev_msi_info,
|
.init_dev_msi_info = pnv_init_dev_msi_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@
|
||||||
* Copyright 2006 Sony Corp.
|
* Copyright 2006 Sony Corp.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/minmax.h>
|
|
||||||
|
|
||||||
#include <asm/lv1call.h>
|
#include <asm/lv1call.h>
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
@ -76,9 +74,8 @@ static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
|
||||||
static u64 make_first_field(const char *text, u64 index)
|
static u64 make_first_field(const char *text, u64 index)
|
||||||
{
|
{
|
||||||
u64 n = 0;
|
u64 n = 0;
|
||||||
size_t len = min(strlen(text), sizeof(n));
|
|
||||||
|
|
||||||
memcpy(&n, text, len);
|
memcpy((char *)&n, text, strnlen(text, sizeof(n)));
|
||||||
return PS3_VENDOR_ID_NONE + (n >> 32) + index;
|
return PS3_VENDOR_ID_NONE + (n >> 32) + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -527,28 +527,28 @@ static int htmdump_init_debugfs(void)
|
||||||
htm_status_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
htm_status_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||||
if (!htm_status_buf) {
|
if (!htm_status_buf) {
|
||||||
pr_err("Failed to allocate htmstatus buf\n");
|
pr_err("Failed to allocate htmstatus buf\n");
|
||||||
goto htm_status_buf_err;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Debugfs interface file to present System Processor Configuration */
|
/* Debugfs interface file to present System Processor Configuration */
|
||||||
htm_info_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
htm_info_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||||
if (!htm_info_buf) {
|
if (!htm_info_buf) {
|
||||||
pr_err("Failed to allocate htm info buf\n");
|
pr_err("Failed to allocate htm info buf\n");
|
||||||
goto htm_info_buf_err;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Debugfs interface file to present HTM capabilities */
|
/* Debugfs interface file to present HTM capabilities */
|
||||||
htm_caps_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
htm_caps_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||||
if (!htm_caps_buf) {
|
if (!htm_caps_buf) {
|
||||||
pr_err("Failed to allocate htm caps buf\n");
|
pr_err("Failed to allocate htm caps buf\n");
|
||||||
goto htm_caps_buf_err;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Memory to present HTM system memory configuration */
|
/* Memory to present HTM system memory configuration */
|
||||||
htm_mem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
htm_mem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||||
if (!htm_mem_buf) {
|
if (!htm_mem_buf) {
|
||||||
pr_err("Failed to allocate htm mem buf\n");
|
pr_err("Failed to allocate htm mem buf\n");
|
||||||
goto htm_mem_buf_err;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops);
|
debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops);
|
||||||
|
|
@ -557,17 +557,6 @@ static int htmdump_init_debugfs(void)
|
||||||
debugfs_create_file("htmsystem_mem", 0400, htmdump_debugfs_dir, htm_mem_buf, &htmsystem_mem_fops);
|
debugfs_create_file("htmsystem_mem", 0400, htmdump_debugfs_dir, htm_mem_buf, &htmsystem_mem_fops);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
htm_mem_buf_err:
|
|
||||||
kfree(htm_caps_buf);
|
|
||||||
htm_caps_buf_err:
|
|
||||||
kfree(htm_info_buf);
|
|
||||||
htm_info_buf_err:
|
|
||||||
kfree(htm_status_buf);
|
|
||||||
htm_status_buf_err:
|
|
||||||
debugfs_remove_recursive(htmdump_debugfs_dir);
|
|
||||||
kfree(htm_buf);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init htmdump_init(void)
|
static int __init htmdump_init(void)
|
||||||
|
|
|
||||||
|
|
@ -132,14 +132,11 @@ static int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
|
||||||
|
|
||||||
/* First integer stores max config */
|
/* First integer stores max config */
|
||||||
max_config_vfs = of_read_number(&max_vfs[0], 1);
|
max_config_vfs = of_read_number(&max_vfs[0], 1);
|
||||||
if (max_config_vfs < num_vfs) {
|
if (max_config_vfs < num_vfs || num_vfs > MAX_VFS_FOR_MAP_PE) {
|
||||||
dev_err(&pdev->dev, "Num VFs %x > %x Configurable VFs\n",
|
dev_err(&pdev->dev,
|
||||||
num_vfs, max_config_vfs);
|
"Num VFs %x > %x Configurable VFs\n",
|
||||||
return -EINVAL;
|
num_vfs, (num_vfs > MAX_VFS_FOR_MAP_PE) ?
|
||||||
}
|
MAX_VFS_FOR_MAP_PE : max_config_vfs);
|
||||||
if (num_vfs > MAX_VFS_FOR_MAP_PE) {
|
|
||||||
dev_err(&pdev->dev, "Num VFs %x > %x PE mapping limit\n",
|
|
||||||
num_vfs, MAX_VFS_FOR_MAP_PE);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1134,7 +1134,7 @@ static int __init xive_init_ipis(void)
|
||||||
if (!ipi_domain)
|
if (!ipi_domain)
|
||||||
goto out_free_fwnode;
|
goto out_free_fwnode;
|
||||||
|
|
||||||
xive_ipis = kzalloc_objs(*xive_ipis, nr_node_ids);
|
xive_ipis = kzalloc_objs(*xive_ipis, nr_node_ids, GFP_KERNEL);
|
||||||
if (!xive_ipis)
|
if (!xive_ipis)
|
||||||
goto out_free_domain;
|
goto out_free_domain;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,7 @@ config STACKTRACE_SUPPORT
|
||||||
config GENERIC_BUG
|
config GENERIC_BUG
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on BUG
|
depends on BUG
|
||||||
select GENERIC_BUG_RELATIVE_POINTERS
|
select GENERIC_BUG_RELATIVE_POINTERS if 64BIT
|
||||||
|
|
||||||
config GENERIC_BUG_RELATIVE_POINTERS
|
config GENERIC_BUG_RELATIVE_POINTERS
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,13 @@
|
||||||
|
|
||||||
typedef u32 bug_insn_t;
|
typedef u32 bug_insn_t;
|
||||||
|
|
||||||
|
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
||||||
#define __BUG_ENTRY_ADDR RISCV_INT " 1b - ."
|
#define __BUG_ENTRY_ADDR RISCV_INT " 1b - ."
|
||||||
#define __BUG_ENTRY_FILE(file) RISCV_INT " " file " - ."
|
#define __BUG_ENTRY_FILE(file) RISCV_INT " " file " - ."
|
||||||
|
#else
|
||||||
|
#define __BUG_ENTRY_ADDR RISCV_PTR " 1b"
|
||||||
|
#define __BUG_ENTRY_FILE(file) RISCV_PTR " " file
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||||
#define __BUG_ENTRY(file, line, flags) \
|
#define __BUG_ENTRY(file, line, flags) \
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@ static inline void __switch_to_fpu(struct task_struct *prev,
|
||||||
|
|
||||||
static __always_inline bool has_fpu(void)
|
static __always_inline bool has_fpu(void)
|
||||||
{
|
{
|
||||||
/* D extension depends on F, so checking D alone is sufficient. */
|
return riscv_has_extension_likely(RISCV_ISA_EXT_F) ||
|
||||||
return riscv_has_extension_likely(RISCV_ISA_EXT_D);
|
riscv_has_extension_likely(RISCV_ISA_EXT_D);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static __always_inline bool has_fpu(void) { return false; }
|
static __always_inline bool has_fpu(void) { return false; }
|
||||||
|
|
|
||||||
|
|
@ -412,19 +412,6 @@ static const unsigned int riscv_zvbb_exts[] = {
|
||||||
RISCV_ISA_EXT_ZVKB
|
RISCV_ISA_EXT_ZVKB
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* The RISC-V ISA manual specifies that Zfh implies Zfhmin and Zvfh implies
|
|
||||||
* Zvfhmin. Report the implied subset extensions whenever the supersets are
|
|
||||||
* detected (see https://github.com/riscv/riscv-isa-manual/pull/3070).
|
|
||||||
*/
|
|
||||||
static const unsigned int riscv_zfh_exts[] = {
|
|
||||||
RISCV_ISA_EXT_ZFHMIN
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned int riscv_zvfh_exts[] = {
|
|
||||||
RISCV_ISA_EXT_ZVFHMIN
|
|
||||||
};
|
|
||||||
|
|
||||||
#define RISCV_ISA_EXT_ZVE64F_IMPLY_LIST \
|
#define RISCV_ISA_EXT_ZVE64F_IMPLY_LIST \
|
||||||
RISCV_ISA_EXT_ZVE64X, \
|
RISCV_ISA_EXT_ZVE64X, \
|
||||||
RISCV_ISA_EXT_ZVE32F, \
|
RISCV_ISA_EXT_ZVE32F, \
|
||||||
|
|
@ -563,8 +550,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
||||||
__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
|
__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
|
||||||
__RISCV_ISA_EXT_DATA_VALIDATE(zfa, RISCV_ISA_EXT_ZFA, riscv_ext_f_depends),
|
__RISCV_ISA_EXT_DATA_VALIDATE(zfa, RISCV_ISA_EXT_ZFA, riscv_ext_f_depends),
|
||||||
__RISCV_ISA_EXT_DATA_VALIDATE(zfbfmin, RISCV_ISA_EXT_ZFBFMIN, riscv_ext_f_depends),
|
__RISCV_ISA_EXT_DATA_VALIDATE(zfbfmin, RISCV_ISA_EXT_ZFBFMIN, riscv_ext_f_depends),
|
||||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zfh, RISCV_ISA_EXT_ZFH,
|
__RISCV_ISA_EXT_DATA_VALIDATE(zfh, RISCV_ISA_EXT_ZFH, riscv_ext_f_depends),
|
||||||
riscv_zfh_exts, riscv_ext_f_depends),
|
|
||||||
__RISCV_ISA_EXT_DATA_VALIDATE(zfhmin, RISCV_ISA_EXT_ZFHMIN, riscv_ext_f_depends),
|
__RISCV_ISA_EXT_DATA_VALIDATE(zfhmin, RISCV_ISA_EXT_ZFHMIN, riscv_ext_f_depends),
|
||||||
__RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA),
|
__RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA),
|
||||||
__RISCV_ISA_EXT_DATA_VALIDATE(zcb, RISCV_ISA_EXT_ZCB, riscv_ext_zca_depends),
|
__RISCV_ISA_EXT_DATA_VALIDATE(zcb, RISCV_ISA_EXT_ZCB, riscv_ext_zca_depends),
|
||||||
|
|
@ -600,9 +586,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
||||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts, riscv_ext_vector_x_validate),
|
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts, riscv_ext_vector_x_validate),
|
||||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN, riscv_vector_f_validate),
|
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN, riscv_vector_f_validate),
|
||||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA, riscv_ext_zvfbfwma_validate),
|
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA, riscv_ext_zvfbfwma_validate),
|
||||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zvfh, RISCV_ISA_EXT_ZVFH,
|
__RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH),
|
||||||
riscv_zvfh_exts,
|
|
||||||
riscv_ext_vector_float_validate),
|
|
||||||
__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
|
__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
|
||||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvkb, RISCV_ISA_EXT_ZVKB, riscv_ext_vector_crypto_validate),
|
__RISCV_ISA_EXT_DATA_VALIDATE(zvkb, RISCV_ISA_EXT_ZVKB, riscv_ext_vector_crypto_validate),
|
||||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvkg, RISCV_ISA_EXT_ZVKG, riscv_ext_vector_crypto_validate),
|
__RISCV_ISA_EXT_DATA_VALIDATE(zvkg, RISCV_ISA_EXT_ZVKG, riscv_ext_vector_crypto_validate),
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,6 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
|
||||||
phys_addr_t phys;
|
phys_addr_t phys;
|
||||||
|
|
||||||
if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) {
|
if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) {
|
||||||
if (!IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
|
|
||||||
return addr;
|
|
||||||
phys = __pa_symbol(addr);
|
phys = __pa_symbol(addr);
|
||||||
} else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) {
|
} else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) {
|
||||||
struct page *page = vmalloc_to_page(addr);
|
struct page *page = vmalloc_to_page(addr);
|
||||||
|
|
|
||||||
|
|
@ -349,8 +349,10 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
|
||||||
if (arg & PR_TAGGED_ADDR_ENABLE && (tagged_addr_disabled || !pmlen))
|
if (arg & PR_TAGGED_ADDR_ENABLE && (tagged_addr_disabled || !pmlen))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!(arg & PR_TAGGED_ADDR_ENABLE))
|
if (!(arg & PR_TAGGED_ADDR_ENABLE)) {
|
||||||
pmlen = PMLEN_0;
|
pmlen = PMLEN_0;
|
||||||
|
pmm = ENVCFG_PMM_PMLEN_0;
|
||||||
|
}
|
||||||
|
|
||||||
if (mmap_write_lock_killable(mm))
|
if (mmap_write_lock_killable(mm))
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
|
|
|
||||||
|
|
@ -297,8 +297,6 @@ static u64 hwprobe_vec_misaligned(const struct cpumask *cpus)
|
||||||
static void hwprobe_one_pair(struct riscv_hwprobe *pair,
|
static void hwprobe_one_pair(struct riscv_hwprobe *pair,
|
||||||
const struct cpumask *cpus)
|
const struct cpumask *cpus)
|
||||||
{
|
{
|
||||||
pair->value = 0;
|
|
||||||
|
|
||||||
switch (pair->key) {
|
switch (pair->key) {
|
||||||
case RISCV_HWPROBE_KEY_MVENDORID:
|
case RISCV_HWPROBE_KEY_MVENDORID:
|
||||||
case RISCV_HWPROBE_KEY_MARCHID:
|
case RISCV_HWPROBE_KEY_MARCHID:
|
||||||
|
|
@ -333,14 +331,17 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE:
|
case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE:
|
||||||
|
pair->value = 0;
|
||||||
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ))
|
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ))
|
||||||
pair->value = riscv_cboz_block_size;
|
pair->value = riscv_cboz_block_size;
|
||||||
break;
|
break;
|
||||||
case RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE:
|
case RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE:
|
||||||
|
pair->value = 0;
|
||||||
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM))
|
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM))
|
||||||
pair->value = riscv_cbom_block_size;
|
pair->value = riscv_cbom_block_size;
|
||||||
break;
|
break;
|
||||||
case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE:
|
case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE:
|
||||||
|
pair->value = 0;
|
||||||
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP))
|
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP))
|
||||||
pair->value = riscv_cbop_block_size;
|
pair->value = riscv_cbop_block_size;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -525,8 +525,9 @@ static int __init setup_global_riscv_enable(char *str)
|
||||||
|
|
||||||
if (riscv_nousercfi)
|
if (riscv_nousercfi)
|
||||||
pr_info("RISC-V user CFI disabled via cmdline - shadow stack status : %s, landing pad status : %s\n",
|
pr_info("RISC-V user CFI disabled via cmdline - shadow stack status : %s, landing pad status : %s\n",
|
||||||
str_disabled_enabled(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI),
|
(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI) ? "disabled" :
|
||||||
str_disabled_enabled(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI));
|
"enabled", (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI) ?
|
||||||
|
"disabled" : "enabled");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -503,8 +503,8 @@ int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
einfo = kvzalloc_objs(*einfo, num_events,
|
einfo = kvcalloc(num_events, sizeof(*einfo),
|
||||||
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
|
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
|
||||||
if (!einfo) {
|
if (!einfo) {
|
||||||
ret = SBI_ERR_FAILURE;
|
ret = SBI_ERR_FAILURE;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
|
||||||
li a3, 9*SZREG-1 /* size must >= (word_copy stride + SZREG-1) */
|
li a3, 9*SZREG-1 /* size must >= (word_copy stride + SZREG-1) */
|
||||||
bltu a2, a3, .Lbyte_copy_tail
|
bltu a2, a3, .Lbyte_copy_tail
|
||||||
|
|
||||||
#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
|
||||||
/*
|
/*
|
||||||
* Copy first bytes until dst is aligned to word boundary.
|
* Copy first bytes until dst is aligned to word boundary.
|
||||||
* a0 - start of dst
|
* a0 - start of dst
|
||||||
|
|
@ -104,7 +103,7 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
|
||||||
/* a1 - start of src */
|
/* a1 - start of src */
|
||||||
andi a3, a1, SZREG-1
|
andi a3, a1, SZREG-1
|
||||||
bnez a3, .Lshift_copy
|
bnez a3, .Lshift_copy
|
||||||
#endif
|
|
||||||
.Lword_copy:
|
.Lword_copy:
|
||||||
/*
|
/*
|
||||||
* Both src and dst are aligned, unrolled word copy
|
* Both src and dst are aligned, unrolled word copy
|
||||||
|
|
@ -138,7 +137,6 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
|
||||||
addi t0, t0, 8*SZREG /* revert to original value */
|
addi t0, t0, 8*SZREG /* revert to original value */
|
||||||
j .Lbyte_copy_tail
|
j .Lbyte_copy_tail
|
||||||
|
|
||||||
#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
|
||||||
.Lshift_copy:
|
.Lshift_copy:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -191,7 +189,6 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
|
||||||
|
|
||||||
/* Revert src to original unaligned value */
|
/* Revert src to original unaligned value */
|
||||||
add a1, a1, a3
|
add a1, a1, a3
|
||||||
#endif
|
|
||||||
|
|
||||||
.Lbyte_copy_tail:
|
.Lbyte_copy_tail:
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1465,9 +1465,7 @@ struct execmem_info __init *execmem_arch_setup(void)
|
||||||
[EXECMEM_KPROBES] = {
|
[EXECMEM_KPROBES] = {
|
||||||
.start = VMALLOC_START,
|
.start = VMALLOC_START,
|
||||||
.end = VMALLOC_END,
|
.end = VMALLOC_END,
|
||||||
.pgprot = IS_ENABLED(CONFIG_STRICT_MODULE_RWX) ?
|
.pgprot = PAGE_KERNEL_READ_EXEC,
|
||||||
PAGE_KERNEL_READ_EXEC :
|
|
||||||
PAGE_KERNEL_EXEC,
|
|
||||||
.alignment = 1,
|
.alignment = 1,
|
||||||
},
|
},
|
||||||
[EXECMEM_BPF] = {
|
[EXECMEM_BPF] = {
|
||||||
|
|
|
||||||
|
|
@ -2128,15 +2128,7 @@ bool bpf_jit_supports_ptr_xchg(void)
|
||||||
|
|
||||||
bool bpf_jit_supports_arena(void)
|
bool bpf_jit_supports_arena(void)
|
||||||
{
|
{
|
||||||
/*
|
return true;
|
||||||
* The arena range tree uses kmalloc_nolock(), which needs
|
|
||||||
* cmpxchg128, provided by ZACAS on riscv.
|
|
||||||
*/
|
|
||||||
#ifdef system_has_cmpxchg128
|
|
||||||
return system_has_cmpxchg128();
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
|
bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,11 @@ static void alt_debug_modify(int type, unsigned int nr, bool clear)
|
||||||
|
|
||||||
static char *alt_debug_parse(int type, char *str)
|
static char *alt_debug_parse(int type, char *str)
|
||||||
{
|
{
|
||||||
unsigned long val, endval, limit;
|
unsigned long val, endval;
|
||||||
char *endp;
|
char *endp;
|
||||||
bool clear;
|
bool clear;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
limit = type == ALT_TYPE_FACILITY ? MAX_FACILITY_BIT : MAX_MFEATURE_BIT;
|
|
||||||
if (*str == ':') {
|
if (*str == ':') {
|
||||||
str++;
|
str++;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -74,7 +73,7 @@ static char *alt_debug_parse(int type, char *str)
|
||||||
if (str == endp)
|
if (str == endp)
|
||||||
break;
|
break;
|
||||||
str = endp;
|
str = endp;
|
||||||
while (val <= endval && val < limit) {
|
while (val <= endval) {
|
||||||
alt_debug_modify(type, val, clear);
|
alt_debug_modify(type, val, clear);
|
||||||
val++;
|
val++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ struct parmarea parmarea __section(".parmarea") = {
|
||||||
};
|
};
|
||||||
|
|
||||||
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
|
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
|
||||||
static char command_line_buf[COMMAND_LINE_SIZE];
|
|
||||||
|
|
||||||
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
|
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
|
||||||
struct ipl_parameter_block __bootdata_preserved(ipl_block);
|
struct ipl_parameter_block __bootdata_preserved(ipl_block);
|
||||||
|
|
@ -136,29 +135,31 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
|
||||||
|
|
||||||
static void append_ipl_block_parm(void)
|
static void append_ipl_block_parm(void)
|
||||||
{
|
{
|
||||||
size_t len, extra = 0;
|
char *parm, *delim;
|
||||||
char *delim;
|
size_t len, rc = 0;
|
||||||
|
|
||||||
len = strlen(early_command_line);
|
len = strlen(early_command_line);
|
||||||
delim = early_command_line + len; /* '\0' character position */
|
|
||||||
|
delim = early_command_line + len; /* '\0' character position */
|
||||||
|
parm = early_command_line + len + 1; /* append right after '\0' */
|
||||||
|
|
||||||
switch (ipl_block.pb0_hdr.pbt) {
|
switch (ipl_block.pb0_hdr.pbt) {
|
||||||
case IPL_PBT_CCW:
|
case IPL_PBT_CCW:
|
||||||
extra = ipl_block_get_ascii_vmparm(command_line_buf, sizeof(command_line_buf), &ipl_block);
|
rc = ipl_block_get_ascii_vmparm(
|
||||||
|
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
|
||||||
break;
|
break;
|
||||||
case IPL_PBT_FCP:
|
case IPL_PBT_FCP:
|
||||||
case IPL_PBT_NVME:
|
case IPL_PBT_NVME:
|
||||||
case IPL_PBT_ECKD:
|
case IPL_PBT_ECKD:
|
||||||
extra = ipl_block_get_ascii_scpdata(command_line_buf, sizeof(command_line_buf), &ipl_block);
|
rc = ipl_block_get_ascii_scpdata(
|
||||||
|
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (extra) {
|
if (rc) {
|
||||||
if (command_line_buf[0] == '=') {
|
if (*parm == '=')
|
||||||
memmove(early_command_line, command_line_buf + 1, extra);
|
memmove(early_command_line, parm + 1, rc);
|
||||||
} else if (len < COMMAND_LINE_SIZE - 2) {
|
else
|
||||||
*delim = ' '; /* replace '\0' with space */
|
*delim = ' '; /* replace '\0' with space */
|
||||||
sized_strscpy(delim + 1, command_line_buf, COMMAND_LINE_SIZE - len - 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,7 +231,7 @@ static void modify_fac_list(char *str)
|
||||||
if (str == endp)
|
if (str == endp)
|
||||||
break;
|
break;
|
||||||
str = endp;
|
str = endp;
|
||||||
while (val <= endval && val < MAX_FACILITY_BIT) {
|
while (val <= endval) {
|
||||||
modify_facility(val, clear);
|
modify_facility(val, clear);
|
||||||
val++;
|
val++;
|
||||||
}
|
}
|
||||||
|
|
@ -244,6 +245,7 @@ static void modify_fac_list(char *str)
|
||||||
check_cleared_facilities();
|
check_cleared_facilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char command_line_buf[COMMAND_LINE_SIZE];
|
||||||
void parse_boot_command_line(void)
|
void parse_boot_command_line(void)
|
||||||
{
|
{
|
||||||
char *param, *val;
|
char *param, *val;
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ static int tprot(unsigned long addr)
|
||||||
|
|
||||||
static unsigned long search_mem_end(void)
|
static unsigned long search_mem_end(void)
|
||||||
{
|
{
|
||||||
unsigned long range = 1UL << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
|
unsigned long range = 1 << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
|
||||||
unsigned long offset = 0;
|
unsigned long offset = 0;
|
||||||
unsigned long pivot;
|
unsigned long pivot;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@
|
||||||
# Cryptographic API
|
# Cryptographic API
|
||||||
#
|
#
|
||||||
|
|
||||||
CONTEXT_ANALYSIS := y
|
|
||||||
|
|
||||||
obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
|
obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
|
||||||
obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o
|
obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o
|
||||||
obj-$(CONFIG_S390_PRNG) += prng.o
|
obj-$(CONFIG_S390_PRNG) += prng.o
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,14 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/cpufeature.h>
|
#include <linux/cpufeature.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <linux/fips.h>
|
#include <linux/fips.h>
|
||||||
#include <linux/semaphore.h>
|
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <crypto/xts.h>
|
#include <crypto/xts.h>
|
||||||
#include <asm/cpacf.h>
|
#include <asm/cpacf.h>
|
||||||
|
|
||||||
static u8 *ctrblk;
|
static u8 *ctrblk;
|
||||||
static DEFINE_SEMAPHORE(ctrblk_sem, 1);
|
static DEFINE_MUTEX(ctrblk_lock);
|
||||||
|
|
||||||
static cpacf_mask_t km_functions, kmc_functions, kmctr_functions,
|
static cpacf_mask_t km_functions, kmc_functions, kmctr_functions,
|
||||||
kma_functions;
|
kma_functions;
|
||||||
|
|
@ -129,7 +129,7 @@ static int ecb_aes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
return fallback_skcipher_crypt(sctx, req, modifier);
|
return fallback_skcipher_crypt(sctx, req, modifier);
|
||||||
|
|
||||||
ret = skcipher_walk_virt(&walk, req, false);
|
ret = skcipher_walk_virt(&walk, req, false);
|
||||||
while (!ret && ((nbytes = walk.nbytes) != 0)) {
|
while ((nbytes = walk.nbytes) != 0) {
|
||||||
/* only use complete blocks */
|
/* only use complete blocks */
|
||||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||||
cpacf_km(sctx->fc | modifier, sctx->key,
|
cpacf_km(sctx->fc | modifier, sctx->key,
|
||||||
|
|
@ -233,7 +233,7 @@ static int cbc_aes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
return ret;
|
return ret;
|
||||||
memcpy(param.iv, walk.iv, AES_BLOCK_SIZE);
|
memcpy(param.iv, walk.iv, AES_BLOCK_SIZE);
|
||||||
memcpy(param.key, sctx->key, sctx->key_len);
|
memcpy(param.key, sctx->key, sctx->key_len);
|
||||||
while (!ret && ((nbytes = walk.nbytes) != 0)) {
|
while ((nbytes = walk.nbytes) != 0) {
|
||||||
/* only use complete blocks */
|
/* only use complete blocks */
|
||||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||||
cpacf_kmc(sctx->fc | modifier, ¶m,
|
cpacf_kmc(sctx->fc | modifier, ¶m,
|
||||||
|
|
@ -359,7 +359,7 @@ static int xts_aes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
memcpy(xts_param.key + offset, xts_ctx->key, xts_ctx->key_len);
|
memcpy(xts_param.key + offset, xts_ctx->key, xts_ctx->key_len);
|
||||||
memcpy(xts_param.init, pcc_param.xts, 16);
|
memcpy(xts_param.init, pcc_param.xts, 16);
|
||||||
|
|
||||||
while (!ret && ((nbytes = walk.nbytes) != 0)) {
|
while ((nbytes = walk.nbytes) != 0) {
|
||||||
/* only use complete blocks */
|
/* only use complete blocks */
|
||||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||||
cpacf_km(xts_ctx->fc | modifier, xts_param.key + offset,
|
cpacf_km(xts_ctx->fc | modifier, xts_param.key + offset,
|
||||||
|
|
@ -487,7 +487,7 @@ static int fullxts_aes_crypt(struct skcipher_request *req, unsigned long modifi
|
||||||
memcpy(fxts_param.tweak, req->iv, AES_BLOCK_SIZE);
|
memcpy(fxts_param.tweak, req->iv, AES_BLOCK_SIZE);
|
||||||
fxts_param.nap[0] = 0x01; /* initial alpha power (1, little-endian) */
|
fxts_param.nap[0] = 0x01; /* initial alpha power (1, little-endian) */
|
||||||
|
|
||||||
while (!ret && ((nbytes = walk.nbytes) != 0)) {
|
while ((nbytes = walk.nbytes) != 0) {
|
||||||
/* only use complete blocks */
|
/* only use complete blocks */
|
||||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||||
cpacf_km(xts_ctx->fc | modifier, fxts_param.key + offset,
|
cpacf_km(xts_ctx->fc | modifier, fxts_param.key + offset,
|
||||||
|
|
@ -562,64 +562,48 @@ static unsigned int __ctrblk_init(u8 *ctrptr, u8 *iv, unsigned int nbytes)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __ctr_aes_crypt(struct s390_aes_ctx *sctx,
|
|
||||||
struct skcipher_walk *walk, bool locked)
|
|
||||||
{
|
|
||||||
unsigned int n, nbytes;
|
|
||||||
int ret = 0;
|
|
||||||
u8 *ctrptr;
|
|
||||||
|
|
||||||
while (!ret && ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE)) {
|
|
||||||
n = AES_BLOCK_SIZE;
|
|
||||||
if (nbytes >= 2 * AES_BLOCK_SIZE && locked)
|
|
||||||
n = __ctrblk_init(ctrblk, walk->iv, nbytes);
|
|
||||||
ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk->iv;
|
|
||||||
cpacf_kmctr(sctx->fc, sctx->key, walk->dst.virt.addr,
|
|
||||||
walk->src.virt.addr, n, ctrptr);
|
|
||||||
if (ctrptr == ctrblk)
|
|
||||||
memcpy(walk->iv, ctrptr + n - AES_BLOCK_SIZE,
|
|
||||||
AES_BLOCK_SIZE);
|
|
||||||
crypto_inc(walk->iv, AES_BLOCK_SIZE);
|
|
||||||
ret = skcipher_walk_done(walk, nbytes - n);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ctr_aes_crypt(struct skcipher_request *req)
|
static int ctr_aes_crypt(struct skcipher_request *req)
|
||||||
{
|
{
|
||||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||||
struct s390_aes_ctx *sctx = crypto_skcipher_ctx(tfm);
|
struct s390_aes_ctx *sctx = crypto_skcipher_ctx(tfm);
|
||||||
|
u8 buf[AES_BLOCK_SIZE], *ctrptr;
|
||||||
struct skcipher_walk walk;
|
struct skcipher_walk walk;
|
||||||
u8 buf[AES_BLOCK_SIZE];
|
unsigned int n, nbytes;
|
||||||
int ret;
|
int ret, locked;
|
||||||
|
|
||||||
if (unlikely(!sctx->fc))
|
if (unlikely(!sctx->fc))
|
||||||
return fallback_skcipher_crypt(sctx, req, 0);
|
return fallback_skcipher_crypt(sctx, req, 0);
|
||||||
|
|
||||||
|
locked = mutex_trylock(&ctrblk_lock);
|
||||||
|
|
||||||
ret = skcipher_walk_virt(&walk, req, false);
|
ret = skcipher_walk_virt(&walk, req, false);
|
||||||
if (ret)
|
while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
|
||||||
return ret;
|
n = AES_BLOCK_SIZE;
|
||||||
|
|
||||||
if (down_trylock(&ctrblk_sem) == 0) {
|
if (nbytes >= 2*AES_BLOCK_SIZE && locked)
|
||||||
ret = __ctr_aes_crypt(sctx, &walk, true);
|
n = __ctrblk_init(ctrblk, walk.iv, nbytes);
|
||||||
up(&ctrblk_sem);
|
ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk.iv;
|
||||||
} else {
|
cpacf_kmctr(sctx->fc, sctx->key, walk.dst.virt.addr,
|
||||||
ret = __ctr_aes_crypt(sctx, &walk, false);
|
walk.src.virt.addr, n, ctrptr);
|
||||||
|
if (ctrptr == ctrblk)
|
||||||
|
memcpy(walk.iv, ctrptr + n - AES_BLOCK_SIZE,
|
||||||
|
AES_BLOCK_SIZE);
|
||||||
|
crypto_inc(walk.iv, AES_BLOCK_SIZE);
|
||||||
|
ret = skcipher_walk_done(&walk, nbytes - n);
|
||||||
}
|
}
|
||||||
|
if (locked)
|
||||||
|
mutex_unlock(&ctrblk_lock);
|
||||||
/*
|
/*
|
||||||
* final block may be < AES_BLOCK_SIZE, copy only nbytes
|
* final block may be < AES_BLOCK_SIZE, copy only nbytes
|
||||||
*/
|
*/
|
||||||
if (!ret && walk.nbytes > 0) {
|
if (nbytes) {
|
||||||
memset(buf, 0, AES_BLOCK_SIZE);
|
memset(buf, 0, AES_BLOCK_SIZE);
|
||||||
memcpy(buf, walk.src.virt.addr, walk.nbytes);
|
memcpy(buf, walk.src.virt.addr, nbytes);
|
||||||
cpacf_kmctr(sctx->fc, sctx->key, buf, buf,
|
cpacf_kmctr(sctx->fc, sctx->key, buf, buf,
|
||||||
AES_BLOCK_SIZE, walk.iv);
|
AES_BLOCK_SIZE, walk.iv);
|
||||||
memcpy(walk.dst.virt.addr, buf, walk.nbytes);
|
memcpy(walk.dst.virt.addr, buf, nbytes);
|
||||||
crypto_inc(walk.iv, AES_BLOCK_SIZE);
|
crypto_inc(walk.iv, AES_BLOCK_SIZE);
|
||||||
ret = skcipher_walk_done(&walk, 0);
|
ret = skcipher_walk_done(&walk, 0);
|
||||||
memzero_explicit(buf, sizeof(buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -911,14 +895,10 @@ static int gcm_aes_crypt(struct aead_request *req, unsigned int flags)
|
||||||
gw_in.ptr, aad_bytes);
|
gw_in.ptr, aad_bytes);
|
||||||
|
|
||||||
n = aad_bytes + pc_bytes;
|
n = aad_bytes + pc_bytes;
|
||||||
if (gcm_in_walk_done(&gw_in, n) != n) {
|
if (gcm_in_walk_done(&gw_in, n) != n)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto out;
|
if (gcm_out_walk_done(&gw_out, n) != n)
|
||||||
}
|
return -ENOMEM;
|
||||||
if (gcm_out_walk_done(&gw_out, n) != n) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
aadlen -= aad_bytes;
|
aadlen -= aad_bytes;
|
||||||
pclen -= pc_bytes;
|
pclen -= pc_bytes;
|
||||||
} while (aadlen + pclen > 0);
|
} while (aadlen + pclen > 0);
|
||||||
|
|
@ -930,10 +910,7 @@ static int gcm_aes_crypt(struct aead_request *req, unsigned int flags)
|
||||||
} else
|
} else
|
||||||
scatterwalk_map_and_copy(param.t, req->dst, len, taglen, 1);
|
scatterwalk_map_and_copy(param.t, req->dst, len, taglen, 1);
|
||||||
|
|
||||||
out:
|
|
||||||
memzero_explicit(¶m, sizeof(param));
|
memzero_explicit(¶m, sizeof(param));
|
||||||
memzero_explicit(gw_in.buf, sizeof(gw_in.buf));
|
|
||||||
memzero_explicit(gw_out.buf, sizeof(gw_out.buf));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/miscdevice.h>
|
#include <linux/miscdevice.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/semaphore.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <crypto/aes.h>
|
#include <crypto/aes.h>
|
||||||
#include <crypto/algapi.h>
|
#include <crypto/algapi.h>
|
||||||
|
|
@ -45,7 +45,7 @@ module_param_named(clrkey, pkey_clrkey_allowed, bool, 0444);
|
||||||
MODULE_PARM_DESC(clrkey, "Allow clear key material (default N)");
|
MODULE_PARM_DESC(clrkey, "Allow clear key material (default N)");
|
||||||
|
|
||||||
static u8 *ctrblk;
|
static u8 *ctrblk;
|
||||||
static DEFINE_SEMAPHORE(ctrblk_sem, 1);
|
static DEFINE_MUTEX(ctrblk_lock);
|
||||||
|
|
||||||
static cpacf_mask_t km_functions, kmc_functions, kmctr_functions;
|
static cpacf_mask_t km_functions, kmc_functions, kmctr_functions;
|
||||||
|
|
||||||
|
|
@ -220,10 +220,6 @@ static inline int convert_key(const u8 *key, unsigned int keylen,
|
||||||
xflags);
|
xflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* But finally map -EBUSY to -EIO to indicate an IO failure */
|
|
||||||
if (rc == -EBUSY)
|
|
||||||
rc = -EIO;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -436,11 +432,8 @@ static int ecb_paes_do_crypt(struct s390_paes_ctx *ctx,
|
||||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||||
k = cpacf_km(ctx->fc | req_ctx->modifier, param,
|
k = cpacf_km(ctx->fc | req_ctx->modifier, param,
|
||||||
walk->dst.virt.addr, walk->src.virt.addr, n);
|
walk->dst.virt.addr, walk->src.virt.addr, n);
|
||||||
if (k) {
|
if (k)
|
||||||
rc = skcipher_walk_done(walk, nbytes - k);
|
rc = skcipher_walk_done(walk, nbytes - k);
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (k < n) {
|
if (k < n) {
|
||||||
if (!maysleep) {
|
if (!maysleep) {
|
||||||
rc = -EKEYEXPIRED;
|
rc = -EKEYEXPIRED;
|
||||||
|
|
@ -467,7 +460,6 @@ static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
|
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
|
||||||
struct skcipher_walk *walk = &req_ctx->walk;
|
struct skcipher_walk *walk = &req_ctx->walk;
|
||||||
bool tested = crypto_skcipher_tested(tfm);
|
bool tested = crypto_skcipher_tested(tfm);
|
||||||
bool cleanup = true;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -499,17 +491,15 @@ static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
if (rc == 0 || rc == -EKEYEXPIRED) {
|
if (rc == 0 || rc == -EKEYEXPIRED) {
|
||||||
atomic_inc(&ctx->via_engine_ctr);
|
atomic_inc(&ctx->via_engine_ctr);
|
||||||
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
|
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
|
||||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
if (rc != -EINPROGRESS)
|
||||||
cleanup = false;
|
|
||||||
else
|
|
||||||
atomic_dec(&ctx->via_engine_ctr);
|
atomic_dec(&ctx->via_engine_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanup && walk->nbytes)
|
if (rc != -EINPROGRESS)
|
||||||
skcipher_walk_done(walk, rc);
|
skcipher_walk_done(walk, rc);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (cleanup)
|
if (rc != -EINPROGRESS)
|
||||||
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
|
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -559,7 +549,7 @@ static int ecb_paes_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
rc = ecb_paes_do_crypt(ctx, req_ctx, tested, true);
|
rc = ecb_paes_do_crypt(ctx, req_ctx, tested, true);
|
||||||
if (rc == -EKEYEXPIRED) {
|
if (rc == -EKEYEXPIRED) {
|
||||||
return pkey_handle_expired();
|
return pkey_handle_expired();
|
||||||
} else if (rc && walk->nbytes) {
|
} else if (rc) {
|
||||||
skcipher_walk_done(walk, rc);
|
skcipher_walk_done(walk, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -569,7 +559,7 @@ static int ecb_paes_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
atomic_dec(&ctx->via_engine_ctr);
|
atomic_dec(&ctx->via_engine_ctr);
|
||||||
crypto_finalize_skcipher_request(engine, req, rc);
|
crypto_finalize_skcipher_request(engine, req, rc);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct skcipher_engine_alg ecb_paes_alg = {
|
static struct skcipher_engine_alg ecb_paes_alg = {
|
||||||
|
|
@ -577,7 +567,6 @@ static struct skcipher_engine_alg ecb_paes_alg = {
|
||||||
.base.cra_name = "ecb(paes)",
|
.base.cra_name = "ecb(paes)",
|
||||||
.base.cra_driver_name = "ecb-paes-s390",
|
.base.cra_driver_name = "ecb-paes-s390",
|
||||||
.base.cra_priority = 401, /* combo: aes + ecb + 1 */
|
.base.cra_priority = 401, /* combo: aes + ecb + 1 */
|
||||||
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
|
|
||||||
.base.cra_blocksize = AES_BLOCK_SIZE,
|
.base.cra_blocksize = AES_BLOCK_SIZE,
|
||||||
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
||||||
.base.cra_module = THIS_MODULE,
|
.base.cra_module = THIS_MODULE,
|
||||||
|
|
@ -701,8 +690,6 @@ static int cbc_paes_do_crypt(struct s390_paes_ctx *ctx,
|
||||||
if (k) {
|
if (k) {
|
||||||
memcpy(walk->iv, param->iv, AES_BLOCK_SIZE);
|
memcpy(walk->iv, param->iv, AES_BLOCK_SIZE);
|
||||||
rc = skcipher_walk_done(walk, nbytes - k);
|
rc = skcipher_walk_done(walk, nbytes - k);
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
if (k < n) {
|
if (k < n) {
|
||||||
if (!maysleep) {
|
if (!maysleep) {
|
||||||
|
|
@ -730,7 +717,6 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
|
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
|
||||||
struct skcipher_walk *walk = &req_ctx->walk;
|
struct skcipher_walk *walk = &req_ctx->walk;
|
||||||
bool tested = crypto_skcipher_tested(tfm);
|
bool tested = crypto_skcipher_tested(tfm);
|
||||||
bool cleanup = true;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -762,17 +748,15 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
|
||||||
if (rc == 0 || rc == -EKEYEXPIRED) {
|
if (rc == 0 || rc == -EKEYEXPIRED) {
|
||||||
atomic_inc(&ctx->via_engine_ctr);
|
atomic_inc(&ctx->via_engine_ctr);
|
||||||
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
|
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
|
||||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
if (rc != -EINPROGRESS)
|
||||||
cleanup = false;
|
|
||||||
else
|
|
||||||
atomic_dec(&ctx->via_engine_ctr);
|
atomic_dec(&ctx->via_engine_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanup && walk->nbytes)
|
if (rc != -EINPROGRESS)
|
||||||
skcipher_walk_done(walk, rc);
|
skcipher_walk_done(walk, rc);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (cleanup)
|
if (rc != -EINPROGRESS)
|
||||||
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
|
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -822,7 +806,7 @@ static int cbc_paes_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
rc = cbc_paes_do_crypt(ctx, req_ctx, tested, true);
|
rc = cbc_paes_do_crypt(ctx, req_ctx, tested, true);
|
||||||
if (rc == -EKEYEXPIRED) {
|
if (rc == -EKEYEXPIRED) {
|
||||||
return pkey_handle_expired();
|
return pkey_handle_expired();
|
||||||
} else if (rc && walk->nbytes) {
|
} else if (rc) {
|
||||||
skcipher_walk_done(walk, rc);
|
skcipher_walk_done(walk, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -832,7 +816,7 @@ static int cbc_paes_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
atomic_dec(&ctx->via_engine_ctr);
|
atomic_dec(&ctx->via_engine_ctr);
|
||||||
crypto_finalize_skcipher_request(engine, req, rc);
|
crypto_finalize_skcipher_request(engine, req, rc);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct skcipher_engine_alg cbc_paes_alg = {
|
static struct skcipher_engine_alg cbc_paes_alg = {
|
||||||
|
|
@ -840,7 +824,6 @@ static struct skcipher_engine_alg cbc_paes_alg = {
|
||||||
.base.cra_name = "cbc(paes)",
|
.base.cra_name = "cbc(paes)",
|
||||||
.base.cra_driver_name = "cbc-paes-s390",
|
.base.cra_driver_name = "cbc-paes-s390",
|
||||||
.base.cra_priority = 402, /* cbc-paes-s390 + 1 */
|
.base.cra_priority = 402, /* cbc-paes-s390 + 1 */
|
||||||
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
|
|
||||||
.base.cra_blocksize = AES_BLOCK_SIZE,
|
.base.cra_blocksize = AES_BLOCK_SIZE,
|
||||||
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
||||||
.base.cra_module = THIS_MODULE,
|
.base.cra_module = THIS_MODULE,
|
||||||
|
|
@ -931,62 +914,15 @@ static inline unsigned int __ctrblk_init(u8 *ctrptr, u8 *iv, unsigned int nbytes
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
|
|
||||||
struct ctr_param *param,
|
|
||||||
struct skcipher_walk *walk,
|
|
||||||
bool tested, bool maysleep, bool locked)
|
|
||||||
{
|
|
||||||
unsigned int nbytes, n, k;
|
|
||||||
u8 *ctrptr;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that in case of partial processing or failure the walk
|
|
||||||
* is NOT unmapped here. So a follow up task may reuse the walk
|
|
||||||
* or in case of unrecoverable failure needs to unmap it.
|
|
||||||
*/
|
|
||||||
while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) {
|
|
||||||
n = AES_BLOCK_SIZE;
|
|
||||||
if (nbytes >= 2 * AES_BLOCK_SIZE && locked)
|
|
||||||
n = __ctrblk_init(ctrblk, walk->iv, nbytes);
|
|
||||||
ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk->iv;
|
|
||||||
k = cpacf_kmctr(ctx->fc, param, walk->dst.virt.addr,
|
|
||||||
walk->src.virt.addr, n, ctrptr);
|
|
||||||
if (k) {
|
|
||||||
if (ctrptr == ctrblk)
|
|
||||||
memcpy(walk->iv, ctrptr + k - AES_BLOCK_SIZE,
|
|
||||||
AES_BLOCK_SIZE);
|
|
||||||
crypto_inc(walk->iv, AES_BLOCK_SIZE);
|
|
||||||
rc = skcipher_walk_done(walk, nbytes - k);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (k < n) {
|
|
||||||
if (!maysleep) {
|
|
||||||
rc = -EKEYEXPIRED;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
rc = paes_convert_key(ctx, tested);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
spin_lock_bh(&ctx->pk_lock);
|
|
||||||
memcpy(param->key, ctx->pk.protkey, sizeof(param->key));
|
|
||||||
spin_unlock_bh(&ctx->pk_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
|
static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
|
||||||
struct s390_pctr_req_ctx *req_ctx,
|
struct s390_pctr_req_ctx *req_ctx,
|
||||||
bool tested, bool maysleep)
|
bool tested, bool maysleep)
|
||||||
{
|
{
|
||||||
struct ctr_param *param = &req_ctx->param;
|
struct ctr_param *param = &req_ctx->param;
|
||||||
struct skcipher_walk *walk = &req_ctx->walk;
|
struct skcipher_walk *walk = &req_ctx->walk;
|
||||||
u8 buf[AES_BLOCK_SIZE];
|
u8 buf[AES_BLOCK_SIZE], *ctrptr;
|
||||||
int pk_state, rc = 0;
|
unsigned int nbytes, n, k;
|
||||||
|
int pk_state, locked, rc = 0;
|
||||||
|
|
||||||
if (!req_ctx->param_init_done) {
|
if (!req_ctx->param_init_done) {
|
||||||
/* fetch and check protected key state */
|
/* fetch and check protected key state */
|
||||||
|
|
@ -1012,17 +948,52 @@ static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (down_trylock(&ctrblk_sem) == 0) {
|
locked = mutex_trylock(&ctrblk_lock);
|
||||||
rc = __ctr_paes_do_crypt(ctx, param, walk, tested, maysleep, true);
|
|
||||||
up(&ctrblk_sem);
|
/*
|
||||||
} else {
|
* Note that in case of partial processing or failure the walk
|
||||||
rc = __ctr_paes_do_crypt(ctx, param, walk, tested, maysleep, false);
|
* is NOT unmapped here. So a follow up task may reuse the walk
|
||||||
|
* or in case of unrecoverable failure needs to unmap it.
|
||||||
|
*/
|
||||||
|
while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) {
|
||||||
|
n = AES_BLOCK_SIZE;
|
||||||
|
if (nbytes >= 2 * AES_BLOCK_SIZE && locked)
|
||||||
|
n = __ctrblk_init(ctrblk, walk->iv, nbytes);
|
||||||
|
ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk->iv;
|
||||||
|
k = cpacf_kmctr(ctx->fc, param, walk->dst.virt.addr,
|
||||||
|
walk->src.virt.addr, n, ctrptr);
|
||||||
|
if (k) {
|
||||||
|
if (ctrptr == ctrblk)
|
||||||
|
memcpy(walk->iv, ctrptr + k - AES_BLOCK_SIZE,
|
||||||
|
AES_BLOCK_SIZE);
|
||||||
|
crypto_inc(walk->iv, AES_BLOCK_SIZE);
|
||||||
|
rc = skcipher_walk_done(walk, nbytes - k);
|
||||||
|
}
|
||||||
|
if (k < n) {
|
||||||
|
if (!maysleep) {
|
||||||
|
if (locked)
|
||||||
|
mutex_unlock(&ctrblk_lock);
|
||||||
|
rc = -EKEYEXPIRED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rc = paes_convert_key(ctx, tested);
|
||||||
|
if (rc) {
|
||||||
|
if (locked)
|
||||||
|
mutex_unlock(&ctrblk_lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
spin_lock_bh(&ctx->pk_lock);
|
||||||
|
memcpy(param->key, ctx->pk.protkey, sizeof(param->key));
|
||||||
|
spin_unlock_bh(&ctx->pk_lock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (locked)
|
||||||
|
mutex_unlock(&ctrblk_lock);
|
||||||
|
|
||||||
/* final block may be < AES_BLOCK_SIZE, copy only nbytes */
|
/* final block may be < AES_BLOCK_SIZE, copy only nbytes */
|
||||||
if (!rc && walk->nbytes > 0) {
|
if (nbytes) {
|
||||||
memset(buf, 0, AES_BLOCK_SIZE);
|
memset(buf, 0, AES_BLOCK_SIZE);
|
||||||
memcpy(buf, walk->src.virt.addr, walk->nbytes);
|
memcpy(buf, walk->src.virt.addr, nbytes);
|
||||||
while (1) {
|
while (1) {
|
||||||
if (cpacf_kmctr(ctx->fc, param, buf,
|
if (cpacf_kmctr(ctx->fc, param, buf,
|
||||||
buf, AES_BLOCK_SIZE,
|
buf, AES_BLOCK_SIZE,
|
||||||
|
|
@ -1039,13 +1010,12 @@ static int ctr_paes_do_crypt(struct s390_paes_ctx *ctx,
|
||||||
memcpy(param->key, ctx->pk.protkey, sizeof(param->key));
|
memcpy(param->key, ctx->pk.protkey, sizeof(param->key));
|
||||||
spin_unlock_bh(&ctx->pk_lock);
|
spin_unlock_bh(&ctx->pk_lock);
|
||||||
}
|
}
|
||||||
memcpy(walk->dst.virt.addr, buf, walk->nbytes);
|
memcpy(walk->dst.virt.addr, buf, nbytes);
|
||||||
crypto_inc(walk->iv, AES_BLOCK_SIZE);
|
crypto_inc(walk->iv, AES_BLOCK_SIZE);
|
||||||
rc = skcipher_walk_done(walk, 0);
|
rc = skcipher_walk_done(walk, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
memzero_explicit(buf, sizeof(buf));
|
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -1057,7 +1027,6 @@ static int ctr_paes_crypt(struct skcipher_request *req)
|
||||||
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
|
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
|
||||||
struct skcipher_walk *walk = &req_ctx->walk;
|
struct skcipher_walk *walk = &req_ctx->walk;
|
||||||
bool tested = crypto_skcipher_tested(tfm);
|
bool tested = crypto_skcipher_tested(tfm);
|
||||||
bool cleanup = true;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1088,17 +1057,15 @@ static int ctr_paes_crypt(struct skcipher_request *req)
|
||||||
if (rc == 0 || rc == -EKEYEXPIRED) {
|
if (rc == 0 || rc == -EKEYEXPIRED) {
|
||||||
atomic_inc(&ctx->via_engine_ctr);
|
atomic_inc(&ctx->via_engine_ctr);
|
||||||
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
|
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
|
||||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
if (rc != -EINPROGRESS)
|
||||||
cleanup = false;
|
|
||||||
else
|
|
||||||
atomic_dec(&ctx->via_engine_ctr);
|
atomic_dec(&ctx->via_engine_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanup && walk->nbytes)
|
if (rc != -EINPROGRESS)
|
||||||
skcipher_walk_done(walk, rc);
|
skcipher_walk_done(walk, rc);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (cleanup)
|
if (rc != -EINPROGRESS)
|
||||||
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
|
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -1138,7 +1105,7 @@ static int ctr_paes_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
rc = ctr_paes_do_crypt(ctx, req_ctx, tested, true);
|
rc = ctr_paes_do_crypt(ctx, req_ctx, tested, true);
|
||||||
if (rc == -EKEYEXPIRED) {
|
if (rc == -EKEYEXPIRED) {
|
||||||
return pkey_handle_expired();
|
return pkey_handle_expired();
|
||||||
} else if (rc && walk->nbytes) {
|
} else if (rc) {
|
||||||
skcipher_walk_done(walk, rc);
|
skcipher_walk_done(walk, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1148,7 +1115,7 @@ static int ctr_paes_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
atomic_dec(&ctx->via_engine_ctr);
|
atomic_dec(&ctx->via_engine_ctr);
|
||||||
crypto_finalize_skcipher_request(engine, req, rc);
|
crypto_finalize_skcipher_request(engine, req, rc);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct skcipher_engine_alg ctr_paes_alg = {
|
static struct skcipher_engine_alg ctr_paes_alg = {
|
||||||
|
|
@ -1156,7 +1123,6 @@ static struct skcipher_engine_alg ctr_paes_alg = {
|
||||||
.base.cra_name = "ctr(paes)",
|
.base.cra_name = "ctr(paes)",
|
||||||
.base.cra_driver_name = "ctr-paes-s390",
|
.base.cra_driver_name = "ctr-paes-s390",
|
||||||
.base.cra_priority = 402, /* ecb-paes-s390 + 1 */
|
.base.cra_priority = 402, /* ecb-paes-s390 + 1 */
|
||||||
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
|
|
||||||
.base.cra_blocksize = 1,
|
.base.cra_blocksize = 1,
|
||||||
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
||||||
.base.cra_module = THIS_MODULE,
|
.base.cra_module = THIS_MODULE,
|
||||||
|
|
@ -1317,11 +1283,8 @@ static int xts_paes_do_crypt_fullkey(struct s390_pxts_ctx *ctx,
|
||||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||||
k = cpacf_km(ctx->fc | req_ctx->modifier, param->key + offset,
|
k = cpacf_km(ctx->fc | req_ctx->modifier, param->key + offset,
|
||||||
walk->dst.virt.addr, walk->src.virt.addr, n);
|
walk->dst.virt.addr, walk->src.virt.addr, n);
|
||||||
if (k) {
|
if (k)
|
||||||
rc = skcipher_walk_done(walk, nbytes - k);
|
rc = skcipher_walk_done(walk, nbytes - k);
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (k < n) {
|
if (k < n) {
|
||||||
if (!maysleep) {
|
if (!maysleep) {
|
||||||
rc = -EKEYEXPIRED;
|
rc = -EKEYEXPIRED;
|
||||||
|
|
@ -1374,7 +1337,7 @@ static inline int __xts_2keys_prep_param(struct s390_pxts_ctx *ctx,
|
||||||
memcpy(param->init, pcc_param.xts, 16);
|
memcpy(param->init, pcc_param.xts, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
memzero_explicit(&pcc_param, sizeof(pcc_param));
|
memzero_explicit(pcc_param.key, sizeof(pcc_param.key));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1414,11 +1377,8 @@ static int xts_paes_do_crypt_2keys(struct s390_pxts_ctx *ctx,
|
||||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||||
k = cpacf_km(ctx->fc | req_ctx->modifier, param->key + offset,
|
k = cpacf_km(ctx->fc | req_ctx->modifier, param->key + offset,
|
||||||
walk->dst.virt.addr, walk->src.virt.addr, n);
|
walk->dst.virt.addr, walk->src.virt.addr, n);
|
||||||
if (k) {
|
if (k)
|
||||||
rc = skcipher_walk_done(walk, nbytes - k);
|
rc = skcipher_walk_done(walk, nbytes - k);
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (k < n) {
|
if (k < n) {
|
||||||
if (!maysleep) {
|
if (!maysleep) {
|
||||||
rc = -EKEYEXPIRED;
|
rc = -EKEYEXPIRED;
|
||||||
|
|
@ -1490,7 +1450,6 @@ static inline int xts_paes_crypt(struct skcipher_request *req, unsigned long mod
|
||||||
struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm);
|
struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm);
|
||||||
struct skcipher_walk *walk = &req_ctx->walk;
|
struct skcipher_walk *walk = &req_ctx->walk;
|
||||||
bool tested = crypto_skcipher_tested(tfm);
|
bool tested = crypto_skcipher_tested(tfm);
|
||||||
bool cleanup = true;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1522,17 +1481,15 @@ static inline int xts_paes_crypt(struct skcipher_request *req, unsigned long mod
|
||||||
if (rc == 0 || rc == -EKEYEXPIRED) {
|
if (rc == 0 || rc == -EKEYEXPIRED) {
|
||||||
atomic_inc(&ctx->via_engine_ctr);
|
atomic_inc(&ctx->via_engine_ctr);
|
||||||
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
|
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
|
||||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
if (rc != -EINPROGRESS)
|
||||||
cleanup = false;
|
|
||||||
else
|
|
||||||
atomic_dec(&ctx->via_engine_ctr);
|
atomic_dec(&ctx->via_engine_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanup && walk->nbytes)
|
if (rc != -EINPROGRESS)
|
||||||
skcipher_walk_done(walk, rc);
|
skcipher_walk_done(walk, rc);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (cleanup)
|
if (rc != -EINPROGRESS)
|
||||||
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
|
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -1582,7 +1539,7 @@ static int xts_paes_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
rc = xts_paes_do_crypt(ctx, req_ctx, tested, true);
|
rc = xts_paes_do_crypt(ctx, req_ctx, tested, true);
|
||||||
if (rc == -EKEYEXPIRED) {
|
if (rc == -EKEYEXPIRED) {
|
||||||
return pkey_handle_expired();
|
return pkey_handle_expired();
|
||||||
} else if (rc && walk->nbytes) {
|
} else if (rc) {
|
||||||
skcipher_walk_done(walk, rc);
|
skcipher_walk_done(walk, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1592,7 +1549,7 @@ static int xts_paes_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
atomic_dec(&ctx->via_engine_ctr);
|
atomic_dec(&ctx->via_engine_ctr);
|
||||||
crypto_finalize_skcipher_request(engine, req, rc);
|
crypto_finalize_skcipher_request(engine, req, rc);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct skcipher_engine_alg xts_paes_alg = {
|
static struct skcipher_engine_alg xts_paes_alg = {
|
||||||
|
|
@ -1600,7 +1557,6 @@ static struct skcipher_engine_alg xts_paes_alg = {
|
||||||
.base.cra_name = "xts(paes)",
|
.base.cra_name = "xts(paes)",
|
||||||
.base.cra_driver_name = "xts-paes-s390",
|
.base.cra_driver_name = "xts-paes-s390",
|
||||||
.base.cra_priority = 402, /* ecb-paes-s390 + 1 */
|
.base.cra_priority = 402, /* ecb-paes-s390 + 1 */
|
||||||
.base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
|
|
||||||
.base.cra_blocksize = AES_BLOCK_SIZE,
|
.base.cra_blocksize = AES_BLOCK_SIZE,
|
||||||
.base.cra_ctxsize = sizeof(struct s390_pxts_ctx),
|
.base.cra_ctxsize = sizeof(struct s390_pxts_ctx),
|
||||||
.base.cra_module = THIS_MODULE,
|
.base.cra_module = THIS_MODULE,
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,8 @@ static inline int hwh_prepare(struct ahash_request *req,
|
||||||
*/
|
*/
|
||||||
static inline int hwh_advance(struct hash_walk_helper *hwh, int n)
|
static inline int hwh_advance(struct hash_walk_helper *hwh, int n)
|
||||||
{
|
{
|
||||||
if (n < 0) {
|
if (n < 0)
|
||||||
hwh->walkbytes = n;
|
|
||||||
return crypto_hash_walk_done(&hwh->walk, n);
|
return crypto_hash_walk_done(&hwh->walk, n);
|
||||||
}
|
|
||||||
|
|
||||||
hwh->walkbytes -= n;
|
hwh->walkbytes -= n;
|
||||||
hwh->walkaddr += n;
|
hwh->walkaddr += n;
|
||||||
|
|
@ -341,10 +339,6 @@ static inline int convert_key(const u8 *key, unsigned int keylen,
|
||||||
xflags);
|
xflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* But finally map -EBUSY to -EIO to indicate an IO failure */
|
|
||||||
if (rc == -EBUSY)
|
|
||||||
rc = -EIO;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -612,7 +606,6 @@ static int phmac_update(struct ahash_request *req)
|
||||||
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
||||||
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
||||||
struct hash_walk_helper *hwh = &req_ctx->hwh;
|
struct hash_walk_helper *hwh = &req_ctx->hwh;
|
||||||
bool cleanup = true;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* prep the walk in the request context */
|
/* prep the walk in the request context */
|
||||||
|
|
@ -636,15 +629,12 @@ static int phmac_update(struct ahash_request *req)
|
||||||
req_ctx->async_op = OP_UPDATE;
|
req_ctx->async_op = OP_UPDATE;
|
||||||
atomic_inc(&tfm_ctx->via_engine_ctr);
|
atomic_inc(&tfm_ctx->via_engine_ctr);
|
||||||
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
||||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
if (rc != -EINPROGRESS)
|
||||||
cleanup = false;
|
|
||||||
else
|
|
||||||
atomic_dec(&tfm_ctx->via_engine_ctr);
|
atomic_dec(&tfm_ctx->via_engine_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanup) {
|
if (rc != -EINPROGRESS) {
|
||||||
if (hwh->walkbytes > 0)
|
hwh_advance(hwh, rc);
|
||||||
hwh_advance(hwh, rc);
|
|
||||||
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -659,7 +649,6 @@ static int phmac_final(struct ahash_request *req)
|
||||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||||
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
||||||
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
||||||
bool cleanup = true;
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* Try synchronous operation if no active engine usage */
|
/* Try synchronous operation if no active engine usage */
|
||||||
|
|
@ -678,14 +667,12 @@ static int phmac_final(struct ahash_request *req)
|
||||||
req_ctx->async_op = OP_FINAL;
|
req_ctx->async_op = OP_FINAL;
|
||||||
atomic_inc(&tfm_ctx->via_engine_ctr);
|
atomic_inc(&tfm_ctx->via_engine_ctr);
|
||||||
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
||||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
if (rc != -EINPROGRESS)
|
||||||
cleanup = false;
|
|
||||||
else
|
|
||||||
atomic_dec(&tfm_ctx->via_engine_ctr);
|
atomic_dec(&tfm_ctx->via_engine_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (cleanup)
|
if (rc != -EINPROGRESS)
|
||||||
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -698,7 +685,6 @@ static int phmac_finup(struct ahash_request *req)
|
||||||
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
||||||
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
||||||
struct hash_walk_helper *hwh = &req_ctx->hwh;
|
struct hash_walk_helper *hwh = &req_ctx->hwh;
|
||||||
bool cleanup = true;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* prep the walk in the request context */
|
/* prep the walk in the request context */
|
||||||
|
|
@ -730,17 +716,15 @@ static int phmac_finup(struct ahash_request *req)
|
||||||
/* req->async_op has been set to either OP_FINUP or OP_FINAL */
|
/* req->async_op has been set to either OP_FINUP or OP_FINAL */
|
||||||
atomic_inc(&tfm_ctx->via_engine_ctr);
|
atomic_inc(&tfm_ctx->via_engine_ctr);
|
||||||
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
||||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
if (rc != -EINPROGRESS)
|
||||||
cleanup = false;
|
|
||||||
else
|
|
||||||
atomic_dec(&tfm_ctx->via_engine_ctr);
|
atomic_dec(&tfm_ctx->via_engine_ctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanup && hwh->walkbytes > 0)
|
if (rc != -EINPROGRESS)
|
||||||
hwh_advance(hwh, rc);
|
hwh_advance(hwh, rc);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (cleanup)
|
if (rc != -EINPROGRESS)
|
||||||
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
||||||
pr_debug("rc=%d\n", rc);
|
pr_debug("rc=%d\n", rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -930,7 +914,7 @@ static int phmac_do_one_request(struct crypto_engine *engine, void *areq)
|
||||||
atomic_dec(&tfm_ctx->via_engine_ctr);
|
atomic_dec(&tfm_ctx->via_engine_ctr);
|
||||||
crypto_finalize_hash_request(engine, req, rc);
|
crypto_finalize_hash_request(engine, req, rc);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define S390_ASYNC_PHMAC_ALG(x) \
|
#define S390_ASYNC_PHMAC_ALG(x) \
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,6 @@ static __always_inline void __cpacf_query(unsigned int opcode,
|
||||||
cpacf_mask_t *mask)
|
cpacf_mask_t *mask)
|
||||||
{
|
{
|
||||||
__cpacf_query_insn(opcode, mask, CPACF_FC_QUERY);
|
__cpacf_query_insn(opcode, mask, CPACF_FC_QUERY);
|
||||||
kmsan_unpoison_memory(mask, sizeof(*mask));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline int __cpacf_check_opcode(unsigned int opcode)
|
static __always_inline int __cpacf_check_opcode(unsigned int opcode)
|
||||||
|
|
@ -371,7 +370,6 @@ static __always_inline int cpacf_query_func(unsigned int opcode,
|
||||||
static __always_inline void __cpacf_qai(unsigned int opcode, cpacf_qai_t *qai)
|
static __always_inline void __cpacf_qai(unsigned int opcode, cpacf_qai_t *qai)
|
||||||
{
|
{
|
||||||
__cpacf_query_insn(opcode, qai, CPACF_FC_QUERY_AUTH_INFO);
|
__cpacf_query_insn(opcode, qai, CPACF_FC_QUERY_AUTH_INFO);
|
||||||
kmsan_unpoison_memory(qai, sizeof(*qai));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -424,7 +422,6 @@ static inline int cpacf_km(unsigned long func, void *param,
|
||||||
[opc] "i" (CPACF_KM)
|
[opc] "i" (CPACF_KM)
|
||||||
: "cc", "memory", "0", "1");
|
: "cc", "memory", "0", "1");
|
||||||
|
|
||||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
|
||||||
return src_len - s.odd;
|
return src_len - s.odd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -457,7 +454,6 @@ static inline int cpacf_kmc(unsigned long func, void *param,
|
||||||
[opc] "i" (CPACF_KMC)
|
[opc] "i" (CPACF_KMC)
|
||||||
: "cc", "memory", "0", "1");
|
: "cc", "memory", "0", "1");
|
||||||
|
|
||||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
|
||||||
return src_len - s.odd;
|
return src_len - s.odd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -591,7 +587,6 @@ static inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
|
||||||
[opc] "i" (CPACF_KMCTR)
|
[opc] "i" (CPACF_KMCTR)
|
||||||
: "cc", "memory", "0", "1");
|
: "cc", "memory", "0", "1");
|
||||||
|
|
||||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
|
||||||
return src_len - s.odd;
|
return src_len - s.odd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -624,7 +619,6 @@ static inline void cpacf_prno(unsigned long func, void *param,
|
||||||
: [fc] "d" (func), [pba] "d" ((unsigned long)param),
|
: [fc] "d" (func), [pba] "d" ((unsigned long)param),
|
||||||
[seed] "d" (s.pair), [opc] "i" (CPACF_PRNO)
|
[seed] "d" (s.pair), [opc] "i" (CPACF_PRNO)
|
||||||
: "cc", "memory", "0", "1");
|
: "cc", "memory", "0", "1");
|
||||||
kmsan_unpoison_memory(dest, dest_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ static __always_inline void pai_kernel_exit(struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PAI_SAVE_AREA(x) ((x)->hw.event_base)
|
#define PAI_SAVE_AREA(x) ((x)->hw.event_base)
|
||||||
|
#define PAI_CPU_MASK(x) ((x)->hw.addr_filters)
|
||||||
#define PAI_PMU_IDX(x) ((x)->hw.last_tag)
|
#define PAI_PMU_IDX(x) ((x)->hw.last_tag)
|
||||||
#define PAI_SWLIST(x) (&(x)->hw.tp_list)
|
#define PAI_SWLIST(x) (&(x)->hw.tp_list)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ struct pcpu {
|
||||||
unsigned long ec_mask; /* bit mask for ec_xxx functions */
|
unsigned long ec_mask; /* bit mask for ec_xxx functions */
|
||||||
unsigned long ec_clk; /* sigp timestamp for ec_xxx */
|
unsigned long ec_clk; /* sigp timestamp for ec_xxx */
|
||||||
unsigned long flags; /* per CPU flags */
|
unsigned long flags; /* per CPU flags */
|
||||||
|
unsigned long capacity; /* cpu capacity for scheduler */
|
||||||
signed char state; /* physical cpu state */
|
signed char state; /* physical cpu state */
|
||||||
signed char polarization; /* physical polarization */
|
signed char polarization; /* physical polarization */
|
||||||
u16 address; /* physical cpu address */
|
u16 address; /* physical cpu address */
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ static __always_inline unsigned int raw_smp_processor_id(void)
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define arch_scale_cpu_capacity topology_get_cpu_scale
|
#define arch_scale_cpu_capacity smp_cpu_get_capacity
|
||||||
|
|
||||||
extern struct mutex smp_cpu_state_mutex;
|
extern struct mutex smp_cpu_state_mutex;
|
||||||
extern unsigned int smp_cpu_mt_shift;
|
extern unsigned int smp_cpu_mt_shift;
|
||||||
|
|
@ -53,7 +53,9 @@ extern void smp_save_dump_secondary_cpus(void);
|
||||||
extern void smp_yield_cpu(int cpu);
|
extern void smp_yield_cpu(int cpu);
|
||||||
extern void smp_cpu_set_polarization(int cpu, int val);
|
extern void smp_cpu_set_polarization(int cpu, int val);
|
||||||
extern int smp_cpu_get_polarization(int cpu);
|
extern int smp_cpu_get_polarization(int cpu);
|
||||||
|
extern void smp_cpu_set_capacity(int cpu, unsigned long val);
|
||||||
extern void smp_set_core_capacity(int cpu, unsigned long val);
|
extern void smp_set_core_capacity(int cpu, unsigned long val);
|
||||||
|
extern unsigned long smp_cpu_get_capacity(int cpu);
|
||||||
extern int smp_cpu_get_cpu_address(int cpu);
|
extern int smp_cpu_get_cpu_address(int cpu);
|
||||||
extern void smp_fill_possible_mask(void);
|
extern void smp_fill_possible_mask(void);
|
||||||
extern void smp_detect_cpus(void);
|
extern void smp_detect_cpus(void);
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ static struct debug_param_t {
|
||||||
static int debug_param_num;
|
static int debug_param_num;
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
static void debug_get_param(const char *name, int *level, int *pages, bool quiet)
|
static void debug_get_param(const char *name, int *level, int *pages)
|
||||||
{
|
{
|
||||||
struct debug_param_t *p;
|
struct debug_param_t *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -192,13 +192,11 @@ static void debug_get_param(const char *name, int *level, int *pages, bool quiet
|
||||||
if (!glob_match(p->name, name))
|
if (!glob_match(p->name, name))
|
||||||
continue;
|
continue;
|
||||||
if (level && p->level != PARAM_UNSET) {
|
if (level && p->level != PARAM_UNSET) {
|
||||||
if (!quiet)
|
pr_info("%s: override level to %d\n", name, p->level);
|
||||||
pr_info("%s: override level to %d\n", name, p->level);
|
|
||||||
*level = p->level;
|
*level = p->level;
|
||||||
}
|
}
|
||||||
if (pages && p->pages != PARAM_UNSET) {
|
if (pages && p->pages != PARAM_UNSET) {
|
||||||
if (!quiet)
|
pr_info("%s: override pages to %d\n", name, p->pages);
|
||||||
pr_info("%s: override pages to %d\n", name, p->pages);
|
|
||||||
*pages = p->pages;
|
*pages = p->pages;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -253,7 +251,7 @@ static int __init s390dbf_parse(char *arg)
|
||||||
* regular memory allocations are possible.
|
* regular memory allocations are possible.
|
||||||
*/
|
*/
|
||||||
for (i = 0, id = __s390dbf_info; &id[i] < __s390dbf_info_end; i++)
|
for (i = 0, id = __s390dbf_info; &id[i] < __s390dbf_info_end; i++)
|
||||||
debug_get_param(id[i]->name, &id[i]->level, NULL, false);
|
debug_get_param(id[i]->name, &id[i]->level, NULL);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -397,7 +395,7 @@ static debug_info_t *debug_info_create(const char *name, int pages_per_area,
|
||||||
int level = DEBUG_DEFAULT_LEVEL;
|
int level = DEBUG_DEFAULT_LEVEL;
|
||||||
debug_info_t *rc;
|
debug_info_t *rc;
|
||||||
|
|
||||||
debug_get_param(name, &level, &pages_per_area, false);
|
debug_get_param(name, &level, &pages_per_area);
|
||||||
rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, level, ALL_AREAS);
|
rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, level, ALL_AREAS);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -962,7 +960,7 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_get_param(id->name, &id->level, &pages_per_area, false);
|
debug_get_param(id->name, &id->level, &pages_per_area);
|
||||||
copy = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size,
|
copy = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size,
|
||||||
id->level, ALL_AREAS);
|
id->level, ALL_AREAS);
|
||||||
if (!copy) {
|
if (!copy) {
|
||||||
|
|
@ -1076,6 +1074,9 @@ static void _debug_set_level(debug_info_t *id, int new_level)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!id)
|
||||||
|
return;
|
||||||
|
|
||||||
if (new_level == DEBUG_OFF_LEVEL) {
|
if (new_level == DEBUG_OFF_LEVEL) {
|
||||||
pr_info("%s: switched off\n", id->name);
|
pr_info("%s: switched off\n", id->name);
|
||||||
} else if ((new_level > DEBUG_MAX_LEVEL) || (new_level < 0)) {
|
} else if ((new_level > DEBUG_MAX_LEVEL) || (new_level < 0)) {
|
||||||
|
|
@ -1100,14 +1101,8 @@ static void _debug_set_level(debug_info_t *id, int new_level)
|
||||||
*/
|
*/
|
||||||
void debug_set_level(debug_info_t *id, int new_level)
|
void debug_set_level(debug_info_t *id, int new_level)
|
||||||
{
|
{
|
||||||
if (!id)
|
/* Level specified via kernel parameter takes precedence */
|
||||||
return;
|
debug_get_param(id->name, &new_level, NULL);
|
||||||
|
|
||||||
/*
|
|
||||||
* Level specified via kernel parameter takes precedence. The override
|
|
||||||
* was already announced during registration, so stay quiet here.
|
|
||||||
*/
|
|
||||||
debug_get_param(id->name, &new_level, NULL, true);
|
|
||||||
|
|
||||||
_debug_set_level(id, new_level);
|
_debug_set_level(id, new_level);
|
||||||
}
|
}
|
||||||
|
|
@ -1283,7 +1278,7 @@ void debug_set_critical(void)
|
||||||
debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf,
|
debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf,
|
||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
debug_entry_t *active = NULL;
|
debug_entry_t *active;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!debug_active || !id->areas)
|
if (!debug_active || !id->areas)
|
||||||
|
|
@ -1294,8 +1289,6 @@ debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf,
|
||||||
} else {
|
} else {
|
||||||
raw_spin_lock_irqsave(&id->lock, flags);
|
raw_spin_lock_irqsave(&id->lock, flags);
|
||||||
}
|
}
|
||||||
if (!id->areas)
|
|
||||||
goto out;
|
|
||||||
do {
|
do {
|
||||||
active = get_active_entry(id);
|
active = get_active_entry(id);
|
||||||
memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
|
memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
|
||||||
|
|
@ -1305,7 +1298,7 @@ debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf,
|
||||||
len -= id->buf_size;
|
len -= id->buf_size;
|
||||||
buf += id->buf_size;
|
buf += id->buf_size;
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
out:
|
|
||||||
raw_spin_unlock_irqrestore(&id->lock, flags);
|
raw_spin_unlock_irqrestore(&id->lock, flags);
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
@ -1318,7 +1311,7 @@ EXPORT_SYMBOL(debug_event_common);
|
||||||
debug_entry_t *debug_exception_common(debug_info_t *id, int level,
|
debug_entry_t *debug_exception_common(debug_info_t *id, int level,
|
||||||
const void *buf, int len)
|
const void *buf, int len)
|
||||||
{
|
{
|
||||||
debug_entry_t *active = NULL;
|
debug_entry_t *active;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!debug_active || !id->areas)
|
if (!debug_active || !id->areas)
|
||||||
|
|
@ -1329,8 +1322,6 @@ debug_entry_t *debug_exception_common(debug_info_t *id, int level,
|
||||||
} else {
|
} else {
|
||||||
raw_spin_lock_irqsave(&id->lock, flags);
|
raw_spin_lock_irqsave(&id->lock, flags);
|
||||||
}
|
}
|
||||||
if (!id->areas)
|
|
||||||
goto out;
|
|
||||||
do {
|
do {
|
||||||
active = get_active_entry(id);
|
active = get_active_entry(id);
|
||||||
memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
|
memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
|
||||||
|
|
@ -1340,7 +1331,7 @@ debug_entry_t *debug_exception_common(debug_info_t *id, int level,
|
||||||
len -= id->buf_size;
|
len -= id->buf_size;
|
||||||
buf += id->buf_size;
|
buf += id->buf_size;
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
out:
|
|
||||||
raw_spin_unlock_irqrestore(&id->lock, flags);
|
raw_spin_unlock_irqrestore(&id->lock, flags);
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
@ -1366,7 +1357,7 @@ static inline int debug_count_numargs(char *string)
|
||||||
debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
|
debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
|
||||||
{
|
{
|
||||||
debug_sprintf_entry_t *curr_event;
|
debug_sprintf_entry_t *curr_event;
|
||||||
debug_entry_t *active = NULL;
|
debug_entry_t *active;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int numargs, idx;
|
int numargs, idx;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
@ -1381,8 +1372,6 @@ debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string,
|
||||||
} else {
|
} else {
|
||||||
raw_spin_lock_irqsave(&id->lock, flags);
|
raw_spin_lock_irqsave(&id->lock, flags);
|
||||||
}
|
}
|
||||||
if (!id->areas)
|
|
||||||
goto out;
|
|
||||||
active = get_active_entry(id);
|
active = get_active_entry(id);
|
||||||
curr_event = (debug_sprintf_entry_t *) DEBUG_DATA(active);
|
curr_event = (debug_sprintf_entry_t *) DEBUG_DATA(active);
|
||||||
va_start(ap, string);
|
va_start(ap, string);
|
||||||
|
|
@ -1391,7 +1380,6 @@ debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string,
|
||||||
curr_event->args[idx] = va_arg(ap, long);
|
curr_event->args[idx] = va_arg(ap, long);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
debug_finish_entry(id, active, level, 0);
|
debug_finish_entry(id, active, level, 0);
|
||||||
out:
|
|
||||||
raw_spin_unlock_irqrestore(&id->lock, flags);
|
raw_spin_unlock_irqrestore(&id->lock, flags);
|
||||||
|
|
||||||
return active;
|
return active;
|
||||||
|
|
@ -1404,7 +1392,7 @@ EXPORT_SYMBOL(__debug_sprintf_event);
|
||||||
debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
|
debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
|
||||||
{
|
{
|
||||||
debug_sprintf_entry_t *curr_event;
|
debug_sprintf_entry_t *curr_event;
|
||||||
debug_entry_t *active = NULL;
|
debug_entry_t *active;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int numargs, idx;
|
int numargs, idx;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
@ -1420,8 +1408,6 @@ debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *stri
|
||||||
} else {
|
} else {
|
||||||
raw_spin_lock_irqsave(&id->lock, flags);
|
raw_spin_lock_irqsave(&id->lock, flags);
|
||||||
}
|
}
|
||||||
if (!id->areas)
|
|
||||||
goto out;
|
|
||||||
active = get_active_entry(id);
|
active = get_active_entry(id);
|
||||||
curr_event = (debug_sprintf_entry_t *)DEBUG_DATA(active);
|
curr_event = (debug_sprintf_entry_t *)DEBUG_DATA(active);
|
||||||
va_start(ap, string);
|
va_start(ap, string);
|
||||||
|
|
@ -1430,7 +1416,6 @@ debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *stri
|
||||||
curr_event->args[idx] = va_arg(ap, long);
|
curr_event->args[idx] = va_arg(ap, long);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
debug_finish_entry(id, active, level, 1);
|
debug_finish_entry(id, active, level, 1);
|
||||||
out:
|
|
||||||
raw_spin_unlock_irqrestore(&id->lock, flags);
|
raw_spin_unlock_irqrestore(&id->lock, flags);
|
||||||
|
|
||||||
return active;
|
return active;
|
||||||
|
|
@ -1673,11 +1658,9 @@ static void debug_flush(debug_info_t *id, int area)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
if (!id)
|
if (!id || !id->areas)
|
||||||
return;
|
return;
|
||||||
raw_spin_lock_irqsave(&id->lock, flags);
|
raw_spin_lock_irqsave(&id->lock, flags);
|
||||||
if (!id->areas)
|
|
||||||
goto out;
|
|
||||||
if (area == DEBUG_FLUSH_ALL) {
|
if (area == DEBUG_FLUSH_ALL) {
|
||||||
id->active_area = 0;
|
id->active_area = 0;
|
||||||
memset(id->active_entries, 0, id->nr_areas * sizeof(int));
|
memset(id->active_entries, 0, id->nr_areas * sizeof(int));
|
||||||
|
|
@ -1692,7 +1675,6 @@ static void debug_flush(debug_info_t *id, int area)
|
||||||
for (i = 0; i < id->pages_per_area; i++)
|
for (i = 0; i < id->pages_per_area; i++)
|
||||||
memset(id->areas[area][i], 0, PAGE_SIZE);
|
memset(id->areas[area][i], 0, PAGE_SIZE);
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
raw_spin_unlock_irqrestore(&id->lock, flags);
|
raw_spin_unlock_irqrestore(&id->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,8 @@ long diag324_pibbuf(unsigned long arg)
|
||||||
goto out;
|
goto out;
|
||||||
rc = copy_to_user((void __user *)address, data->pib, data->pib->len);
|
rc = copy_to_user((void __user *)address, data->pib, data->pib->len);
|
||||||
rc |= put_user(data->sequence, &udata->sequence);
|
rc |= put_user(data->sequence, &udata->sequence);
|
||||||
rc = rc ? -EFAULT : data->rc;
|
if (rc)
|
||||||
|
rc = -EFAULT;
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&pibmutex);
|
mutex_unlock(&pibmutex);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
||||||
|
|
@ -1157,8 +1157,6 @@ static struct attribute_group reipl_nss_attr_group = {
|
||||||
|
|
||||||
void set_os_info_reipl_block(void)
|
void set_os_info_reipl_block(void)
|
||||||
{
|
{
|
||||||
if (!reipl_block_actual)
|
|
||||||
return;
|
|
||||||
os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
|
os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
|
||||||
reipl_block_actual->hdr.len);
|
reipl_block_actual->hdr.len);
|
||||||
}
|
}
|
||||||
|
|
@ -1929,8 +1927,7 @@ static struct shutdown_action __refdata dump_action = {
|
||||||
static void dump_reipl_run(struct shutdown_trigger *trigger)
|
static void dump_reipl_run(struct shutdown_trigger *trigger)
|
||||||
{
|
{
|
||||||
struct lowcore *abs_lc;
|
struct lowcore *abs_lc;
|
||||||
unsigned long ipib = 0;
|
unsigned int csum;
|
||||||
unsigned int csum = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set REIPL_CLEAR flag in os_info flags entry indicating
|
* Set REIPL_CLEAR flag in os_info flags entry indicating
|
||||||
|
|
@ -1946,12 +1943,9 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
|
||||||
reipl_type == IPL_TYPE_UNKNOWN)
|
reipl_type == IPL_TYPE_UNKNOWN)
|
||||||
os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
|
os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
|
||||||
os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
|
os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
|
||||||
if (reipl_block_actual) {
|
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
|
||||||
ipib = __pa(reipl_block_actual);
|
|
||||||
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
|
|
||||||
}
|
|
||||||
abs_lc = get_abs_lowcore();
|
abs_lc = get_abs_lowcore();
|
||||||
abs_lc->ipib = ipib;
|
abs_lc->ipib = __pa(reipl_block_actual);
|
||||||
abs_lc->ipib_checksum = csum;
|
abs_lc->ipib_checksum = csum;
|
||||||
put_abs_lowcore(abs_lc);
|
put_abs_lowcore(abs_lc);
|
||||||
dump_run(trigger);
|
dump_run(trigger);
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@ struct pai_mapptr {
|
||||||
|
|
||||||
static struct pai_root { /* Anchor to per CPU data */
|
static struct pai_root { /* Anchor to per CPU data */
|
||||||
refcount_t refcnt; /* Overall active events */
|
refcount_t refcnt; /* Overall active events */
|
||||||
atomic_t tskctx; /* Overall per-task events */
|
|
||||||
struct pai_mapptr __percpu *mapptr;
|
struct pai_mapptr __percpu *mapptr;
|
||||||
} pai_root[PAI_PMU_MAX];
|
} pai_root[PAI_PMU_MAX];
|
||||||
|
|
||||||
|
|
@ -94,15 +93,14 @@ struct pai_pmu { /* Define PAI PMU characteristics */
|
||||||
static struct pai_pmu pai_pmu[]; /* Forward declaration */
|
static struct pai_pmu pai_pmu[]; /* Forward declaration */
|
||||||
|
|
||||||
/* Free per CPU data when the last event is removed. */
|
/* Free per CPU data when the last event is removed. */
|
||||||
static void pai_root_free(int idx, int tasks)
|
static void pai_root_free(int idx)
|
||||||
{
|
{
|
||||||
if (refcount_sub_and_test(tasks, &pai_root[idx].refcnt)) {
|
if (refcount_dec_and_test(&pai_root[idx].refcnt)) {
|
||||||
free_percpu(pai_root[idx].mapptr);
|
free_percpu(pai_root[idx].mapptr);
|
||||||
pai_root[idx].mapptr = NULL;
|
pai_root[idx].mapptr = NULL;
|
||||||
}
|
}
|
||||||
debug_sprintf_event(paidbg, 5, "%s root[%d].refcount %d tskctx %d\n",
|
debug_sprintf_event(paidbg, 5, "%s root[%d].refcount %d\n", __func__,
|
||||||
__func__, idx, refcount_read(&pai_root[idx].refcnt),
|
idx, refcount_read(&pai_root[idx].refcnt));
|
||||||
atomic_read(&pai_root[idx].tskctx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -139,54 +137,40 @@ static void pai_free(struct pai_mapptr *mp)
|
||||||
mp->mapptr = NULL;
|
mp->mapptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called under mutex_lock */
|
/* Adjust usage counters and remove allocated memory when all users are
|
||||||
static void pai_event_destroy_cpu(int idx, int cpu, bool hotplug)
|
* gone.
|
||||||
|
*/
|
||||||
|
static void pai_event_destroy_cpu(struct perf_event *event, int cpu)
|
||||||
{
|
{
|
||||||
struct pai_mapptr *mp;
|
int idx = PAI_PMU_IDX(event);
|
||||||
struct pai_map *cpump;
|
struct pai_mapptr *mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
|
||||||
int tasks = 1;
|
struct pai_map *cpump = mp->mapptr;
|
||||||
|
|
||||||
/* Check reference count and return when all gone.
|
mutex_lock(&pai_reserve_mutex);
|
||||||
* 1. An event is installed on online CPU X.
|
debug_sprintf_event(paidbg, 5, "%s event %#llx idx %d cpu %d users %d "
|
||||||
* 2. CPU x is offlined and the per-CPU data is removed.
|
"refcnt %u\n", __func__, event->attr.config, idx,
|
||||||
* 3. Event is destroyed via close system call.
|
event->cpu, cpump->active_events,
|
||||||
*/
|
refcount_read(&cpump->refcnt));
|
||||||
if (!refcount_read(&pai_root[idx].refcnt))
|
if (refcount_dec_and_test(&cpump->refcnt))
|
||||||
return; /* No events at all */
|
|
||||||
mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
|
|
||||||
if (!mp || !mp->mapptr) /* No events on that CPU */
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* When hotplug is true, invocation is from CPU hotplug callback.
|
|
||||||
* Delete per-CPU resource and adjust refcnt when per-task events
|
|
||||||
* are currently active. This can be more than one.
|
|
||||||
* In this case adjust counters.
|
|
||||||
*/
|
|
||||||
if (hotplug)
|
|
||||||
tasks = atomic_read(&pai_root[idx].tskctx);
|
|
||||||
|
|
||||||
cpump = mp->mapptr;
|
|
||||||
if (refcount_sub_and_test(tasks, &cpump->refcnt))
|
|
||||||
pai_free(mp);
|
pai_free(mp);
|
||||||
pai_root_free(idx, tasks);
|
pai_root_free(idx);
|
||||||
|
mutex_unlock(&pai_reserve_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pai_event_destroy(struct perf_event *event)
|
static void pai_event_destroy(struct perf_event *event)
|
||||||
{
|
{
|
||||||
int cpu = 0, idx = PAI_PMU_IDX(event);
|
int cpu;
|
||||||
|
|
||||||
free_page(PAI_SAVE_AREA(event));
|
free_page(PAI_SAVE_AREA(event));
|
||||||
cpus_read_lock();
|
|
||||||
mutex_lock(&pai_reserve_mutex);
|
|
||||||
if (event->cpu == -1) {
|
if (event->cpu == -1) {
|
||||||
atomic_dec(&pai_root[idx].tskctx);
|
struct cpumask *mask = PAI_CPU_MASK(event);
|
||||||
for_each_online_cpu(cpu)
|
|
||||||
pai_event_destroy_cpu(idx, cpu, false);
|
for_each_cpu(cpu, mask)
|
||||||
|
pai_event_destroy_cpu(event, cpu);
|
||||||
|
kfree(mask);
|
||||||
} else {
|
} else {
|
||||||
pai_event_destroy_cpu(idx, event->cpu, false);
|
pai_event_destroy_cpu(event, event->cpu);
|
||||||
}
|
}
|
||||||
mutex_unlock(&pai_reserve_mutex);
|
|
||||||
cpus_read_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void paicrypt_event_destroy(struct perf_event *event)
|
static void paicrypt_event_destroy(struct perf_event *event)
|
||||||
|
|
@ -250,30 +234,25 @@ static u64 paicrypt_getall(struct perf_event *event)
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called under mutex_lock */
|
/* Check concurrent access of counting and sampling for crypto events.
|
||||||
static int pai_alloc_cpu(int idx, int cpu, bool hotplug)
|
* This function is called in process context and it is save to block.
|
||||||
|
* When the event initialization functions fails, no other call back will
|
||||||
|
* be invoked.
|
||||||
|
*
|
||||||
|
* Allocate the memory for the event.
|
||||||
|
*/
|
||||||
|
static int pai_alloc_cpu(struct perf_event *event, int cpu)
|
||||||
{
|
{
|
||||||
|
int rc, idx = PAI_PMU_IDX(event);
|
||||||
struct pai_map *cpump = NULL;
|
struct pai_map *cpump = NULL;
|
||||||
bool need_paiext_cb = false;
|
bool need_paiext_cb = false;
|
||||||
struct pai_mapptr *mp;
|
struct pai_mapptr *mp;
|
||||||
int tasks = 1, rc = 0;
|
|
||||||
|
|
||||||
/* When hotplug is true, invocation is from CPU hotplug callback.
|
|
||||||
* Allocate per-CPU resource when per-task events are currently active.
|
|
||||||
* This can be more than one. In this case adjust all reference
|
|
||||||
* counters. Otherwise return, this ensures memory is only allocated
|
|
||||||
* when needed.
|
|
||||||
*/
|
|
||||||
if (hotplug) {
|
|
||||||
tasks = atomic_read(&pai_root[idx].tskctx);
|
|
||||||
if (!tasks)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
mutex_lock(&pai_reserve_mutex);
|
||||||
/* Allocate root node */
|
/* Allocate root node */
|
||||||
rc = pai_root_alloc(idx);
|
rc = pai_root_alloc(idx);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto unlock;
|
||||||
|
|
||||||
/* Allocate node for this event */
|
/* Allocate node for this event */
|
||||||
mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
|
mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
|
||||||
|
|
@ -317,45 +296,28 @@ static int pai_alloc_cpu(int idx, int cpu, bool hotplug)
|
||||||
goto undo;
|
goto undo;
|
||||||
}
|
}
|
||||||
INIT_LIST_HEAD(&cpump->syswide_list);
|
INIT_LIST_HEAD(&cpump->syswide_list);
|
||||||
refcount_set(&cpump->refcnt, tasks);
|
refcount_set(&cpump->refcnt, 1);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
refcount_add(tasks, &cpump->refcnt);
|
refcount_inc(&cpump->refcnt);
|
||||||
}
|
}
|
||||||
/* If tasks is greater than 1, we are called from CPU hotplug path
|
|
||||||
* and need to adjust the pai_root[idx].refcnt by the number of
|
|
||||||
* per-process events. Function pai_root_alloc(idx) already
|
|
||||||
* incremented by one. Adjust for the rest.
|
|
||||||
*/
|
|
||||||
if (tasks > 1)
|
|
||||||
refcount_add(tasks - 1, &pai_root[idx].refcnt);
|
|
||||||
|
|
||||||
undo:
|
undo:
|
||||||
if (rc) {
|
if (rc) {
|
||||||
/* Error in allocation of event, decrement anchor. Since
|
/* Error in allocation of event, decrement anchor. Since
|
||||||
* the event in not created, its destroy() function is never
|
* the event in not created, its destroy() function is never
|
||||||
* invoked. Adjust the reference counter for the anchor.
|
* invoked. Adjust the reference counter for the anchor.
|
||||||
* The failure happened in the case of variable
|
|
||||||
* cpump == NULL branch above. The pai_root[XXX].refcnt has
|
|
||||||
* been incremented by one. Then the per-CPU allocation
|
|
||||||
* failed, so decrement it by one, regardless of tasks.
|
|
||||||
*/
|
*/
|
||||||
pai_root_free(idx, 1);
|
pai_root_free(idx);
|
||||||
}
|
}
|
||||||
out:
|
unlock:
|
||||||
|
mutex_unlock(&pai_reserve_mutex);
|
||||||
/* If rc is non-zero, no increment of counter/sampler was done. */
|
/* If rc is non-zero, no increment of counter/sampler was done. */
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check concurrent access of counting and sampling for PAI events.
|
|
||||||
* This function is called in process context and it is safe to block.
|
|
||||||
* When the event initialization functions fails, no other call back will
|
|
||||||
* be invoked.
|
|
||||||
* Called under mutex_lock.
|
|
||||||
*/
|
|
||||||
static int pai_alloc(struct perf_event *event)
|
static int pai_alloc(struct perf_event *event)
|
||||||
{
|
{
|
||||||
int idx = PAI_PMU_IDX(event);
|
|
||||||
struct cpumask *maskptr;
|
struct cpumask *maskptr;
|
||||||
int cpu, rc = -ENOMEM;
|
int cpu, rc = -ENOMEM;
|
||||||
|
|
||||||
|
|
@ -364,20 +326,24 @@ static int pai_alloc(struct perf_event *event)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
rc = pai_alloc_cpu(idx, cpu, false);
|
rc = pai_alloc_cpu(event, cpu);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
for_each_cpu(cpu, maskptr)
|
for_each_cpu(cpu, maskptr)
|
||||||
pai_event_destroy_cpu(idx, cpu, false);
|
pai_event_destroy_cpu(event, cpu);
|
||||||
goto undo;
|
kfree(maskptr);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
cpumask_set_cpu(cpu, maskptr);
|
cpumask_set_cpu(cpu, maskptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On error all cpumask are freed and all events have been destroyed.
|
||||||
|
* Save of which CPUs data structures have been allocated for.
|
||||||
|
* Release them in pai_event_destroy call back function
|
||||||
|
* for this event.
|
||||||
|
*/
|
||||||
|
PAI_CPU_MASK(event) = maskptr;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
/* Trace per-task events for CPU hotplug. */
|
|
||||||
atomic_inc(&pai_root[idx].tskctx);
|
|
||||||
undo:
|
|
||||||
kfree(maskptr);
|
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -425,14 +391,10 @@ static int pai_event_init(struct perf_event *event, int idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cpus_read_lock();
|
|
||||||
mutex_lock(&pai_reserve_mutex);
|
|
||||||
if (event->cpu >= 0)
|
if (event->cpu >= 0)
|
||||||
rc = pai_alloc_cpu(idx, event->cpu, false);
|
rc = pai_alloc_cpu(event, event->cpu);
|
||||||
else
|
else
|
||||||
rc = pai_alloc(event);
|
rc = pai_alloc(event);
|
||||||
mutex_unlock(&pai_reserve_mutex);
|
|
||||||
cpus_read_unlock();
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
free_page(PAI_SAVE_AREA(event));
|
free_page(PAI_SAVE_AREA(event));
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -502,7 +464,6 @@ static void pai_start(struct perf_event *event, int flags,
|
||||||
cpump->event = event;
|
cpump->event = event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event->hw.state &= ~PERF_HES_STOPPED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void paicrypt_start(struct perf_event *event, int flags)
|
static void paicrypt_start(struct perf_event *event, int flags)
|
||||||
|
|
@ -549,13 +510,6 @@ static void pai_stop(struct perf_event *event, int flags)
|
||||||
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
|
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
|
||||||
struct pai_map *cpump = mp->mapptr;
|
struct pai_map *cpump = mp->mapptr;
|
||||||
|
|
||||||
/* Cope with multiple invocations:
|
|
||||||
* 1. perf_event_throttle() --> PMU->stop()
|
|
||||||
* 2. task schedules out --> PMU->stop()
|
|
||||||
* Check for event already stopped.
|
|
||||||
*/
|
|
||||||
if (event->hw.state & PERF_HES_STOPPED)
|
|
||||||
return;
|
|
||||||
if (!event->attr.sample_period) { /* Counting */
|
if (!event->attr.sample_period) { /* Counting */
|
||||||
pai_pmu[idx].pmu->read(event);
|
pai_pmu[idx].pmu->read(event);
|
||||||
} else { /* Sampling */
|
} else { /* Sampling */
|
||||||
|
|
@ -718,9 +672,9 @@ static void pai_have_samples(int idx)
|
||||||
{
|
{
|
||||||
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
|
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
|
||||||
struct pai_map *cpump = mp->mapptr;
|
struct pai_map *cpump = mp->mapptr;
|
||||||
struct perf_event *event, *e2;
|
struct perf_event *event;
|
||||||
|
|
||||||
list_for_each_entry_safe(event, e2, &cpump->syswide_list, hw.tp_list)
|
list_for_each_entry(event, &cpump->syswide_list, hw.tp_list)
|
||||||
pai_have_sample(event, cpump);
|
pai_have_sample(event, cpump);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -737,17 +691,6 @@ static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx,
|
||||||
pai_have_samples(PAI_PMU_CRYPTO);
|
pai_have_samples(PAI_PMU_CRYPTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prevent ioctl(fd, PERF_EVENT_IOC_PERIOD, ...) call.
|
|
||||||
* It sets perf_event::event_limit to a positive value and causes
|
|
||||||
* perf_event_overflow() to invoke pai_stop() call back function when
|
|
||||||
* perf_event::event_limit hits zero. This is not supported because the
|
|
||||||
* sample events CRYPTO_ALL and NNPA_ALL are always taken at schedule out
|
|
||||||
* of a task.
|
|
||||||
*/
|
|
||||||
static int pai_check_period(struct perf_event *event, u64 value)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
/* ============================= paiext ====================================*/
|
/* ============================= paiext ====================================*/
|
||||||
|
|
||||||
static void paiext_event_destroy(struct perf_event *event)
|
static void paiext_event_destroy(struct perf_event *event)
|
||||||
|
|
@ -861,7 +804,6 @@ static struct pmu paicrypt = {
|
||||||
.stop = paicrypt_stop,
|
.stop = paicrypt_stop,
|
||||||
.read = paicrypt_read,
|
.read = paicrypt_read,
|
||||||
.sched_task = paicrypt_sched_task,
|
.sched_task = paicrypt_sched_task,
|
||||||
.check_period = pai_check_period,
|
|
||||||
.attr_groups = paicrypt_attr_groups
|
.attr_groups = paicrypt_attr_groups
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1073,7 +1015,6 @@ static struct pmu paiext = {
|
||||||
.stop = paiext_stop,
|
.stop = paiext_stop,
|
||||||
.read = paiext_read,
|
.read = paiext_read,
|
||||||
.sched_task = paiext_sched_task,
|
.sched_task = paiext_sched_task,
|
||||||
.check_period = pai_check_period,
|
|
||||||
.attr_groups = paiext_attr_groups,
|
.attr_groups = paiext_attr_groups,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1277,61 +1218,23 @@ static int __init paipmu_setup(void)
|
||||||
return install_ok;
|
return install_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pai_online_cpu(unsigned int cpu)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
mutex_lock(&pai_reserve_mutex);
|
|
||||||
rc = pai_alloc_cpu(PAI_PMU_CRYPTO, cpu, true);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
rc = pai_alloc_cpu(PAI_PMU_EXT, cpu, true);
|
|
||||||
if (rc)
|
|
||||||
pai_event_destroy_cpu(PAI_PMU_CRYPTO, cpu, true);
|
|
||||||
out:
|
|
||||||
mutex_unlock(&pai_reserve_mutex);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pai_offline_cpu(unsigned int cpu)
|
|
||||||
{
|
|
||||||
mutex_lock(&pai_reserve_mutex);
|
|
||||||
pai_event_destroy_cpu(PAI_PMU_CRYPTO, cpu, true);
|
|
||||||
pai_event_destroy_cpu(PAI_PMU_EXT, cpu, true);
|
|
||||||
mutex_unlock(&pai_reserve_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init pai_init(void)
|
static int __init pai_init(void)
|
||||||
{
|
{
|
||||||
int state, rc;
|
|
||||||
|
|
||||||
/* Setup s390dbf facility */
|
/* Setup s390dbf facility */
|
||||||
paidbg = debug_register("pai", 1, 1, 128);
|
paidbg = debug_register("pai", 32, 256, 128);
|
||||||
if (!paidbg) {
|
if (!paidbg) {
|
||||||
pr_err("Registration of s390dbf pai failed\n");
|
pr_err("Registration of s390dbf pai failed\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
debug_register_view(paidbg, &debug_sprintf_view);
|
debug_register_view(paidbg, &debug_sprintf_view);
|
||||||
|
|
||||||
/* CPUHP_BP_PREPARE_DYN --> before CPU is brought online */
|
if (!paipmu_setup()) {
|
||||||
state = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "perf/pai:prepare",
|
/* No PMU registration, no need for debug buffer */
|
||||||
pai_online_cpu, pai_offline_cpu);
|
debug_unregister_view(paidbg, &debug_sprintf_view);
|
||||||
rc = state < 0 ? state : 0;
|
debug_unregister(paidbg);
|
||||||
if (rc < 0)
|
return -ENODEV;
|
||||||
goto out_debug;
|
}
|
||||||
|
|
||||||
rc = -ENODEV;
|
|
||||||
if (!paipmu_setup())
|
|
||||||
goto out_cpuhp;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_cpuhp:
|
|
||||||
cpuhp_remove_state(state);
|
|
||||||
out_debug:
|
|
||||||
debug_unregister_view(paidbg, &debug_sprintf_view);
|
|
||||||
debug_unregister(paidbg);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device_initcall(pai_init);
|
device_initcall(pai_init);
|
||||||
|
|
|
||||||
|
|
@ -659,13 +659,23 @@ int smp_cpu_get_polarization(int cpu)
|
||||||
return per_cpu(pcpu_devices, cpu).polarization;
|
return per_cpu(pcpu_devices, cpu).polarization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void smp_cpu_set_capacity(int cpu, unsigned long val)
|
||||||
|
{
|
||||||
|
per_cpu(pcpu_devices, cpu).capacity = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long smp_cpu_get_capacity(int cpu)
|
||||||
|
{
|
||||||
|
return per_cpu(pcpu_devices, cpu).capacity;
|
||||||
|
}
|
||||||
|
|
||||||
void smp_set_core_capacity(int cpu, unsigned long val)
|
void smp_set_core_capacity(int cpu, unsigned long val)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cpu = smp_get_base_cpu(cpu);
|
cpu = smp_get_base_cpu(cpu);
|
||||||
for (i = cpu; (i <= cpu + smp_cpu_mtid) && (i < nr_cpu_ids); i++)
|
for (i = cpu; (i <= cpu + smp_cpu_mtid) && (i < nr_cpu_ids); i++)
|
||||||
topology_set_cpu_scale(i, val);
|
smp_cpu_set_capacity(i, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int smp_cpu_get_cpu_address(int cpu)
|
int smp_cpu_get_cpu_address(int cpu)
|
||||||
|
|
@ -717,7 +727,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
|
||||||
else
|
else
|
||||||
pcpu->state = CPU_STATE_STANDBY;
|
pcpu->state = CPU_STATE_STANDBY;
|
||||||
smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
|
smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
|
||||||
topology_set_cpu_scale(cpu, CPU_CAPACITY_HIGH);
|
smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
|
||||||
set_cpu_present(cpu, true);
|
set_cpu_present(cpu, true);
|
||||||
if (!early && arch_register_cpu(cpu))
|
if (!early && arch_register_cpu(cpu))
|
||||||
set_cpu_present(cpu, false);
|
set_cpu_present(cpu, false);
|
||||||
|
|
@ -957,7 +967,7 @@ void __init smp_prepare_boot_cpu(void)
|
||||||
ipl_pcpu->state = CPU_STATE_CONFIGURED;
|
ipl_pcpu->state = CPU_STATE_CONFIGURED;
|
||||||
lc->pcpu = (unsigned long)ipl_pcpu;
|
lc->pcpu = (unsigned long)ipl_pcpu;
|
||||||
smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
|
smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
|
||||||
topology_set_cpu_scale(0, CPU_CAPACITY_HIGH);
|
smp_cpu_set_capacity(0, CPU_CAPACITY_HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init smp_setup_processor_id(void)
|
void __init smp_setup_processor_id(void)
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ static void add_cpus_to_mask(struct topology_core *tl_core,
|
||||||
cpumask_set_cpu(cpu, &book->mask);
|
cpumask_set_cpu(cpu, &book->mask);
|
||||||
cpumask_set_cpu(cpu, &socket->mask);
|
cpumask_set_cpu(cpu, &socket->mask);
|
||||||
smp_cpu_set_polarization(cpu, tl_core->pp);
|
smp_cpu_set_polarization(cpu, tl_core->pp);
|
||||||
topology_set_cpu_scale(cpu, CPU_CAPACITY_HIGH);
|
smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ static atomic64_t virt_timer_elapsed;
|
||||||
DEFINE_PER_CPU(u64, mt_cycles[8]);
|
DEFINE_PER_CPU(u64, mt_cycles[8]);
|
||||||
static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
|
static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
|
||||||
static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
|
static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
|
||||||
static DEFINE_PER_CPU(unsigned long, mt_scaling_jiffies);
|
static DEFINE_PER_CPU(u64, mt_scaling_jiffies);
|
||||||
|
|
||||||
static inline void set_vtimer(u64 expires)
|
static inline void set_vtimer(u64 expires)
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +81,7 @@ static void update_mt_scaling(void)
|
||||||
memcpy(cycles_old, cycles_new,
|
memcpy(cycles_old, cycles_new,
|
||||||
sizeof(u64) * (smp_cpu_mtid + 1));
|
sizeof(u64) * (smp_cpu_mtid + 1));
|
||||||
}
|
}
|
||||||
__this_cpu_write(mt_scaling_jiffies, jiffies);
|
__this_cpu_write(mt_scaling_jiffies, jiffies_64);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u64 update_tsk_timer(unsigned long *tsk_vtime, u64 new)
|
static inline u64 update_tsk_timer(unsigned long *tsk_vtime, u64 new)
|
||||||
|
|
@ -144,7 +144,7 @@ static int do_account_vtime(struct task_struct *tsk)
|
||||||
lc->system_timer += timer;
|
lc->system_timer += timer;
|
||||||
|
|
||||||
/* Update MT utilization calculation */
|
/* Update MT utilization calculation */
|
||||||
if (smp_cpu_mtid && time_after(jiffies, __this_cpu_read(mt_scaling_jiffies)))
|
if (smp_cpu_mtid && time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies)))
|
||||||
update_mt_scaling();
|
update_mt_scaling();
|
||||||
|
|
||||||
/* Calculate cputime delta */
|
/* Calculate cputime delta */
|
||||||
|
|
|
||||||
|
|
@ -2168,7 +2168,7 @@ static int kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
|
||||||
if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX)
|
if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
keys = kvmalloc_objs(*keys, args->count, GFP_KERNEL_ACCOUNT);
|
keys = kvmalloc_array(args->count, sizeof(*keys), GFP_KERNEL_ACCOUNT);
|
||||||
if (!keys)
|
if (!keys)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
@ -2205,7 +2205,7 @@ static int kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
|
||||||
if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX)
|
if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
keys = kvmalloc_objs(*keys, args->count, GFP_KERNEL_ACCOUNT);
|
keys = kvmalloc_array(args->count, sizeof(*keys), GFP_KERNEL_ACCOUNT);
|
||||||
if (!keys)
|
if (!keys)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,46 +55,63 @@ static void __crst_table_upgrade(void *arg)
|
||||||
|
|
||||||
int crst_table_upgrade(struct mm_struct *mm, unsigned long end)
|
int crst_table_upgrade(struct mm_struct *mm, unsigned long end)
|
||||||
{
|
{
|
||||||
unsigned long *table, *pgd;
|
unsigned long *pgd = NULL, *p4d = NULL, *__pgd;
|
||||||
int rc, notify;
|
unsigned long asce_limit = mm->context.asce_limit;
|
||||||
|
|
||||||
mmap_assert_write_locked(mm);
|
mmap_assert_write_locked(mm);
|
||||||
|
|
||||||
/* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */
|
/* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */
|
||||||
VM_BUG_ON(mm->context.asce_limit < _REGION2_SIZE);
|
VM_BUG_ON(asce_limit < _REGION2_SIZE);
|
||||||
rc = 0;
|
|
||||||
notify = 0;
|
if (end <= asce_limit)
|
||||||
while (mm->context.asce_limit < end) {
|
return 0;
|
||||||
table = crst_table_alloc(mm);
|
|
||||||
if (!table) {
|
if (asce_limit == _REGION2_SIZE) {
|
||||||
rc = -ENOMEM;
|
p4d = crst_table_alloc(mm);
|
||||||
break;
|
if (unlikely(!p4d))
|
||||||
}
|
goto err_p4d;
|
||||||
spin_lock_bh(&mm->page_table_lock);
|
crst_table_init(p4d, _REGION2_ENTRY_EMPTY);
|
||||||
pgd = (unsigned long *)mm->pgd;
|
pagetable_p4d_ctor(virt_to_ptdesc(p4d));
|
||||||
if (mm->context.asce_limit == _REGION2_SIZE) {
|
|
||||||
crst_table_init(table, _REGION2_ENTRY_EMPTY);
|
|
||||||
p4d_populate(mm, (p4d_t *)table, (pud_t *)pgd);
|
|
||||||
pagetable_p4d_ctor(virt_to_ptdesc(table));
|
|
||||||
mm->pgd = (pgd_t *)table;
|
|
||||||
mm->context.asce_limit = _REGION1_SIZE;
|
|
||||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
|
||||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
|
||||||
mm_inc_nr_puds(mm);
|
|
||||||
} else {
|
|
||||||
crst_table_init(table, _REGION1_ENTRY_EMPTY);
|
|
||||||
pgd_populate(mm, (pgd_t *)table, (p4d_t *)pgd);
|
|
||||||
pagetable_pgd_ctor(virt_to_ptdesc(table));
|
|
||||||
mm->pgd = (pgd_t *)table;
|
|
||||||
mm->context.asce_limit = TASK_SIZE_MAX;
|
|
||||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
|
||||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
|
|
||||||
}
|
|
||||||
notify = 1;
|
|
||||||
spin_unlock_bh(&mm->page_table_lock);
|
|
||||||
}
|
}
|
||||||
if (notify)
|
if (end > _REGION1_SIZE) {
|
||||||
on_each_cpu(__crst_table_upgrade, mm, 0);
|
pgd = crst_table_alloc(mm);
|
||||||
return rc;
|
if (unlikely(!pgd))
|
||||||
|
goto err_pgd;
|
||||||
|
crst_table_init(pgd, _REGION1_ENTRY_EMPTY);
|
||||||
|
pagetable_pgd_ctor(virt_to_ptdesc(pgd));
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_bh(&mm->page_table_lock);
|
||||||
|
|
||||||
|
if (p4d) {
|
||||||
|
__pgd = (unsigned long *) mm->pgd;
|
||||||
|
p4d_populate(mm, (p4d_t *) p4d, (pud_t *) __pgd);
|
||||||
|
mm->pgd = (pgd_t *) p4d;
|
||||||
|
mm->context.asce_limit = _REGION1_SIZE;
|
||||||
|
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||||
|
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
||||||
|
mm_inc_nr_puds(mm);
|
||||||
|
}
|
||||||
|
if (pgd) {
|
||||||
|
__pgd = (unsigned long *) mm->pgd;
|
||||||
|
pgd_populate(mm, (pgd_t *) pgd, (p4d_t *) __pgd);
|
||||||
|
mm->pgd = (pgd_t *) pgd;
|
||||||
|
mm->context.asce_limit = TASK_SIZE_MAX;
|
||||||
|
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||||
|
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_bh(&mm->page_table_lock);
|
||||||
|
|
||||||
|
on_each_cpu(__crst_table_upgrade, mm, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_pgd:
|
||||||
|
pagetable_dtor(virt_to_ptdesc(p4d));
|
||||||
|
crst_table_free(mm, p4d);
|
||||||
|
err_p4d:
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long *page_table_alloc_noprof(struct mm_struct *mm)
|
unsigned long *page_table_alloc_noprof(struct mm_struct *mm)
|
||||||
|
|
|
||||||
|
|
@ -153,9 +153,6 @@ static ssize_t report_error_write(struct file *filp, struct kobject *kobj,
|
||||||
if (off || (count < sizeof(*report)))
|
if (off || (count < sizeof(*report)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (count < (report->length + sizeof(*report)))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ret = sclp_pci_report(report, zdev->fh, zdev->fid);
|
ret = sclp_pci_report(report, zdev->fh, zdev->fid);
|
||||||
|
|
||||||
return ret ? ret : count;
|
return ret ? ret : count;
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user