mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
Linux 7.1-rc3
-----BEGIN PGP SIGNATURE----- iQFSBAABCgA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAmoA87keHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGsnAIAJENovWOPJnq6XOM GcnwSFG+xsv5kfSXU9+ZgP2WnoHJGoWCon2T69+dyVrthmMxFcPub1UM+VI0M+LP Eo894JhbAlpej4Z0f6I4L6eE9RMq2vc3UW3ga1WK6R9IYJ3WE1kEur64zJJoBvX1 SPj4oxpI/S02KxLT8F2Sq5PVS4lvaDwK/N2mTB5JNjZE24iUMYc/4nPFNFpVKhgb qfpMOk4VGjfgRexVksskm8pVO6FAWXUMQTGUUYSpzv5f2avGAyP8o+m3dHIs366+ Y/xVLADTtW7z4pu3eTw5hZLhbTekElFfLTsSPqWwqCiu0zA5s3HjRHMo3xbhHkwT 0zXS2H0= =j7EH -----END PGP SIGNATURE----- Merge tag 'v7.1-rc3' into staging-next We need the staging fixes in here to build off of. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
commit
ea09c82fbc
7
.mailmap
7
.mailmap
|
|
@ -19,6 +19,7 @@ Abhinav Kumar <quic_abhinavk@quicinc.com> <abhinavk@codeaurora.org>
|
|||
Ahmad Masri <quic_amasri@quicinc.com> <amasri@codeaurora.org>
|
||||
Adam Oldham <oldhamca@gmail.com>
|
||||
Adam Radford <aradford@gmail.com>
|
||||
Aditya Garg <gargaditya08@proton.me> <gargaditya08@live.com>
|
||||
Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com>
|
||||
Adrian Bunk <bunk@stusta.de>
|
||||
Ajay Kaher <ajay.kaher@broadcom.com> <akaher@vmware.com>
|
||||
|
|
@ -207,6 +208,7 @@ Claudiu Beznea <claudiu.beznea@tuxon.dev> <claudiu.beznea@microchip.com>
|
|||
Colin Ian King <colin.i.king@gmail.com> <colin.king@canonical.com>
|
||||
Corey Minyard <minyard@acm.org>
|
||||
Damian Hobson-Garcia <dhobsong@igel.co.jp>
|
||||
Dan Carpenter <error27@gmail.com> <dan.carpenter@linaro.org>
|
||||
Dan Carpenter <error27@gmail.com> <dan.carpenter@oracle.com>
|
||||
Dan Williams <djbw@kernel.org> <dan.j.williams@intel.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <danborkmann@googlemail.com>
|
||||
|
|
@ -495,6 +497,7 @@ Leon Romanovsky <leon@kernel.org> <leon@leon.nu>
|
|||
Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com>
|
||||
Leon Romanovsky <leon@kernel.org> <leonro@nvidia.com>
|
||||
Leo Yan <leo.yan@linux.dev> <leo.yan@linaro.org>
|
||||
Liam R. Howlett <liam@infradead.org> <Liam.Howlett@oracle.com>
|
||||
Liam Mark <quic_lmark@quicinc.com> <lmark@codeaurora.org>
|
||||
Linas Vepstas <linas@austin.ibm.com>
|
||||
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>
|
||||
|
|
@ -505,6 +508,8 @@ Linus Walleij <linusw@kernel.org> <linus.walleij@stericsson.com>
|
|||
Linus Walleij <linusw@kernel.org> <linus.walleij@linaro.org>
|
||||
Linus Walleij <linusw@kernel.org> <triad@df.lth.se>
|
||||
<linux-hardening@vger.kernel.org> <kernel-hardening@lists.openwall.com>
|
||||
Li Wang <li.wang@linux.dev> <liwang@redhat.com>
|
||||
Li Wang <li.wang@linux.dev> <wangli.ahau@gmail.com>
|
||||
Li Yang <leoyang.li@nxp.com> <leoli@freescale.com>
|
||||
Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
|
||||
Lior David <quic_liord@quicinc.com> <liord@codeaurora.org>
|
||||
|
|
@ -677,6 +682,7 @@ Peter A Jonsson <pj@ludd.ltu.se>
|
|||
Peter Hilber <peter.hilber@oss.qualcomm.com> <quic_philber@quicinc.com>
|
||||
Peter Oruba <peter.oruba@amd.com>
|
||||
Peter Oruba <peter@oruba.de>
|
||||
Peter Rosin <peda@lysator.liu.se> <peda@axentia.se>
|
||||
Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> <pierre-louis.bossart@linux.intel.com>
|
||||
Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com>
|
||||
Pratyush Yadav <pratyush@kernel.org> <ptyadav@amazon.de>
|
||||
|
|
@ -687,6 +693,7 @@ Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com>
|
|||
Puranjay Mohan <puranjay@kernel.org> <puranjay12@gmail.com>
|
||||
Qais Yousef <qyousef@layalina.io> <qais.yousef@imgtec.com>
|
||||
Qais Yousef <qyousef@layalina.io> <qais.yousef@arm.com>
|
||||
Qi Zheng <qi.zheng@linux.dev> <zhengqi.arch@bytedance.com>
|
||||
Quentin Monnet <qmo@kernel.org> <quentin.monnet@netronome.com>
|
||||
Quentin Monnet <qmo@kernel.org> <quentin@isovalent.com>
|
||||
Quentin Perret <qperret@qperret.net> <quentin.perret@arm.com>
|
||||
|
|
|
|||
|
|
@ -47,21 +47,19 @@ Please note that implementation details can be changed.
|
|||
Called when swp_entry's refcnt goes down to 0. A charge against swap
|
||||
disappears.
|
||||
|
||||
3. charge-commit-cancel
|
||||
3. charge-commit
|
||||
=======================
|
||||
|
||||
Memcg pages are charged in two steps:
|
||||
|
||||
- mem_cgroup_try_charge()
|
||||
- mem_cgroup_commit_charge() or mem_cgroup_cancel_charge()
|
||||
- commit_charge()
|
||||
|
||||
At try_charge(), there are no flags to say "this page is charged".
|
||||
at this point, usage += PAGE_SIZE.
|
||||
|
||||
At commit(), the page is associated with the memcg.
|
||||
|
||||
At cancel(), simply usage -= PAGE_SIZE.
|
||||
|
||||
Under below explanation, we assume CONFIG_SWAP=y.
|
||||
|
||||
4. Anonymous
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ cgroup v2 currently supports the following mount options.
|
|||
memory_hugetlb_accounting
|
||||
Count HugeTLB memory usage towards the cgroup's overall
|
||||
memory usage for the memory controller (for the purpose of
|
||||
statistics reporting and memory protetion). This is a new
|
||||
statistics reporting and memory protection). This is a new
|
||||
behavior that could regress existing setups, so it must be
|
||||
explicitly opted in with this mount option.
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,15 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,meson6-i2c # Meson6, Meson8 and compatible SoCs
|
||||
- amlogic,meson-gxbb-i2c # GXBB and compatible SoCs
|
||||
- amlogic,meson-axg-i2c # AXG and compatible SoCs
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,t7-i2c
|
||||
- const: amlogic,meson-axg-i2c
|
||||
- enum:
|
||||
- amlogic,meson6-i2c # Meson6, Meson8 and compatible SoCs
|
||||
- amlogic,meson-gxbb-i2c # GXBB and compatible SoCs
|
||||
- amlogic,meson-axg-i2c # AXG and compatible SoCs
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ properties:
|
|||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-i2c
|
||||
- enum:
|
||||
- apple,t6020-i2c
|
||||
- apple,t8122-i2c
|
||||
- const: apple,t8103-i2c
|
||||
- items:
|
||||
- enum:
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ properties:
|
|||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,eliza-ipcc
|
||||
- qcom,glymur-ipcc
|
||||
- qcom,kaanapali-ipcc
|
||||
- qcom,milos-ipcc
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ Mount options unique to the isofs filesystem.
|
|||
Recommended documents about ISO 9660 standard are located at:
|
||||
|
||||
- http://www.y-adagio.com/
|
||||
- ftp://ftp.ecma.ch/ecma-st/Ecma-119.pdf
|
||||
- https://ecma-international.org/wp-content/uploads/ECMA-119_2nd_edition_december_1987.pdf
|
||||
|
||||
Quoting from the PDF "This 2nd Edition of Standard ECMA-119 is technically
|
||||
identical with ISO 9660.", so it is a valid and gratis substitute of the
|
||||
|
|
|
|||
|
|
@ -135,4 +135,4 @@ References
|
|||
|
||||
4. **Lenovo IdeaPad Laptop Driver:** Reference for DMI-based hardware
|
||||
feature gating in Lenovo laptops.
|
||||
https://github.com/torvalds/linux/blob/master/drivers/platform/x86/ideapad-laptop.c
|
||||
https://github.com/torvalds/linux/blob/master/drivers/platform/x86/lenovo/ideapad-laptop.c
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ operations:
|
|||
name: dev-set
|
||||
doc: Set the configuration of a PSP device.
|
||||
attribute-set: dev
|
||||
flags: [admin-perm]
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
|
|
@ -207,6 +208,7 @@ operations:
|
|||
name: key-rotate
|
||||
doc: Rotate the device key.
|
||||
attribute-set: dev
|
||||
flags: [admin-perm]
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
|
|
|
|||
|
|
@ -24,6 +24,97 @@ Quick access to CPU number, node ID
|
|||
Allows to implement per CPU data efficiently. Documentation is in code and
|
||||
selftests. :(
|
||||
|
||||
Optimized RSEQ V2
|
||||
-----------------
|
||||
|
||||
On architectures which utilize the generic entry code and generic TIF bits
|
||||
the kernel supports runtime optimizations for RSEQ, which also enable
|
||||
enhanced features like scheduler time slice extensions.
|
||||
|
||||
To enable them a task has to register the RSEQ region with at least the
|
||||
length advertised by getauxval(AT_RSEQ_FEATURE_SIZE).
|
||||
|
||||
If existing binaries register with RSEQ_ORIG_SIZE (32 bytes), the kernel
|
||||
keeps the legacy low performance mode enabled to fulfil the expectations
|
||||
of existing users regarding the original RSEQ implementation behaviour.
|
||||
|
||||
The following table documents the ABI and behavioral guarantees of the
|
||||
legacy and the optimized V2 mode.
|
||||
|
||||
.. list-table:: RSEQ modes
|
||||
:header-rows: 1
|
||||
|
||||
* - Nr
|
||||
- What
|
||||
|
||||
- Legacy
|
||||
- Optimized V2
|
||||
|
||||
* - 1
|
||||
- The cpu_id_start, cpu_id, node_id and mm_cid fields (User mode read
|
||||
only)
|
||||
.. Legacy
|
||||
- Updated by the kernel unconditionally after each context switch and
|
||||
before signal delivery
|
||||
.. Optimized V2
|
||||
- Updated by the kernel if and only if they change, i.e. if the task
|
||||
is migrated or mm_cid changes
|
||||
|
||||
* - 2
|
||||
- The rseq_cs critical section field
|
||||
.. Legacy
|
||||
- Evaluated and handled unconditionally after each context switch and
|
||||
before signal delivery
|
||||
.. Optimized V2
|
||||
- Evaluated and handled conditionally only when user space was
|
||||
interrupted and was scheduled out or before delivering a signal in
|
||||
the interrupted context.
|
||||
|
||||
* - 3
|
||||
- Read only fields
|
||||
.. Legacy
|
||||
- No strict enforcement except in debug mode
|
||||
.. Optimized V2
|
||||
- Strict enforcement
|
||||
|
||||
* - 4
|
||||
- membarrier(...RSEQ)
|
||||
.. Legacy
|
||||
- All running threads of the process are interrupted and the ID fields
|
||||
are rewritten and eventually active critical sections are aborted
|
||||
before they return to user space. All threads which are scheduled
|
||||
out whether voluntary or not are covered by #1/#2 above.
|
||||
.. Optimized V2
|
||||
- All running threads of the process are interrupted and eventually
|
||||
active critical sections are aborted before these threads return to
|
||||
user space. The ID fields are only updated if changed as a
|
||||
consequence of the interrupt. All threads which are scheduled out
|
||||
whether voluntary or not are covered by #1/#2 above.
|
||||
|
||||
* - 5
|
||||
- Time slice extensions
|
||||
.. Legacy
|
||||
- Not supported
|
||||
.. Optimized V2
|
||||
- Supported
|
||||
|
||||
The legacy mode is obviously less performant as it does unconditional
|
||||
updates and critical section checks even if not strictly required by the
|
||||
ABI contract. That can't be changed anymore as some users depend on that
|
||||
observed behavior, which in turn enables them to violate the ABI and
|
||||
overwrite the cpu_id_start field for their own purposes. This is obviously
|
||||
discouraged as it renders RSEQ incompatible with the intended usage and
|
||||
breaks the expectation of other libraries in the same application.
|
||||
|
||||
The ABI compliant optimized v2 mode, which respects the read only fields,
|
||||
does not require unconditional updates and therefore is way more
|
||||
performant. The kernel validates the read only fields for compliance. If
|
||||
user space modifies them, the process is killed. Compliant usage allows
|
||||
multiple libraries in the same application to benefit from the RSEQ
|
||||
functionality without disturbing each other. The ABI compliant optimized v2
|
||||
mode also enables extended RSEQ features like time slice extensions.
|
||||
|
||||
|
||||
Scheduler time slice extensions
|
||||
-------------------------------
|
||||
|
||||
|
|
@ -37,7 +128,8 @@ The prerequisites for this functionality are:
|
|||
|
||||
* Enabled at boot time (default is enabled)
|
||||
|
||||
* A rseq userspace pointer has been registered for the thread
|
||||
* A rseq userspace pointer has been registered for the thread in
|
||||
optimized V2 mode
|
||||
|
||||
The thread has to enable the functionality via prctl(2)::
|
||||
|
||||
|
|
|
|||
150
MAINTAINERS
150
MAINTAINERS
|
|
@ -4299,18 +4299,16 @@ F: Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml
|
|||
F: drivers/video/backlight/aw99706.c
|
||||
|
||||
AXENTIA ARM DEVICES
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: arch/arm/boot/dts/microchip/at91-linea.dtsi
|
||||
F: arch/arm/boot/dts/microchip/at91-natte.dtsi
|
||||
F: arch/arm/boot/dts/microchip/at91-nattis-2-natte-2.dts
|
||||
F: arch/arm/boot/dts/microchip/at91-tse850-3.dts
|
||||
|
||||
AXENTIA ASOC DRIVERS
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: Documentation/devicetree/bindings/sound/axentia,*
|
||||
F: sound/soc/atmel/tse850-pcm5142.c
|
||||
|
||||
|
|
@ -6358,6 +6356,7 @@ F: include/uapi/linux/comedi.h
|
|||
COMMON CLK FRAMEWORK
|
||||
M: Michael Turquette <mturquette@baylibre.com>
|
||||
M: Stephen Boyd <sboyd@kernel.org>
|
||||
R: Brian Masney <bmasney@redhat.com>
|
||||
L: linux-clk@vger.kernel.org
|
||||
S: Maintained
|
||||
Q: http://patchwork.kernel.org/project/linux-clk/list/
|
||||
|
|
@ -7077,6 +7076,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core/debugobjec
|
|||
F: include/linux/debugobjects.h
|
||||
F: lib/debugobjects.c
|
||||
|
||||
DEC LANCE NETWORK DRIVER
|
||||
M: "Maciej W. Rozycki" <macro@orcam.me.uk>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/amd/declance.c
|
||||
|
||||
DECSTATION PLATFORM SUPPORT
|
||||
M: "Maciej W. Rozycki" <macro@orcam.me.uk>
|
||||
L: linux-mips@vger.kernel.org
|
||||
|
|
@ -7873,7 +7878,7 @@ F: drivers/gpu/drm/sun4i/sun8i*
|
|||
|
||||
DRM DRIVER FOR APPLE TOUCH BARS
|
||||
M: Aun-Ali Zaidi <admin@kodeit.net>
|
||||
M: Aditya Garg <gargaditya08@live.com>
|
||||
M: Aditya Garg <gargaditya08@proton.me>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
|
|
@ -8193,10 +8198,9 @@ F: include/uapi/drm/nouveau_drm.h
|
|||
CORE DRIVER FOR NVIDIA GPUS [RUST]
|
||||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
M: Alexandre Courbot <acourbot@nvidia.com>
|
||||
L: nouveau@lists.freedesktop.org
|
||||
L: nova-gpu@lists.linux.dev
|
||||
S: Supported
|
||||
W: https://rust-for-linux.com/nova-gpu-driver
|
||||
Q: https://patchwork.freedesktop.org/project/nouveau/
|
||||
B: https://gitlab.freedesktop.org/drm/nova/-/issues
|
||||
C: irc://irc.oftc.net/nouveau
|
||||
T: git https://gitlab.freedesktop.org/drm/rust/kernel.git drm-rust-next
|
||||
|
|
@ -8205,10 +8209,9 @@ F: drivers/gpu/nova-core/
|
|||
|
||||
DRM DRIVER FOR NVIDIA GPUS [RUST]
|
||||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
L: nouveau@lists.freedesktop.org
|
||||
L: nova-gpu@lists.linux.dev
|
||||
S: Supported
|
||||
W: https://rust-for-linux.com/nova-gpu-driver
|
||||
Q: https://patchwork.freedesktop.org/project/nouveau/
|
||||
B: https://gitlab.freedesktop.org/drm/nova/-/issues
|
||||
C: irc://irc.oftc.net/nouveau
|
||||
T: git https://gitlab.freedesktop.org/drm/rust/kernel.git drm-rust-next
|
||||
|
|
@ -12046,7 +12049,7 @@ F: Documentation/i2c/busses/i2c-nvidia-gpu.rst
|
|||
F: drivers/i2c/busses/i2c-nvidia-gpu.c
|
||||
|
||||
I2C MUXES
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/i2c/i2c-arb*
|
||||
|
|
@ -12447,7 +12450,7 @@ F: drivers/iio/industrialio-backend.c
|
|||
F: include/linux/iio/backend.h
|
||||
|
||||
IIO DIGITAL POTENTIOMETER DAC
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-bus-iio-dac-dpot-dac
|
||||
|
|
@ -12455,7 +12458,7 @@ F: Documentation/devicetree/bindings/iio/dac/dpot-dac.yaml
|
|||
F: drivers/iio/dac/dpot-dac.c
|
||||
|
||||
IIO ENVELOPE DETECTOR
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-bus-iio-adc-envelope-detector
|
||||
|
|
@ -12471,7 +12474,7 @@ F: include/linux/iio/iio-gts-helper.h
|
|||
F: drivers/iio/test/iio-test-gts.c
|
||||
|
||||
IIO MULTIPLEXER
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/multiplexer/io-channel-mux.yaml
|
||||
|
|
@ -12502,7 +12505,7 @@ F: include/linux/iio/
|
|||
F: tools/iio/
|
||||
|
||||
IIO UNIT CONVERTER
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/afe/current-sense-amplifier.yaml
|
||||
|
|
@ -13860,7 +13863,6 @@ M: Pratyush Yadav <pratyush@kernel.org>
|
|||
R: Dave Young <ruirui.yang@linux.dev>
|
||||
L: kexec@lists.infradead.org
|
||||
S: Maintained
|
||||
W: http://lse.sourceforge.net/kdump/
|
||||
F: Documentation/admin-guide/kdump/
|
||||
F: fs/proc/vmcore.c
|
||||
F: include/linux/crash_core.h
|
||||
|
|
@ -15252,7 +15254,7 @@ M: Andrea Cervesato <andrea.cervesato@suse.com>
|
|||
M: Cyril Hrubis <chrubis@suse.cz>
|
||||
M: Jan Stancek <jstancek@redhat.com>
|
||||
M: Petr Vorel <pvorel@suse.cz>
|
||||
M: Li Wang <liwang@redhat.com>
|
||||
M: Li Wang <li.wang@linux.dev>
|
||||
M: Yang Xu <xuyang2018.jy@fujitsu.com>
|
||||
M: Xiao Yang <yangx.jy@fujitsu.com>
|
||||
L: ltp@lists.linux.it (subscribers-only)
|
||||
|
|
@ -15399,7 +15401,7 @@ F: include/net/netns/mctp.h
|
|||
F: net/mctp/
|
||||
|
||||
MAPLE TREE
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Liam R. Howlett <liam@infradead.org>
|
||||
R: Alice Ryhl <aliceryhl@google.com>
|
||||
R: Andrew Ballance <andrewjballance@gmail.com>
|
||||
L: maple-tree@lists.infradead.org
|
||||
|
|
@ -15719,7 +15721,7 @@ F: Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
|
|||
F: drivers/media/i2c/max96717.c
|
||||
|
||||
MAX9860 MONO AUDIO VOICE CODEC DRIVER
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/max9860.txt
|
||||
|
|
@ -15934,7 +15936,7 @@ F: Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
|
|||
F: drivers/net/can/spi/mcp251xfd/
|
||||
|
||||
MCP4018 AND MCP4531 MICROCHIP DIGITAL POTENTIOMETER DRIVERS
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531
|
||||
|
|
@ -16759,7 +16761,7 @@ MEMORY MANAGEMENT - CORE
|
|||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Liam R. Howlett <liam@infradead.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Mike Rapoport <rppt@kernel.org>
|
||||
R: Suren Baghdasaryan <surenb@google.com>
|
||||
|
|
@ -16805,7 +16807,7 @@ F: mm/sparse.c
|
|||
F: mm/util.c
|
||||
F: mm/vmpressure.c
|
||||
F: mm/vmstat.c
|
||||
N: include/linux/page[-_]*
|
||||
N: include\/linux\/page[-_][a-zA-Z]*
|
||||
|
||||
MEMORY MANAGEMENT - EXECMEM
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
|
|
@ -16895,7 +16897,7 @@ MEMORY MANAGEMENT - MISC
|
|||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Liam R. Howlett <liam@infradead.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Mike Rapoport <rppt@kernel.org>
|
||||
R: Suren Baghdasaryan <surenb@google.com>
|
||||
|
|
@ -16962,6 +16964,7 @@ S: Maintained
|
|||
F: include/linux/compaction.h
|
||||
F: include/linux/gfp.h
|
||||
F: include/linux/page-isolation.h
|
||||
F: include/linux/pageblock-flags.h
|
||||
F: mm/compaction.c
|
||||
F: mm/debug_page_alloc.c
|
||||
F: mm/debug_page_ref.c
|
||||
|
|
@ -16983,7 +16986,7 @@ M: Andrew Morton <akpm@linux-foundation.org>
|
|||
M: Johannes Weiner <hannes@cmpxchg.org>
|
||||
R: David Hildenbrand <david@kernel.org>
|
||||
R: Michal Hocko <mhocko@kernel.org>
|
||||
R: Qi Zheng <zhengqi.arch@bytedance.com>
|
||||
R: Qi Zheng <qi.zheng@linux.dev>
|
||||
R: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
L: linux-mm@kvack.org
|
||||
|
|
@ -16996,7 +16999,7 @@ M: Andrew Morton <akpm@linux-foundation.org>
|
|||
M: David Hildenbrand <david@kernel.org>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Rik van Riel <riel@surriel.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Liam R. Howlett <liam@infradead.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Harry Yoo <harry@kernel.org>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
|
|
@ -17043,7 +17046,7 @@ M: David Hildenbrand <david@kernel.org>
|
|||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Zi Yan <ziy@nvidia.com>
|
||||
R: Baolin Wang <baolin.wang@linux.alibaba.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Liam R. Howlett <liam@infradead.org>
|
||||
R: Nico Pache <npache@redhat.com>
|
||||
R: Ryan Roberts <ryan.roberts@arm.com>
|
||||
R: Dev Jain <dev.jain@arm.com>
|
||||
|
|
@ -17081,7 +17084,7 @@ F: tools/testing/selftests/mm/uffd-*.[ch]
|
|||
MEMORY MANAGEMENT - RUST
|
||||
M: Alice Ryhl <aliceryhl@google.com>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Liam R. Howlett <liam@infradead.org>
|
||||
L: linux-mm@kvack.org
|
||||
L: rust-for-linux@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -17095,7 +17098,7 @@ F: rust/kernel/page.rs
|
|||
|
||||
MEMORY MAPPING
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Liam R. Howlett <liam@infradead.org>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
|
|
@ -17127,7 +17130,7 @@ F: tools/testing/vma/
|
|||
MEMORY MAPPING - LOCKING
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Suren Baghdasaryan <surenb@google.com>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Liam R. Howlett <liam@infradead.org>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
|
|
@ -17142,7 +17145,7 @@ F: mm/mmap_lock.c
|
|||
|
||||
MEMORY MAPPING - MADVISE (MEMORY ADVICE)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Liam R. Howlett <liam@infradead.org>
|
||||
M: Lorenzo Stoakes <ljs@kernel.org>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
|
|
@ -18238,7 +18241,7 @@ F: include/linux/mmc/
|
|||
F: include/uapi/linux/mmc/
|
||||
|
||||
MULTIPLEXER SUBSYSTEM
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
S: Odd Fixes
|
||||
F: Documentation/ABI/testing/sysfs-class-mux*
|
||||
F: Documentation/devicetree/bindings/mux/
|
||||
|
|
@ -18672,19 +18675,59 @@ F: net/xfrm/
|
|||
F: tools/testing/selftests/net/ipsec.c
|
||||
|
||||
NETWORKING [IPv4/IPv6]
|
||||
M: "David S. Miller" <davem@davemloft.net>
|
||||
M: David Ahern <dsahern@kernel.org>
|
||||
M: Ido Schimmel <idosch@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||
F: arch/x86/net/*
|
||||
F: include/linux/ip.h
|
||||
F: include/linux/ipv6*
|
||||
F: Documentation/netlink/specs/rt-addr.yaml
|
||||
F: Documentation/netlink/specs/rt-neigh.yaml
|
||||
F: Documentation/netlink/specs/rt-route.yaml
|
||||
F: Documentation/netlink/specs/rt-rule.yaml
|
||||
F: include/linux/inetdevice.h
|
||||
F: include/linux/mroute*
|
||||
F: include/net/addrconf.h
|
||||
F: include/net/arp.h
|
||||
F: include/net/fib*
|
||||
F: include/net/if_inet6.h
|
||||
F: include/net/inetpeer.h
|
||||
F: include/net/ip*
|
||||
F: include/net/lwtunnel.h
|
||||
F: include/net/ndisc.h
|
||||
F: include/net/netns/nexthop.h
|
||||
F: include/net/nexthop.h
|
||||
F: include/net/route.h
|
||||
F: net/ipv4/
|
||||
F: net/ipv6/
|
||||
F: include/uapi/linux/fib_rules.h
|
||||
F: include/uapi/linux/in_route.h
|
||||
F: include/uapi/linux/mroute*
|
||||
F: include/uapi/linux/nexthop.h
|
||||
F: net/core/fib*
|
||||
F: net/core/lwtunnel.c
|
||||
F: net/ipv4/arp.c
|
||||
F: net/ipv4/devinet.c
|
||||
F: net/ipv4/fib*
|
||||
F: net/ipv4/icmp.c
|
||||
F: net/ipv4/igmp.c
|
||||
F: net/ipv4/inet_fragment.c
|
||||
F: net/ipv4/inetpeer.c
|
||||
F: net/ipv4/ip*
|
||||
F: net/ipv4/metrics.c
|
||||
F: net/ipv4/netlink.c
|
||||
F: net/ipv4/nexthop.c
|
||||
F: net/ipv4/route.c
|
||||
F: net/ipv6/addr*
|
||||
F: net/ipv6/anycast.c
|
||||
F: net/ipv6/exthdrs.c
|
||||
F: net/ipv6/exthdrs_core.c
|
||||
F: net/ipv6/fib*
|
||||
F: net/ipv6/icmp.c
|
||||
F: net/ipv6/ip*
|
||||
F: net/ipv6/mcast*
|
||||
F: net/ipv6/ndisc.c
|
||||
F: net/ipv6/output_core.c
|
||||
F: net/ipv6/reassembly.c
|
||||
F: net/ipv6/route.c
|
||||
F: tools/testing/selftests/net/fib*
|
||||
F: tools/testing/selftests/net/forwarding/
|
||||
|
||||
NETWORKING [LABELED] (NetLabel, Labeled IPsec, SECMARK)
|
||||
M: Paul Moore <paul@paul-moore.com>
|
||||
|
|
@ -18819,18 +18862,11 @@ F: Documentation/networking/net_failover.rst
|
|||
F: drivers/net/net_failover.c
|
||||
F: include/net/net_failover.h
|
||||
|
||||
NEXTHOP
|
||||
M: David Ahern <dsahern@kernel.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: include/net/netns/nexthop.h
|
||||
F: include/net/nexthop.h
|
||||
F: include/uapi/linux/nexthop.h
|
||||
F: net/ipv4/nexthop.c
|
||||
|
||||
NFC SUBSYSTEM
|
||||
L: netdev@vger.kernel.org
|
||||
S: Orphan
|
||||
M: David Heidelberg <david+nfc@ixit.cz>
|
||||
L: oe-linux-nfc@lists.linux.dev
|
||||
S: Maintained
|
||||
T: git https://codeberg.org/linux-nfc/linux.git
|
||||
F: Documentation/devicetree/bindings/net/nfc/
|
||||
F: drivers/nfc/
|
||||
F: include/net/nfc/
|
||||
|
|
@ -19314,7 +19350,7 @@ F: include/dt-bindings/display/tda998x.h
|
|||
K: "nxp,tda998x"
|
||||
|
||||
NXP TFA9879 DRIVER
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
M: Peter Rosin <peda@lysator.liu.se>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/trivial-codec.yaml
|
||||
|
|
@ -20315,13 +20351,14 @@ F: Documentation/devicetree/bindings/pci/marvell,armada8k-pcie.yaml
|
|||
F: drivers/pci/controller/dwc/pcie-armada8k.c
|
||||
|
||||
PCI DRIVER FOR CADENCE PCIE IP
|
||||
R: Aksh Garg <a-garg7@ti.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Orphan
|
||||
F: Documentation/devicetree/bindings/pci/cdns,*
|
||||
F: drivers/pci/controller/cadence/*cadence*
|
||||
F: drivers/pci/controller/cadence/
|
||||
|
||||
PCI DRIVER FOR CIX Sky1
|
||||
M: Hans Zhang <hans.zhang@cixtech.com>
|
||||
M: Hans Zhang <18255117159@163.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/cix,sky1-pcie-*.yaml
|
||||
|
|
@ -20433,7 +20470,7 @@ F: drivers/pci/controller/plda/pcie-plda-host.c
|
|||
F: drivers/pci/controller/plda/pcie-plda.h
|
||||
|
||||
PCI DRIVER FOR RENESAS R-CAR
|
||||
M: Marek Vasut <marek.vasut+renesas@gmail.com>
|
||||
M: Marek Vasut <marek.vasut+renesas@mailbox.org>
|
||||
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
|
|
@ -20774,6 +20811,7 @@ M: Dominik Brodowski <linux@dominikbrodowski.net>
|
|||
S: Odd Fixes
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux.git
|
||||
F: Documentation/pcmcia/
|
||||
F: drivers/net/ethernet/8390/pcnet_cs.c
|
||||
F: drivers/pcmcia/
|
||||
F: include/pcmcia/
|
||||
F: tools/pcmcia/
|
||||
|
|
@ -23369,7 +23407,7 @@ RUST [ALLOC]
|
|||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
R: Lorenzo Stoakes <ljs@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Liam R. Howlett <liam@infradead.org>
|
||||
R: Uladzislau Rezki <urezki@gmail.com>
|
||||
L: rust-for-linux@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -23521,7 +23559,7 @@ F: drivers/s390/net/
|
|||
|
||||
S390 PCI SUBSYSTEM
|
||||
M: Niklas Schnelle <schnelle@linux.ibm.com>
|
||||
M: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
|
||||
M: Gerd Bayer <gbayer@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/arch/s390/pci.rst
|
||||
|
|
@ -24314,7 +24352,7 @@ F: include/media/i2c/rj54n1cb0c.h
|
|||
SHRINKER
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Dave Chinner <david@fromorbit.com>
|
||||
R: Qi Zheng <zhengqi.arch@bytedance.com>
|
||||
R: Qi Zheng <qi.zheng@linux.dev>
|
||||
R: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
R: Muchun Song <muchun.song@linux.dev>
|
||||
L: linux-mm@kvack.org
|
||||
|
|
@ -24616,6 +24654,7 @@ S: Maintained
|
|||
F: fs/smb/client/smbdirect.*
|
||||
F: fs/smb/smbdirect/
|
||||
F: fs/smb/server/transport_rdma.*
|
||||
F: include/linux/smbdirect.h
|
||||
|
||||
SMC91x ETHERNET DRIVER
|
||||
M: Nicolas Pitre <nico@fluxnic.net>
|
||||
|
|
@ -24764,6 +24803,7 @@ SOFTWARE RAID (Multiple Disks) SUPPORT
|
|||
M: Song Liu <song@kernel.org>
|
||||
M: Yu Kuai <yukuai@fnnas.com>
|
||||
R: Li Nan <linan122@huawei.com>
|
||||
R: Xiao Ni <xiao@kernel.org>
|
||||
L: linux-raid@vger.kernel.org
|
||||
S: Supported
|
||||
Q: https://patchwork.kernel.org/project/linux-raid/list/
|
||||
|
|
|
|||
4
Makefile
4
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
VERSION = 7
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
@ -486,6 +486,8 @@ export rust_common_flags := --edition=2021 \
|
|||
-Wclippy::as_ptr_cast_mut \
|
||||
-Wclippy::as_underscore \
|
||||
-Wclippy::cast_lossless \
|
||||
-Aclippy::collapsible_if \
|
||||
-Aclippy::collapsible_match \
|
||||
-Wclippy::ignored_unit_patterns \
|
||||
-Aclippy::incompatible_msrv \
|
||||
-Wclippy::mut_mut \
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ static __always_inline void __pmr_local_irq_enable(void)
|
|||
barrier();
|
||||
}
|
||||
|
||||
static inline void arch_local_irq_enable(void)
|
||||
static __always_inline void arch_local_irq_enable(void)
|
||||
{
|
||||
if (system_uses_irq_prio_masking()) {
|
||||
__pmr_local_irq_enable();
|
||||
|
|
@ -68,7 +68,7 @@ static __always_inline void __pmr_local_irq_disable(void)
|
|||
barrier();
|
||||
}
|
||||
|
||||
static inline void arch_local_irq_disable(void)
|
||||
static __always_inline void arch_local_irq_disable(void)
|
||||
{
|
||||
if (system_uses_irq_prio_masking()) {
|
||||
__pmr_local_irq_disable();
|
||||
|
|
@ -90,7 +90,7 @@ static __always_inline unsigned long __pmr_local_save_flags(void)
|
|||
/*
|
||||
* Save the current interrupt enable state.
|
||||
*/
|
||||
static inline unsigned long arch_local_save_flags(void)
|
||||
static __always_inline unsigned long arch_local_save_flags(void)
|
||||
{
|
||||
if (system_uses_irq_prio_masking()) {
|
||||
return __pmr_local_save_flags();
|
||||
|
|
@ -109,7 +109,7 @@ static __always_inline bool __pmr_irqs_disabled_flags(unsigned long flags)
|
|||
return flags != GIC_PRIO_IRQON;
|
||||
}
|
||||
|
||||
static inline bool arch_irqs_disabled_flags(unsigned long flags)
|
||||
static __always_inline bool arch_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
if (system_uses_irq_prio_masking()) {
|
||||
return __pmr_irqs_disabled_flags(flags);
|
||||
|
|
@ -128,7 +128,7 @@ static __always_inline bool __pmr_irqs_disabled(void)
|
|||
return __pmr_irqs_disabled_flags(__pmr_local_save_flags());
|
||||
}
|
||||
|
||||
static inline bool arch_irqs_disabled(void)
|
||||
static __always_inline bool arch_irqs_disabled(void)
|
||||
{
|
||||
if (system_uses_irq_prio_masking()) {
|
||||
return __pmr_irqs_disabled();
|
||||
|
|
@ -160,7 +160,7 @@ static __always_inline unsigned long __pmr_local_irq_save(void)
|
|||
return flags;
|
||||
}
|
||||
|
||||
static inline unsigned long arch_local_irq_save(void)
|
||||
static __always_inline unsigned long arch_local_irq_save(void)
|
||||
{
|
||||
if (system_uses_irq_prio_masking()) {
|
||||
return __pmr_local_irq_save();
|
||||
|
|
@ -187,7 +187,7 @@ static __always_inline void __pmr_local_irq_restore(unsigned long flags)
|
|||
/*
|
||||
* restore saved IRQ state
|
||||
*/
|
||||
static inline void arch_local_irq_restore(unsigned long flags)
|
||||
static __always_inline void arch_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
if (system_uses_irq_prio_masking()) {
|
||||
__pmr_local_irq_restore(flags);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,12 @@
|
|||
#define KERNEL_SEGMENT_COUNT 5
|
||||
|
||||
#if SWAPPER_BLOCK_SIZE > SEGMENT_ALIGN
|
||||
#define EARLY_SEGMENT_EXTRA_PAGES (KERNEL_SEGMENT_COUNT + 1)
|
||||
/*
|
||||
* KERNEL_SEGMENT_COUNT counts the permanent kernel VMAs. The early mapping
|
||||
* has one additional split, [_text, _stext). Reserve one more page for the
|
||||
* SWAPPER_BLOCK_SIZE-unaligned boundaries.
|
||||
*/
|
||||
#define EARLY_SEGMENT_EXTRA_PAGES (KERNEL_SEGMENT_COUNT + 2)
|
||||
/*
|
||||
* The initial ID map consists of the kernel image, mapped as two separate
|
||||
* segments, and may appear misaligned wrt the swapper block size. This means
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@
|
|||
|
||||
#include <linux/mm.h>
|
||||
|
||||
#define MARKER(m) \
|
||||
m, __after_##m = m - 1
|
||||
|
||||
enum __kvm_host_smccc_func {
|
||||
/* Hypercalls that are unavailable once pKVM has finalised. */
|
||||
/* __KVM_HOST_SMCCC_FUNC___kvm_hyp_init */
|
||||
|
|
@ -59,8 +62,10 @@ enum __kvm_host_smccc_func {
|
|||
__KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v3_init_lrs,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v3_get_gic_config,
|
||||
|
||||
MARKER(__KVM_HOST_SMCCC_FUNC_MIN_PKVM),
|
||||
|
||||
__KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize,
|
||||
__KVM_HOST_SMCCC_FUNC_MIN_PKVM = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize,
|
||||
|
||||
/* Hypercalls that are always available and common to [nh]VHE/pKVM. */
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
|
||||
|
|
@ -72,11 +77,20 @@ enum __kvm_host_smccc_func {
|
|||
__KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_range,
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context,
|
||||
__KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_load,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_unload,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_enable,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_swap_reader,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_update_clock,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_reset,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_enable_event,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_write_event,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v5_save_apr,
|
||||
__KVM_HOST_SMCCC_FUNC___vgic_v5_restore_vmcr_apr,
|
||||
__KVM_HOST_SMCCC_FUNC_MAX_NO_PKVM = __KVM_HOST_SMCCC_FUNC___vgic_v5_restore_vmcr_apr,
|
||||
|
||||
MARKER(__KVM_HOST_SMCCC_FUNC_PKVM_ONLY),
|
||||
|
||||
/* Hypercalls that are available only when pKVM has finalised. */
|
||||
__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
|
||||
|
|
@ -100,14 +114,8 @@ enum __kvm_host_smccc_func {
|
|||
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
|
||||
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
|
||||
__KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_load,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_unload,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_enable,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_swap_reader,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_update_clock,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_reset,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_enable_event,
|
||||
__KVM_HOST_SMCCC_FUNC___tracing_write_event,
|
||||
|
||||
MARKER(__KVM_HOST_SMCCC_FUNC_MAX)
|
||||
};
|
||||
|
||||
#define DECLARE_KVM_VHE_SYM(sym) extern char sym[]
|
||||
|
|
|
|||
|
|
@ -450,9 +450,6 @@ struct kvm_vcpu_fault_info {
|
|||
r = __VNCR_START__ + ((VNCR_ ## r) / 8), \
|
||||
__after_##r = __MAX__(__before_##r - 1, r)
|
||||
|
||||
#define MARKER(m) \
|
||||
m, __after_##m = m - 1
|
||||
|
||||
enum vcpu_sysreg {
|
||||
__INVALID_SYSREG__, /* 0 is reserved as an invalid value */
|
||||
MPIDR_EL1, /* MultiProcessor Affinity Register */
|
||||
|
|
@ -1548,7 +1545,7 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature)
|
|||
#define kvm_vcpu_has_feature(k, f) __vcpu_has_feature(&(k)->arch, (f))
|
||||
#define vcpu_has_feature(v, f) __vcpu_has_feature(&(v)->kvm->arch, (f))
|
||||
|
||||
#define kvm_vcpu_initialized(v) vcpu_get_flag(vcpu, VCPU_INITIALIZED)
|
||||
#define kvm_vcpu_initialized(v) vcpu_get_flag(v, VCPU_INITIALIZED)
|
||||
|
||||
int kvm_trng_call(struct kvm_vcpu *vcpu);
|
||||
#ifdef CONFIG_KVM
|
||||
|
|
|
|||
|
|
@ -196,9 +196,9 @@ static int scs_handle_fde_frame(const struct eh_frame *frame,
|
|||
loc += *opcode++ * code_alignment_factor;
|
||||
loc += (*opcode++ << 8) * code_alignment_factor;
|
||||
loc += (*opcode++ << 16) * code_alignment_factor;
|
||||
loc += (*opcode++ << 24) * code_alignment_factor;
|
||||
loc += ((u64)*opcode++ << 24) * code_alignment_factor;
|
||||
size -= 4;
|
||||
break;
|
||||
break;
|
||||
|
||||
case DW_CFA_def_cfa:
|
||||
case DW_CFA_offset_extended:
|
||||
|
|
|
|||
|
|
@ -983,8 +983,8 @@ static int sve_set_common(struct task_struct *target,
|
|||
}
|
||||
|
||||
/* Always zero V regs, FPSR, and FPCR */
|
||||
memset(¤t->thread.uw.fpsimd_state, 0,
|
||||
sizeof(current->thread.uw.fpsimd_state));
|
||||
memset(&target->thread.uw.fpsimd_state, 0,
|
||||
sizeof(target->thread.uw.fpsimd_state));
|
||||
|
||||
/* Registers: FPSIMD-only case */
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ struct rt_sigframe_user_layout {
|
|||
unsigned long end_offset;
|
||||
};
|
||||
|
||||
#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16)
|
||||
#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16)
|
||||
|
||||
/*
|
||||
* Holds any EL0-controlled state that influences unprivileged memory accesses.
|
||||
* This includes both accesses done in userspace and uaccess done in the kernel.
|
||||
|
|
@ -74,13 +77,35 @@ struct rt_sigframe_user_layout {
|
|||
* This state needs to be carefully managed to ensure that it doesn't cause
|
||||
* uaccess to fail when setting up the signal frame, and the signal handler
|
||||
* itself also expects a well-defined state when entered.
|
||||
*
|
||||
* The struct should be zero-initialised. Its members should only be accessed
|
||||
* via the accessors below. __valid_fields tracks which of the fields are valid
|
||||
* (have been set to some value).
|
||||
*/
|
||||
struct user_access_state {
|
||||
u64 por_el0;
|
||||
unsigned int __valid_fields;
|
||||
u64 __por_el0;
|
||||
};
|
||||
|
||||
#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16)
|
||||
#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16)
|
||||
#define UA_STATE_HAS_POR_EL0 BIT(0)
|
||||
|
||||
static void set_ua_state_por_el0(struct user_access_state *ua_state,
|
||||
u64 por_el0)
|
||||
{
|
||||
ua_state->__por_el0 = por_el0;
|
||||
ua_state->__valid_fields |= UA_STATE_HAS_POR_EL0;
|
||||
}
|
||||
|
||||
static int get_ua_state_por_el0(const struct user_access_state *ua_state,
|
||||
u64 *por_el0)
|
||||
{
|
||||
if (ua_state->__valid_fields & UA_STATE_HAS_POR_EL0) {
|
||||
*por_el0 = ua_state->__por_el0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the user access state into ua_state and reset it to disable any
|
||||
|
|
@ -94,7 +119,7 @@ static void save_reset_user_access_state(struct user_access_state *ua_state)
|
|||
for (int pkey = 0; pkey < arch_max_pkey(); pkey++)
|
||||
por_enable_all |= POR_ELx_PERM_PREP(pkey, POE_RWX);
|
||||
|
||||
ua_state->por_el0 = read_sysreg_s(SYS_POR_EL0);
|
||||
set_ua_state_por_el0(ua_state, read_sysreg_s(SYS_POR_EL0));
|
||||
write_sysreg_s(por_enable_all, SYS_POR_EL0);
|
||||
/*
|
||||
* No ISB required as we can tolerate spurious Overlay faults -
|
||||
|
|
@ -122,8 +147,10 @@ static void set_handler_user_access_state(void)
|
|||
*/
|
||||
static void restore_user_access_state(const struct user_access_state *ua_state)
|
||||
{
|
||||
if (system_supports_poe())
|
||||
write_sysreg_s(ua_state->por_el0, SYS_POR_EL0);
|
||||
u64 por_el0;
|
||||
|
||||
if (get_ua_state_por_el0(ua_state, &por_el0) == 0)
|
||||
write_sysreg_s(por_el0, SYS_POR_EL0);
|
||||
}
|
||||
|
||||
static void init_user_layout(struct rt_sigframe_user_layout *user)
|
||||
|
|
@ -333,11 +360,16 @@ static int restore_fpmr_context(struct user_ctxs *user)
|
|||
static int preserve_poe_context(struct poe_context __user *ctx,
|
||||
const struct user_access_state *ua_state)
|
||||
{
|
||||
int err = 0;
|
||||
int err;
|
||||
u64 por_el0;
|
||||
|
||||
err = get_ua_state_por_el0(ua_state, &por_el0);
|
||||
if (WARN_ON_ONCE(err))
|
||||
return err;
|
||||
|
||||
__put_user_error(POE_MAGIC, &ctx->head.magic, err);
|
||||
__put_user_error(sizeof(*ctx), &ctx->head.size, err);
|
||||
__put_user_error(ua_state->por_el0, &ctx->por_el0, err);
|
||||
__put_user_error(por_el0, &ctx->por_el0, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -353,7 +385,7 @@ static int restore_poe_context(struct user_ctxs *user,
|
|||
|
||||
__get_user_error(por_el0, &(user->poe->por_el0), err);
|
||||
if (!err)
|
||||
ua_state->por_el0 = por_el0;
|
||||
set_ua_state_por_el0(ua_state, por_el0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1095,7 +1127,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
|
|||
{
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
struct rt_sigframe __user *frame;
|
||||
struct user_access_state ua_state;
|
||||
struct user_access_state ua_state = {};
|
||||
|
||||
/* Always make any pending restarted system calls return -EINTR */
|
||||
current->restart_block.fn = do_no_restart_syscall;
|
||||
|
|
@ -1507,7 +1539,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
|
|||
{
|
||||
struct rt_sigframe_user_layout user;
|
||||
struct rt_sigframe __user *frame;
|
||||
struct user_access_state ua_state;
|
||||
struct user_access_state ua_state = {};
|
||||
int err = 0;
|
||||
|
||||
fpsimd_save_and_flush_current_state();
|
||||
|
|
|
|||
|
|
@ -824,6 +824,10 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
|
|||
{
|
||||
bool irq_lines = *vcpu_hcr(v) & (HCR_VI | HCR_VF | HCR_VSE);
|
||||
|
||||
irq_lines |= (!irqchip_in_kernel(v->kvm) &&
|
||||
(kvm_timer_should_notify_user(v) ||
|
||||
kvm_pmu_should_notify_user(v)));
|
||||
|
||||
return ((irq_lines || kvm_vgic_vcpu_pending_irq(v))
|
||||
&& !kvm_arm_vcpu_stopped(v) && !v->arch.pause);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,6 @@ struct reg_feat_map_desc {
|
|||
}
|
||||
|
||||
#define FEAT_SPE ID_AA64DFR0_EL1, PMSVer, IMP
|
||||
#define FEAT_SPE_FnE ID_AA64DFR0_EL1, PMSVer, V1P2
|
||||
#define FEAT_BRBE ID_AA64DFR0_EL1, BRBE, IMP
|
||||
#define FEAT_TRC_SR ID_AA64DFR0_EL1, TraceVer, IMP
|
||||
#define FEAT_PMUv3 ID_AA64DFR0_EL1, PMUVer, IMP
|
||||
|
|
@ -192,7 +191,7 @@ struct reg_feat_map_desc {
|
|||
#define FEAT_SRMASK ID_AA64MMFR4_EL1, SRMASK, IMP
|
||||
#define FEAT_PoPS ID_AA64MMFR4_EL1, PoPS, IMP
|
||||
#define FEAT_PFAR ID_AA64PFR1_EL1, PFAR, IMP
|
||||
#define FEAT_Debugv8p9 ID_AA64DFR0_EL1, PMUVer, V3P9
|
||||
#define FEAT_Debugv8p9 ID_AA64DFR0_EL1, DebugVer, V8P9
|
||||
#define FEAT_PMUv3_SS ID_AA64DFR0_EL1, PMSS, IMP
|
||||
#define FEAT_SEBEP ID_AA64DFR0_EL1, SEBEP, IMP
|
||||
#define FEAT_EBEP ID_AA64DFR1_EL1, EBEP, IMP
|
||||
|
|
@ -283,7 +282,7 @@ static bool feat_anerr(struct kvm *kvm)
|
|||
static bool feat_sme_smps(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* Revists this if KVM ever supports SME -- this really should
|
||||
* Revisit this if KVM ever supports SME -- this really should
|
||||
* look at the guest's view of SMIDR_EL1. Funnily enough, this
|
||||
* is not captured in the JSON file, but only as a note in the
|
||||
* ARM ARM.
|
||||
|
|
@ -295,17 +294,27 @@ static bool feat_sme_smps(struct kvm *kvm)
|
|||
static bool feat_spe_fds(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* Revists this if KVM ever supports SPE -- this really should
|
||||
* Revisit this if KVM ever supports SPE -- this really should
|
||||
* look at the guest's view of PMSIDR_EL1.
|
||||
*/
|
||||
return (kvm_has_feat(kvm, FEAT_SPEv1p4) &&
|
||||
(read_sysreg_s(SYS_PMSIDR_EL1) & PMSIDR_EL1_FDS));
|
||||
}
|
||||
|
||||
static bool feat_spe_fne(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* Revisit this if KVM ever supports SPE -- this really should
|
||||
* look at the guest's view of PMSIDR_EL1.
|
||||
*/
|
||||
return (kvm_has_feat(kvm, FEAT_SPEv1p2) &&
|
||||
(read_sysreg_s(SYS_PMSIDR_EL1) & PMSIDR_EL1_FnE));
|
||||
}
|
||||
|
||||
static bool feat_trbe_mpam(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* Revists this if KVM ever supports both MPAM and TRBE --
|
||||
* Revisit this if KVM ever supports both MPAM and TRBE --
|
||||
* this really should look at the guest's view of TRBIDR_EL1.
|
||||
*/
|
||||
return (kvm_has_feat(kvm, FEAT_TRBE) &&
|
||||
|
|
@ -537,7 +546,7 @@ static const struct reg_bits_to_feat_map hdfgrtr_feat_map[] = {
|
|||
HDFGRTR_EL2_PMBPTR_EL1 |
|
||||
HDFGRTR_EL2_PMBLIMITR_EL1,
|
||||
FEAT_SPE),
|
||||
NEEDS_FEAT(HDFGRTR_EL2_nPMSNEVFR_EL1, FEAT_SPE_FnE),
|
||||
NEEDS_FEAT(HDFGRTR_EL2_nPMSNEVFR_EL1, feat_spe_fne),
|
||||
NEEDS_FEAT(HDFGRTR_EL2_nBRBDATA |
|
||||
HDFGRTR_EL2_nBRBCTL |
|
||||
HDFGRTR_EL2_nBRBIDR,
|
||||
|
|
@ -605,7 +614,7 @@ static const struct reg_bits_to_feat_map hdfgwtr_feat_map[] = {
|
|||
HDFGWTR_EL2_PMBPTR_EL1 |
|
||||
HDFGWTR_EL2_PMBLIMITR_EL1,
|
||||
FEAT_SPE),
|
||||
NEEDS_FEAT(HDFGWTR_EL2_nPMSNEVFR_EL1, FEAT_SPE_FnE),
|
||||
NEEDS_FEAT(HDFGWTR_EL2_nPMSNEVFR_EL1, feat_spe_fne),
|
||||
NEEDS_FEAT(HDFGWTR_EL2_nBRBDATA |
|
||||
HDFGWTR_EL2_nBRBCTL,
|
||||
FEAT_BRBE),
|
||||
|
|
|
|||
|
|
@ -709,6 +709,14 @@ static const hcall_t host_hcall[] = {
|
|||
HANDLE_FUNC(__kvm_tlb_flush_vmid_range),
|
||||
HANDLE_FUNC(__kvm_flush_cpu_context),
|
||||
HANDLE_FUNC(__kvm_timer_set_cntvoff),
|
||||
HANDLE_FUNC(__tracing_load),
|
||||
HANDLE_FUNC(__tracing_unload),
|
||||
HANDLE_FUNC(__tracing_enable),
|
||||
HANDLE_FUNC(__tracing_swap_reader),
|
||||
HANDLE_FUNC(__tracing_update_clock),
|
||||
HANDLE_FUNC(__tracing_reset),
|
||||
HANDLE_FUNC(__tracing_enable_event),
|
||||
HANDLE_FUNC(__tracing_write_event),
|
||||
HANDLE_FUNC(__vgic_v3_save_aprs),
|
||||
HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
|
||||
HANDLE_FUNC(__vgic_v5_save_apr),
|
||||
|
|
@ -735,22 +743,16 @@ static const hcall_t host_hcall[] = {
|
|||
HANDLE_FUNC(__pkvm_vcpu_load),
|
||||
HANDLE_FUNC(__pkvm_vcpu_put),
|
||||
HANDLE_FUNC(__pkvm_tlb_flush_vmid),
|
||||
HANDLE_FUNC(__tracing_load),
|
||||
HANDLE_FUNC(__tracing_unload),
|
||||
HANDLE_FUNC(__tracing_enable),
|
||||
HANDLE_FUNC(__tracing_swap_reader),
|
||||
HANDLE_FUNC(__tracing_update_clock),
|
||||
HANDLE_FUNC(__tracing_reset),
|
||||
HANDLE_FUNC(__tracing_enable_event),
|
||||
HANDLE_FUNC(__tracing_write_event),
|
||||
};
|
||||
|
||||
static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
DECLARE_REG(unsigned long, id, host_ctxt, 0);
|
||||
unsigned long hcall_min = 0, hcall_max = -1;
|
||||
unsigned long hcall_min = 0, hcall_max = __KVM_HOST_SMCCC_FUNC_MAX;
|
||||
hcall_t hfn;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(host_hcall) != __KVM_HOST_SMCCC_FUNC_MAX);
|
||||
|
||||
/*
|
||||
* If pKVM has been initialised then reject any calls to the
|
||||
* early "privileged" hypercalls. Note that we cannot reject
|
||||
|
|
@ -763,16 +765,14 @@ static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
|
|||
if (static_branch_unlikely(&kvm_protected_mode_initialized)) {
|
||||
hcall_min = __KVM_HOST_SMCCC_FUNC_MIN_PKVM;
|
||||
} else {
|
||||
hcall_max = __KVM_HOST_SMCCC_FUNC_MAX_NO_PKVM;
|
||||
hcall_max = __KVM_HOST_SMCCC_FUNC_PKVM_ONLY;
|
||||
}
|
||||
|
||||
id &= ~ARM_SMCCC_CALL_HINTS;
|
||||
id -= KVM_HOST_SMCCC_ID(0);
|
||||
|
||||
if (unlikely(id < hcall_min || id > hcall_max ||
|
||||
id >= ARRAY_SIZE(host_hcall))) {
|
||||
if (unlikely(id < hcall_min || id >= hcall_max))
|
||||
goto inval;
|
||||
}
|
||||
|
||||
hfn = host_hcall[id];
|
||||
if (unlikely(!hfn))
|
||||
|
|
@ -805,6 +805,10 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
|
|||
}
|
||||
|
||||
func_id &= ~ARM_SMCCC_CALL_HINTS;
|
||||
if (upper_32_bits(func_id)) {
|
||||
cpu_reg(host_ctxt, 0) = SMCCC_RET_NOT_SUPPORTED;
|
||||
goto exit_skip_instr;
|
||||
}
|
||||
|
||||
handled = kvm_host_psci_handler(host_ctxt, func_id);
|
||||
if (!handled)
|
||||
|
|
|
|||
|
|
@ -266,7 +266,8 @@ struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
|
|||
if (hyp_vm->kvm.created_vcpus <= vcpu_idx)
|
||||
goto unlock;
|
||||
|
||||
hyp_vcpu = hyp_vm->vcpus[vcpu_idx];
|
||||
/* Pairs with smp_store_release() in register_hyp_vcpu(). */
|
||||
hyp_vcpu = smp_load_acquire(&hyp_vm->vcpus[vcpu_idx]);
|
||||
if (!hyp_vcpu)
|
||||
goto unlock;
|
||||
|
||||
|
|
@ -860,12 +861,30 @@ int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
|
|||
* the page-aligned size of 'struct pkvm_hyp_vcpu'.
|
||||
* Return 0 on success, negative error code on failure.
|
||||
*/
|
||||
static int register_hyp_vcpu(struct pkvm_hyp_vm *hyp_vm,
|
||||
struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
{
|
||||
unsigned int idx = hyp_vcpu->vcpu.vcpu_idx;
|
||||
|
||||
if (idx >= hyp_vm->kvm.created_vcpus)
|
||||
return -EINVAL;
|
||||
|
||||
if (hyp_vm->vcpus[idx])
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Ensure the hyp_vcpu is initialised before publishing it to
|
||||
* the vCPU-load path via 'hyp_vm->vcpus[]'.
|
||||
*/
|
||||
smp_store_release(&hyp_vm->vcpus[idx], hyp_vcpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
|
||||
unsigned long vcpu_hva)
|
||||
{
|
||||
struct pkvm_hyp_vcpu *hyp_vcpu;
|
||||
struct pkvm_hyp_vm *hyp_vm;
|
||||
unsigned int idx;
|
||||
int ret;
|
||||
|
||||
hyp_vcpu = map_donated_memory(vcpu_hva, sizeof(*hyp_vcpu));
|
||||
|
|
@ -884,18 +903,11 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
|
|||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
idx = hyp_vcpu->vcpu.vcpu_idx;
|
||||
if (idx >= hyp_vm->kvm.created_vcpus) {
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
ret = register_hyp_vcpu(hyp_vm, hyp_vcpu);
|
||||
if (ret) {
|
||||
unpin_host_vcpu(host_vcpu);
|
||||
unpin_host_sve_state(hyp_vcpu);
|
||||
}
|
||||
|
||||
if (hyp_vm->vcpus[idx]) {
|
||||
ret = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hyp_vm->vcpus[idx] = hyp_vcpu;
|
||||
unlock:
|
||||
hyp_spin_unlock(&vm_table_lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -312,10 +312,6 @@ void __noreturn __pkvm_init_finalise(void)
|
|||
};
|
||||
pkvm_pgtable.mm_ops = &pkvm_pgtable_mm_ops;
|
||||
|
||||
ret = fix_host_ownership();
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = fix_hyp_pgtable_refcnt();
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
@ -324,6 +320,10 @@ void __noreturn __pkvm_init_finalise(void)
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = fix_host_ownership();
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = hyp_ffa_init(ffa_proxy_pages);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ static int vgic_mmio_uaccess_write_v2_misc(struct kvm_vcpu *vcpu,
|
|||
* migration from old kernels to new kernels with legacy
|
||||
* userspace.
|
||||
*/
|
||||
reg = FIELD_GET(GICD_IIDR_REVISION_MASK, reg);
|
||||
reg = FIELD_GET(GICD_IIDR_REVISION_MASK, val);
|
||||
switch (reg) {
|
||||
case KVM_VGIC_IMP_REV_2:
|
||||
case KVM_VGIC_IMP_REV_3:
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ static int vgic_mmio_uaccess_write_v3_misc(struct kvm_vcpu *vcpu,
|
|||
if ((reg ^ val) & ~GICD_IIDR_REVISION_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
reg = FIELD_GET(GICD_IIDR_REVISION_MASK, reg);
|
||||
reg = FIELD_GET(GICD_IIDR_REVISION_MASK, val);
|
||||
switch (reg) {
|
||||
case KVM_VGIC_IMP_REV_2:
|
||||
case KVM_VGIC_IMP_REV_3:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ obj-y += mm/
|
|||
obj-y += net/
|
||||
obj-y += vdso/
|
||||
|
||||
obj-$(CONFIG_KVM) += kvm/
|
||||
obj-$(subst m,y,$(CONFIG_KVM)) += kvm/
|
||||
|
||||
# for cleaning
|
||||
subdir- += boot
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ menu "Kernel type and options"
|
|||
|
||||
choice
|
||||
prompt "Kernel type"
|
||||
default 64BIT # Keep existing behavior
|
||||
|
||||
config 32BIT
|
||||
bool "32-bit kernel"
|
||||
|
|
|
|||
|
|
@ -55,9 +55,11 @@ endif
|
|||
ifdef CONFIG_32BIT
|
||||
tool-archpref = $(32bit-tool-archpref)
|
||||
UTS_MACHINE := loongarch32
|
||||
cflags-y += $(call cc-option,-m32)
|
||||
else
|
||||
tool-archpref = $(64bit-tool-archpref)
|
||||
UTS_MACHINE := loongarch64
|
||||
cflags-y += $(call cc-option,-m64)
|
||||
endif
|
||||
|
||||
ifneq ($(SUBARCH),$(ARCH))
|
||||
|
|
|
|||
|
|
@ -20,3 +20,23 @@ asmlinkage void noinstr __no_stack_protector ret_from_kernel_thread(struct task_
|
|||
struct pt_regs *regs,
|
||||
int (*fn)(void *),
|
||||
void *fn_arg);
|
||||
|
||||
struct kvm_run;
|
||||
struct kvm_vcpu;
|
||||
struct loongarch_fpu;
|
||||
|
||||
void kvm_exc_entry(void);
|
||||
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
|
||||
void kvm_save_fpu(struct loongarch_fpu *fpu);
|
||||
void kvm_restore_fpu(struct loongarch_fpu *fpu);
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LSX
|
||||
void kvm_save_lsx(struct loongarch_fpu *fpu);
|
||||
void kvm_restore_lsx(struct loongarch_fpu *fpu);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LASX
|
||||
void kvm_save_lasx(struct loongarch_fpu *fpu);
|
||||
void kvm_restore_lasx(struct loongarch_fpu *fpu);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ struct kvm_context {
|
|||
struct kvm_world_switch {
|
||||
int (*exc_entry)(void);
|
||||
int (*enter_guest)(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
unsigned long page_order;
|
||||
};
|
||||
|
||||
#define MAX_PGTABLE_LEVELS 4
|
||||
|
|
@ -359,8 +358,6 @@ void kvm_exc_entry(void);
|
|||
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
|
||||
extern unsigned long vpid_mask;
|
||||
extern const unsigned long kvm_exception_size;
|
||||
extern const unsigned long kvm_enter_guest_size;
|
||||
extern struct kvm_world_switch *kvm_loongarch_ops;
|
||||
|
||||
#define SW_GCSR (1 << 0)
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
9, 10, 11, 12, 13, 14, 15, 16, \
|
||||
17, 18, 19, 20, 21, 22, 23, 24, \
|
||||
25, 26, 27, 28, 29, 30, 31; \
|
||||
.cfi_offset \num, SC_REGS + \num * SZREG; \
|
||||
.cfi_offset \num, SC_REGS + \num * 8; \
|
||||
.endr; \
|
||||
\
|
||||
nop; \
|
||||
|
|
|
|||
|
|
@ -85,12 +85,6 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
|
|||
return count;
|
||||
}
|
||||
|
||||
static inline bool loongarch_vdso_hres_capable(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#define __arch_vdso_hres_capable loongarch_vdso_hres_capable
|
||||
|
||||
#endif /* CONFIG_GENERIC_GETTIMEOFDAY */
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@ include $(srctree)/virt/kvm/Makefile.kvm
|
|||
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
||||
obj-y += switch.o
|
||||
|
||||
kvm-y += exit.o
|
||||
kvm-y += interrupt.o
|
||||
kvm-y += main.o
|
||||
kvm-y += mmu.o
|
||||
kvm-y += switch.o
|
||||
kvm-y += timer.o
|
||||
kvm-y += tlb.o
|
||||
kvm-y += vcpu.o
|
||||
|
|
|
|||
|
|
@ -390,6 +390,7 @@ int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst)
|
|||
run->mmio.len = 8;
|
||||
break;
|
||||
default:
|
||||
ret = EMULATE_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -28,23 +28,29 @@ static unsigned int priority_to_irq[EXCCODE_INT_NUM] = {
|
|||
static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
|
||||
{
|
||||
unsigned int irq = 0;
|
||||
unsigned long old, new;
|
||||
|
||||
clear_bit(priority, &vcpu->arch.irq_pending);
|
||||
if (priority < EXCCODE_INT_NUM)
|
||||
irq = priority_to_irq[priority];
|
||||
|
||||
if (kvm_guest_has_msgint(&vcpu->arch) && (priority == INT_AVEC)) {
|
||||
dmsintc_inject_irq(vcpu);
|
||||
set_gcsr_estat(irq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (priority) {
|
||||
case INT_AVEC:
|
||||
if (!kvm_guest_has_msgint(&vcpu->arch))
|
||||
break;
|
||||
dmsintc_inject_irq(vcpu);
|
||||
fallthrough;
|
||||
case INT_TI:
|
||||
case INT_IPI:
|
||||
case INT_SWI0:
|
||||
case INT_SWI1:
|
||||
old = kvm_read_hw_gcsr(LOONGARCH_CSR_TVAL);
|
||||
set_gcsr_estat(irq);
|
||||
new = kvm_read_hw_gcsr(LOONGARCH_CSR_TVAL);
|
||||
|
||||
/* Inject TI if TVAL inverted */
|
||||
if (new > old)
|
||||
set_gcsr_estat(CPU_TIMER);
|
||||
break;
|
||||
|
||||
case INT_HWI0 ... INT_HWI7:
|
||||
|
|
@ -61,22 +67,28 @@ static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
|
|||
static int kvm_irq_clear(struct kvm_vcpu *vcpu, unsigned int priority)
|
||||
{
|
||||
unsigned int irq = 0;
|
||||
unsigned long old, new;
|
||||
|
||||
clear_bit(priority, &vcpu->arch.irq_clear);
|
||||
if (priority < EXCCODE_INT_NUM)
|
||||
irq = priority_to_irq[priority];
|
||||
|
||||
if (kvm_guest_has_msgint(&vcpu->arch) && (priority == INT_AVEC)) {
|
||||
clear_gcsr_estat(irq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (priority) {
|
||||
case INT_AVEC:
|
||||
if (!kvm_guest_has_msgint(&vcpu->arch))
|
||||
break;
|
||||
fallthrough;
|
||||
case INT_TI:
|
||||
case INT_IPI:
|
||||
case INT_SWI0:
|
||||
case INT_SWI1:
|
||||
old = kvm_read_hw_gcsr(LOONGARCH_CSR_TVAL);
|
||||
clear_gcsr_estat(irq);
|
||||
new = kvm_read_hw_gcsr(LOONGARCH_CSR_TVAL);
|
||||
|
||||
/* Inject TI if TVAL inverted */
|
||||
if (new > old)
|
||||
set_gcsr_estat(CPU_TIMER);
|
||||
break;
|
||||
|
||||
case INT_HWI0 ... INT_HWI7:
|
||||
|
|
|
|||
|
|
@ -348,8 +348,7 @@ void kvm_arch_disable_virtualization_cpu(void)
|
|||
|
||||
static int kvm_loongarch_env_init(void)
|
||||
{
|
||||
int cpu, order, ret;
|
||||
void *addr;
|
||||
int cpu, ret;
|
||||
struct kvm_context *context;
|
||||
|
||||
vmcs = alloc_percpu(struct kvm_context);
|
||||
|
|
@ -365,30 +364,8 @@ static int kvm_loongarch_env_init(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* PGD register is shared between root kernel and kvm hypervisor.
|
||||
* So world switch entry should be in DMW area rather than TLB area
|
||||
* to avoid page fault reenter.
|
||||
*
|
||||
* In future if hardware pagetable walking is supported, we won't
|
||||
* need to copy world switch code to DMW area.
|
||||
*/
|
||||
order = get_order(kvm_exception_size + kvm_enter_guest_size);
|
||||
addr = (void *)__get_free_pages(GFP_KERNEL, order);
|
||||
if (!addr) {
|
||||
free_percpu(vmcs);
|
||||
vmcs = NULL;
|
||||
kfree(kvm_loongarch_ops);
|
||||
kvm_loongarch_ops = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(addr, kvm_exc_entry, kvm_exception_size);
|
||||
memcpy(addr + kvm_exception_size, kvm_enter_guest, kvm_enter_guest_size);
|
||||
flush_icache_range((unsigned long)addr, (unsigned long)addr + kvm_exception_size + kvm_enter_guest_size);
|
||||
kvm_loongarch_ops->exc_entry = addr;
|
||||
kvm_loongarch_ops->enter_guest = addr + kvm_exception_size;
|
||||
kvm_loongarch_ops->page_order = order;
|
||||
kvm_loongarch_ops->exc_entry = (void *)kvm_exc_entry;
|
||||
kvm_loongarch_ops->enter_guest = (void *)kvm_enter_guest;
|
||||
|
||||
vpid_mask = read_csr_gstat();
|
||||
vpid_mask = (vpid_mask & CSR_GSTAT_GIDBIT) >> CSR_GSTAT_GIDBIT_SHIFT;
|
||||
|
|
@ -428,16 +405,10 @@ static int kvm_loongarch_env_init(void)
|
|||
|
||||
static void kvm_loongarch_env_exit(void)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
if (vmcs)
|
||||
free_percpu(vmcs);
|
||||
|
||||
if (kvm_loongarch_ops) {
|
||||
if (kvm_loongarch_ops->exc_entry) {
|
||||
addr = (unsigned long)kvm_loongarch_ops->exc_entry;
|
||||
free_pages(addr, kvm_loongarch_ops->page_order);
|
||||
}
|
||||
kfree(kvm_loongarch_ops);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ static int kvm_flush_pte(kvm_pte_t *pte, phys_addr_t addr, kvm_ptw_ctx *ctx)
|
|||
else
|
||||
kvm->stat.pages--;
|
||||
|
||||
*pte = ctx->invalid_entry;
|
||||
kvm_set_pte(pte, ctx->invalid_entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/kvm_types.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/loongarch.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/unwind_hints.h>
|
||||
|
||||
|
|
@ -100,11 +102,16 @@
|
|||
* - is still in guest mode, such as pgd table/vmid registers etc,
|
||||
* - will fix with hw page walk enabled in future
|
||||
* load kvm_vcpu from reserved CSR KVM_VCPU_KS, and save a2 to KVM_TEMP_KS
|
||||
*
|
||||
* PGD register is shared between root kernel and kvm hypervisor.
|
||||
* So world switch entry should be in DMW area rather than TLB area
|
||||
* to avoid page fault re-enter.
|
||||
*/
|
||||
.text
|
||||
.p2align PAGE_SHIFT
|
||||
.cfi_sections .debug_frame
|
||||
SYM_CODE_START(kvm_exc_entry)
|
||||
UNWIND_HINT_UNDEFINED
|
||||
UNWIND_HINT_END_OF_STACK
|
||||
csrwr a2, KVM_TEMP_KS
|
||||
csrrd a2, KVM_VCPU_KS
|
||||
addi.d a2, a2, KVM_VCPU_ARCH
|
||||
|
|
@ -190,8 +197,8 @@ ret_to_host:
|
|||
kvm_restore_host_gpr a2
|
||||
jr ra
|
||||
|
||||
SYM_INNER_LABEL(kvm_exc_entry_end, SYM_L_LOCAL)
|
||||
SYM_CODE_END(kvm_exc_entry)
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_exc_entry)
|
||||
|
||||
/*
|
||||
* int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
||||
|
|
@ -215,8 +222,8 @@ SYM_FUNC_START(kvm_enter_guest)
|
|||
/* Save kvm_vcpu to kscratch */
|
||||
csrwr a1, KVM_VCPU_KS
|
||||
kvm_switch_to_guest
|
||||
SYM_INNER_LABEL(kvm_enter_guest_end, SYM_L_LOCAL)
|
||||
SYM_FUNC_END(kvm_enter_guest)
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_enter_guest)
|
||||
|
||||
SYM_FUNC_START(kvm_save_fpu)
|
||||
fpu_save_csr a0 t1
|
||||
|
|
@ -224,6 +231,7 @@ SYM_FUNC_START(kvm_save_fpu)
|
|||
fpu_save_cc a0 t1 t2
|
||||
jr ra
|
||||
SYM_FUNC_END(kvm_save_fpu)
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_save_fpu)
|
||||
|
||||
SYM_FUNC_START(kvm_restore_fpu)
|
||||
fpu_restore_double a0 t1
|
||||
|
|
@ -231,6 +239,7 @@ SYM_FUNC_START(kvm_restore_fpu)
|
|||
fpu_restore_cc a0 t1 t2
|
||||
jr ra
|
||||
SYM_FUNC_END(kvm_restore_fpu)
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_restore_fpu)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LSX
|
||||
SYM_FUNC_START(kvm_save_lsx)
|
||||
|
|
@ -239,6 +248,7 @@ SYM_FUNC_START(kvm_save_lsx)
|
|||
lsx_save_data a0 t1
|
||||
jr ra
|
||||
SYM_FUNC_END(kvm_save_lsx)
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_save_lsx)
|
||||
|
||||
SYM_FUNC_START(kvm_restore_lsx)
|
||||
lsx_restore_data a0 t1
|
||||
|
|
@ -246,6 +256,7 @@ SYM_FUNC_START(kvm_restore_lsx)
|
|||
fpu_restore_csr a0 t1 t2
|
||||
jr ra
|
||||
SYM_FUNC_END(kvm_restore_lsx)
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_restore_lsx)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LASX
|
||||
|
|
@ -255,6 +266,7 @@ SYM_FUNC_START(kvm_save_lasx)
|
|||
lasx_save_data a0 t1
|
||||
jr ra
|
||||
SYM_FUNC_END(kvm_save_lasx)
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_save_lasx)
|
||||
|
||||
SYM_FUNC_START(kvm_restore_lasx)
|
||||
lasx_restore_data a0 t1
|
||||
|
|
@ -262,10 +274,8 @@ SYM_FUNC_START(kvm_restore_lasx)
|
|||
fpu_restore_csr a0 t1 t2
|
||||
jr ra
|
||||
SYM_FUNC_END(kvm_restore_lasx)
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_restore_lasx)
|
||||
#endif
|
||||
.section ".rodata"
|
||||
SYM_DATA(kvm_exception_size, .quad kvm_exc_entry_end - kvm_exc_entry)
|
||||
SYM_DATA(kvm_enter_guest_size, .quad kvm_enter_guest_end - kvm_enter_guest)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
STACK_FRAME_NON_STANDARD kvm_restore_fpu
|
||||
|
|
|
|||
|
|
@ -96,15 +96,21 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu)
|
|||
* and set CSR TVAL with -1
|
||||
*/
|
||||
write_gcsr_timertick(0);
|
||||
__delay(2); /* Wait cycles until timer interrupt injected */
|
||||
|
||||
/*
|
||||
* Writing CSR_TINTCLR_TI to LOONGARCH_CSR_TINTCLR will clear
|
||||
* timer interrupt, and CSR TVAL keeps unchanged with -1, it
|
||||
* avoids spurious timer interrupt
|
||||
*/
|
||||
if (!(estat & CPU_TIMER))
|
||||
if (!(estat & CPU_TIMER)) {
|
||||
__delay(2); /* Wait cycles until timer interrupt injected */
|
||||
|
||||
/* Write TVAL with max value if no TI shot */
|
||||
estat = kvm_read_hw_gcsr(LOONGARCH_CSR_ESTAT);
|
||||
if (!(estat & CPU_TIMER))
|
||||
write_gcsr_timertick(CSR_TCFG_VAL);
|
||||
gcsr_write(CSR_TINTCLR_TI, LOONGARCH_CSR_TINTCLR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
|||
r = 1;
|
||||
break;
|
||||
case KVM_CAP_NR_VCPUS:
|
||||
r = num_online_cpus();
|
||||
r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
|
||||
break;
|
||||
case KVM_CAP_MAX_VCPUS:
|
||||
r = KVM_MAX_VCPUS;
|
||||
|
|
|
|||
|
|
@ -61,11 +61,16 @@ static void acpi_release_root_info(struct acpi_pci_root_info *ci)
|
|||
static int acpi_prepare_root_resources(struct acpi_pci_root_info *ci)
|
||||
{
|
||||
int status;
|
||||
unsigned long long pci_h = 0;
|
||||
struct resource_entry *entry, *tmp;
|
||||
struct acpi_device *device = ci->bridge;
|
||||
|
||||
status = acpi_pci_probe_root_resources(ci);
|
||||
if (status > 0) {
|
||||
acpi_evaluate_integer(device->handle, "PCIH", NULL, &pci_h);
|
||||
if (pci_h)
|
||||
return status;
|
||||
|
||||
resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
|
||||
if (entry->res->flags & IORESOURCE_MEM) {
|
||||
entry->offset = ci->root->mcfg_addr & GENMASK_ULL(63, 40);
|
||||
|
|
|
|||
|
|
@ -132,6 +132,9 @@ static void loongson_gpu_fixup_dma_hang(struct pci_dev *pdev, bool on)
|
|||
crtc_reg = regbase;
|
||||
crtc_offset = 0x400;
|
||||
break;
|
||||
default:
|
||||
iounmap(regbase);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < CRTC_NUM_MAX; i++, crtc_reg += crtc_offset) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ obj-vdso-$(CONFIG_GENERIC_GETTIMEOFDAY) += vgettimeofday.o
|
|||
ccflags-vdso := \
|
||||
$(filter -I%,$(KBUILD_CFLAGS)) \
|
||||
$(filter -E%,$(KBUILD_CFLAGS)) \
|
||||
$(filter -m32,$(KBUILD_CFLAGS)) \
|
||||
$(filter -m64,$(KBUILD_CFLAGS)) \
|
||||
$(filter -march=%,$(KBUILD_CFLAGS)) \
|
||||
$(filter -m%-float,$(KBUILD_CFLAGS)) \
|
||||
$(CLANG_FLAGS) \
|
||||
|
|
|
|||
|
|
@ -174,15 +174,21 @@ ifeq ($(KBUILD_EXTMOD),)
|
|||
# this hack.
|
||||
prepare: vdso_prepare
|
||||
vdso_prepare: prepare0
|
||||
$(if $(CONFIG_64BIT),$(Q)$(MAKE) \
|
||||
$(build)=arch/parisc/kernel/vdso64 include/generated/vdso64-offsets.h)
|
||||
$(if $(CONFIG_PA11)$(CONFIG_COMPAT),$(Q)$(MAKE) \
|
||||
ifdef CONFIG_64BIT
|
||||
$(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso64 include/generated/vdso64-offsets.h
|
||||
$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
|
||||
$(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h)
|
||||
else
|
||||
$(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h
|
||||
endif
|
||||
endif
|
||||
|
||||
vdso-install-$(CONFIG_PA11) += arch/parisc/kernel/vdso32/vdso32.so
|
||||
ifdef CONFIG_64BIT
|
||||
vdso-install-y += arch/parisc/kernel/vdso64/vdso64.so
|
||||
vdso-install-$(CONFIG_COMPAT) += arch/parisc/kernel/vdso32/vdso32.so
|
||||
vdso-install-$(CONFIG_64BIT) += arch/parisc/kernel/vdso64/vdso64.so
|
||||
else
|
||||
vdso-install-y += arch/parisc/kernel/vdso32/vdso32.so
|
||||
endif
|
||||
|
||||
install: KBUILD_IMAGE := vmlinux
|
||||
zinstall: KBUILD_IMAGE := vmlinuz
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@
|
|||
|
||||
#ifdef CONFIG_64BIT
|
||||
#include <generated/vdso64-offsets.h>
|
||||
#define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name))
|
||||
#endif
|
||||
#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
|
||||
#include <generated/vdso32-offsets.h>
|
||||
#endif
|
||||
|
||||
#define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name))
|
||||
#define VDSO32_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso32_offset_##name))
|
||||
#else
|
||||
#define VDSO32_SYMBOL(tsk, name) 0UL
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
|
|||
|
||||
# vdso
|
||||
obj-y += vdso.o
|
||||
obj-$(CONFIG_64BIT) += vdso64/
|
||||
obj-$(CONFIG_PA11) += vdso32/
|
||||
ifdef CONFIG_64BIT
|
||||
obj-y += vdso64/
|
||||
obj-$(CONFIG_COMPAT) += vdso32/
|
||||
else
|
||||
obj-y += vdso32/
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -41,9 +41,7 @@
|
|||
const struct dma_map_ops *hppa_dma_ops __ro_after_init;
|
||||
EXPORT_SYMBOL(hppa_dma_ops);
|
||||
|
||||
static struct device root = {
|
||||
.init_name = "parisc",
|
||||
};
|
||||
static struct device *root;
|
||||
|
||||
static inline int check_dev(struct device *dev)
|
||||
{
|
||||
|
|
@ -89,7 +87,7 @@ static int for_each_padev(int (*fn)(struct device *, void *), void * data)
|
|||
.obj = data,
|
||||
.fn = fn,
|
||||
};
|
||||
return device_for_each_child(&root, &recurse_data, descend_children);
|
||||
return device_for_each_child(root, &recurse_data, descend_children);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -290,7 +288,7 @@ const struct parisc_device *
|
|||
find_pa_parent_type(const struct parisc_device *padev, int type)
|
||||
{
|
||||
const struct device *dev = &padev->dev;
|
||||
while (dev != &root) {
|
||||
while (dev != root) {
|
||||
struct parisc_device *candidate = to_parisc_device(dev);
|
||||
if (candidate->id.hw_type == type)
|
||||
return candidate;
|
||||
|
|
@ -319,7 +317,7 @@ static void get_node_path(struct device *dev, struct hardware_path *path)
|
|||
dev = dev->parent;
|
||||
}
|
||||
|
||||
while (dev != &root) {
|
||||
while (dev != root) {
|
||||
if (dev_is_pci(dev)) {
|
||||
unsigned int devfn = to_pci_dev(dev)->devfn;
|
||||
path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn)<< 5);
|
||||
|
|
@ -482,7 +480,7 @@ static struct parisc_device * __init alloc_tree_node(
|
|||
static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
|
||||
{
|
||||
int i;
|
||||
struct device *parent = &root;
|
||||
struct device *parent = root;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (modpath->bc[i] == -1)
|
||||
continue;
|
||||
|
|
@ -755,7 +753,7 @@ parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
|
|||
struct device *hwpath_to_device(struct hardware_path *modpath)
|
||||
{
|
||||
int i;
|
||||
struct device *parent = &root;
|
||||
struct device *parent = root;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (modpath->bc[i] == -1)
|
||||
continue;
|
||||
|
|
@ -880,7 +878,7 @@ void __init walk_central_bus(void)
|
|||
{
|
||||
walk_native_bus(CENTRAL_BUS_ADDR,
|
||||
CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET),
|
||||
&root);
|
||||
root);
|
||||
}
|
||||
|
||||
static __init void print_parisc_device(struct parisc_device *dev)
|
||||
|
|
@ -907,9 +905,10 @@ void __init init_parisc_bus(void)
|
|||
{
|
||||
if (bus_register(&parisc_bus_type))
|
||||
panic("Could not register PA-RISC bus type\n");
|
||||
if (device_register(&root))
|
||||
|
||||
root = root_device_register("parisc");
|
||||
if (IS_ERR(root))
|
||||
panic("Could not register PA-RISC root device\n");
|
||||
get_device(&root);
|
||||
}
|
||||
|
||||
static __init void qemu_header(void)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
|
|||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_FB=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_TILEBLITTING=y
|
||||
CONFIG_FB_RADEON=y
|
||||
CONFIG_FB_3DFX=y
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
|
|||
CONFIG_NVRAM=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_FB=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_OF=y
|
||||
CONFIG_FB_MATROX=y
|
||||
CONFIG_FB_MATROX_MILLENIUM=y
|
||||
|
|
|
|||
|
|
@ -121,7 +121,6 @@ CONFIG_I2C_CHARDEV=y
|
|||
CONFIG_AGP=m
|
||||
CONFIG_AGP_UNINORTH=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_TILEBLITTING=y
|
||||
CONFIG_FB_OF=y
|
||||
CONFIG_FB_NVIDIA=y
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@ CONFIG_SENSORS_LM85=y
|
|||
CONFIG_SENSORS_LM90=y
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_RADEON=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_TILEBLITTING=y
|
||||
CONFIG_FB_VGA16=y
|
||||
CONFIG_FB_NVIDIA=y
|
||||
|
|
|
|||
|
|
@ -196,7 +196,6 @@ CONFIG_I2C_CHARDEV=y
|
|||
# CONFIG_PTP_1588_CLOCK is not set
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_AST=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_OF=y
|
||||
CONFIG_FB_MATROX=m
|
||||
CONFIG_FB_MATROX_MILLENIUM=y
|
||||
|
|
|
|||
|
|
@ -249,7 +249,6 @@ CONFIG_I2C_CHARDEV=y
|
|||
CONFIG_I2C_AMD8111=y
|
||||
CONFIG_I2C_PASEMI=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_OF=y
|
||||
CONFIG_FB_MATROX=y
|
||||
CONFIG_FB_MATROX_MILLENIUM=y
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
|
|||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_AMD8111=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_OF=y
|
||||
CONFIG_FB_MATROX=y
|
||||
CONFIG_FB_MATROX_MILLENIUM=y
|
||||
|
|
|
|||
|
|
@ -214,7 +214,6 @@ CONFIG_SENSORS_IBMPOWERNV=m
|
|||
CONFIG_DRM=m
|
||||
CONFIG_DRM_AST=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_LOGO=y
|
||||
|
|
|
|||
|
|
@ -62,6 +62,12 @@ CC32FLAGSREMOVE += -fno-stack-clash-protection
|
|||
# 32-bit one. clang validates the values passed to these arguments during
|
||||
# parsing, even when -fno-stack-protector is passed afterwards.
|
||||
CC32FLAGSREMOVE += -mstack-protector-guard%
|
||||
# ftrace is disabled for the vdso but arch/powerpc/Makefile adds this define to
|
||||
# KBUILD_CPPFLAGS, which enables use of the 'patchable_function_entry'
|
||||
# attribute in the 'inline' define via 'notrace'. This attribute is not
|
||||
# supported for the powerpcle target, resulting in many instances of
|
||||
# -Wunknown-attributes.
|
||||
CC32FLAGSREMOVE += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
|
||||
endif
|
||||
LD32FLAGS := -Wl,-soname=linux-vdso32.so.1
|
||||
AS32FLAGS := -D__VDSO32__
|
||||
|
|
|
|||
|
|
@ -16,4 +16,4 @@ GCOV_PROFILE_core_$(BITS).o := n
|
|||
KCOV_INSTRUMENT_core_$(BITS).o := n
|
||||
UBSAN_SANITIZE_core_$(BITS).o := n
|
||||
KASAN_SANITIZE_core.o := n
|
||||
KASAN_SANITIZE_core_$(BITS) := n
|
||||
KASAN_SANITIZE_core_$(BITS).o := n
|
||||
|
|
|
|||
|
|
@ -52,7 +52,14 @@ int exit_vmx_usercopy(void)
|
|||
}
|
||||
EXPORT_SYMBOL(exit_vmx_usercopy);
|
||||
|
||||
int enter_vmx_ops(void)
|
||||
/*
|
||||
* Can be called from kexec copy_page() path with MMU off. The kexec
|
||||
* code sets preempt_count to HARDIRQ_OFFSET so we return early here.
|
||||
* Since in_interrupt() is always inline, __no_sanitize_address on this
|
||||
* function is sufficient to avoid KASAN shadow memory accesses in real
|
||||
* mode.
|
||||
*/
|
||||
int __no_sanitize_address enter_vmx_ops(void)
|
||||
{
|
||||
if (in_interrupt())
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2242,6 +2242,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
|
|||
const u64 last_period = event->hw.last_period;
|
||||
s64 prev, delta, left;
|
||||
int record = 0;
|
||||
int mark_event = regs->dsisr & MMCRA_SAMPLE_ENABLE;
|
||||
|
||||
if (event->hw.state & PERF_HES_STOPPED) {
|
||||
write_pmc(event->hw.idx, 0);
|
||||
|
|
@ -2304,9 +2305,9 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
|
|||
* In ISA v3.0 and before values "0" and "7" are considered reserved.
|
||||
* In ISA v3.1, value "7" has been used to indicate "larx/stcx".
|
||||
* Drop the sample if "type" has reserved values for this field with a
|
||||
* ISA version check.
|
||||
* ISA version check for marked events.
|
||||
*/
|
||||
if (event->attr.sample_type & PERF_SAMPLE_DATA_SRC &&
|
||||
if (mark_event && event->attr.sample_type & PERF_SAMPLE_DATA_SRC &&
|
||||
ppmu->get_mem_data_src) {
|
||||
val = (regs->dar & SIER_TYPE_MASK) >> SIER_TYPE_SHIFT;
|
||||
if (val == 0 || (val == 7 && !cpu_has_feature(CPU_FTR_ARCH_31))) {
|
||||
|
|
|
|||
|
|
@ -477,7 +477,7 @@ int cpm1_gpiochip_add16(struct device *dev)
|
|||
struct device_node *np = dev->of_node;
|
||||
struct cpm1_gpio16_chip *cpm1_gc;
|
||||
struct gpio_chip *gc;
|
||||
u16 mask;
|
||||
u32 mask;
|
||||
|
||||
cpm1_gc = devm_kzalloc(dev, sizeof(*cpm1_gc), GFP_KERNEL);
|
||||
if (!cpm1_gc)
|
||||
|
|
@ -485,7 +485,7 @@ int cpm1_gpiochip_add16(struct device *dev)
|
|||
|
||||
spin_lock_init(&cpm1_gc->lock);
|
||||
|
||||
if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
|
||||
if (!of_property_read_u32(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < 16; i++)
|
||||
|
|
|
|||
|
|
@ -272,13 +272,12 @@ void __init pas_pci_init(void)
|
|||
{
|
||||
struct device_node *root = of_find_node_by_path("/");
|
||||
struct device_node *np;
|
||||
int res;
|
||||
|
||||
pci_set_flags(PCI_SCAN_ALL_PCIE_DEVS);
|
||||
|
||||
np = of_find_compatible_node(root, NULL, "pasemi,rootbus");
|
||||
if (np) {
|
||||
res = pas_add_bridge(np);
|
||||
pas_add_bridge(np);
|
||||
of_node_put(np);
|
||||
}
|
||||
of_node_put(root);
|
||||
|
|
|
|||
|
|
@ -950,8 +950,6 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
|
|||
|
||||
static int __init ps3_register_devices(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
|
||||
return -ENODEV;
|
||||
|
||||
|
|
@ -959,7 +957,7 @@ static int __init ps3_register_devices(void)
|
|||
|
||||
/* ps3_repository_dump_bus_info(); */
|
||||
|
||||
result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
|
||||
ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
|
||||
|
||||
ps3_register_vuart_devices();
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ static void *htm_buf;
|
|||
static void *htm_status_buf;
|
||||
static void *htm_info_buf;
|
||||
static void *htm_caps_buf;
|
||||
static void *htm_mem_buf;
|
||||
static u32 nodeindex;
|
||||
static u32 nodalchipindex;
|
||||
static u32 coreindexonchip;
|
||||
|
|
@ -86,7 +87,7 @@ static ssize_t htm_return_check(long rc)
|
|||
static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
void *htm_buf = filp->private_data;
|
||||
void *htm_buf_data = filp->private_data;
|
||||
unsigned long page, read_size, available;
|
||||
loff_t offset;
|
||||
long rc, ret;
|
||||
|
|
@ -100,7 +101,7 @@ static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
|
|||
* - last three values are address, size and offset
|
||||
*/
|
||||
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
|
||||
htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf),
|
||||
htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf_data),
|
||||
PAGE_SIZE, page);
|
||||
|
||||
ret = htm_return_check(rc);
|
||||
|
|
@ -112,7 +113,61 @@ static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
|
|||
available = PAGE_SIZE;
|
||||
read_size = min(count, available);
|
||||
*ppos += read_size;
|
||||
return simple_read_from_buffer(ubuf, count, &offset, htm_buf, available);
|
||||
return simple_read_from_buffer(ubuf, count, &offset, htm_buf_data, available);
|
||||
}
|
||||
|
||||
static ssize_t htmsystem_mem_read(struct file *filp, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
void *htm_mem_data = filp->private_data;
|
||||
long rc, ret;
|
||||
u64 *num_entries;
|
||||
u64 to_copy = 0;
|
||||
loff_t offset = 0;
|
||||
u64 mem_offset = 0;
|
||||
|
||||
/*
|
||||
* Invoke H_HTM call with:
|
||||
* - operation as htm status (H_HTM_OP_STATUS)
|
||||
* - last three values as addr, size and offset. "offset"
|
||||
* is value from output buffer header that points to next
|
||||
* entry to dump. 0 is the first entry to dump. next entry
|
||||
* is read from the output bufferbyte offset 0x8.
|
||||
*
|
||||
* When first time hcall is invoked, mem_offset should be
|
||||
* zero because zero is the first entry.
|
||||
* In the next hcall, offset of next entry to read from is
|
||||
* picked from output buffer header itself. So don't fill
|
||||
* mem_offset for first read.
|
||||
*
|
||||
* If there is no further data to read in next iteration,
|
||||
* offset value from output buffer header will point to -1.
|
||||
*/
|
||||
if (*ppos) {
|
||||
mem_offset = *(u64 *)(htm_mem_data + 0x8);
|
||||
if (mem_offset == -1)
|
||||
return 0;
|
||||
}
|
||||
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
|
||||
htmtype, H_HTM_OP_DUMP_SYSMEM_CONF, virt_to_phys(htm_mem_data),
|
||||
PAGE_SIZE, be64_to_cpu(mem_offset));
|
||||
ret = htm_return_check(rc);
|
||||
if (ret <= 0) {
|
||||
pr_debug("H_HTM hcall returned for op: H_HTM_OP_DUMP_SYSMEM_CONF with hcall returning %ld\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* HTM system mem buffer, start of buffer + 0x10 gives the
|
||||
* number of HTM entries in the buffer.
|
||||
* So total count to copy is:
|
||||
* 32 bytes (for first 5 fields) + (number of HTM entries * entry size)
|
||||
*/
|
||||
num_entries = htm_mem_data + 0x10;
|
||||
to_copy = 32 + (be64_to_cpu(*num_entries) * 32);
|
||||
|
||||
*ppos += to_copy;
|
||||
return simple_read_from_buffer(ubuf, count, &offset, htm_mem_data, to_copy);
|
||||
}
|
||||
|
||||
static const struct file_operations htmdump_fops = {
|
||||
|
|
@ -121,6 +176,12 @@ static const struct file_operations htmdump_fops = {
|
|||
.open = simple_open,
|
||||
};
|
||||
|
||||
static const struct file_operations htmsystem_mem_fops = {
|
||||
.llseek = NULL,
|
||||
.read = htmsystem_mem_read,
|
||||
.open = simple_open,
|
||||
};
|
||||
|
||||
static int htmconfigure_set(void *data, u64 val)
|
||||
{
|
||||
long rc, ret;
|
||||
|
|
@ -226,20 +287,31 @@ static int htmstart_get(void *data, u64 *val)
|
|||
static ssize_t htmstatus_read(struct file *filp, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
void *htm_status_buf = filp->private_data;
|
||||
void *htm_status_data = filp->private_data;
|
||||
long rc, ret;
|
||||
u64 *num_entries;
|
||||
u64 to_copy;
|
||||
int htmstatus_flag;
|
||||
loff_t offset = 0;
|
||||
u64 status_offset = 0;
|
||||
|
||||
/*
|
||||
* Invoke H_HTM call with:
|
||||
* - operation as htm status (H_HTM_OP_STATUS)
|
||||
* - last three values as addr, size and offset
|
||||
* - last three values as addr, size and offset.
|
||||
* "offset" is value from output buffer header
|
||||
* that points to next entry to dump. 0 is the first
|
||||
* entry to dump. next entry is read from the output
|
||||
* bufferbyte offset 0x8.
|
||||
*/
|
||||
if (*ppos) {
|
||||
status_offset = *(u64 *)(htm_status_data + 0x8);
|
||||
if (status_offset == -1)
|
||||
return 0;
|
||||
}
|
||||
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
|
||||
htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_buf),
|
||||
PAGE_SIZE, 0);
|
||||
htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_data),
|
||||
PAGE_SIZE, be64_to_cpu(status_offset));
|
||||
|
||||
ret = htm_return_check(rc);
|
||||
if (ret <= 0) {
|
||||
|
|
@ -255,13 +327,15 @@ static ssize_t htmstatus_read(struct file *filp, char __user *ubuf,
|
|||
* So total count to copy is:
|
||||
* 32 bytes (for first 7 fields) + (number of HTM entries * entry size)
|
||||
*/
|
||||
num_entries = htm_status_buf + 0x10;
|
||||
num_entries = htm_status_data + 0x10;
|
||||
if (htmtype == 0x2)
|
||||
htmstatus_flag = 0x8;
|
||||
else
|
||||
htmstatus_flag = 0x6;
|
||||
to_copy = 32 + (be64_to_cpu(*num_entries) * htmstatus_flag);
|
||||
return simple_read_from_buffer(ubuf, count, ppos, htm_status_buf, to_copy);
|
||||
*ppos += to_copy;
|
||||
|
||||
return simple_read_from_buffer(ubuf, count, &offset, htm_status_data, to_copy);
|
||||
}
|
||||
|
||||
static const struct file_operations htmstatus_fops = {
|
||||
|
|
@ -273,19 +347,30 @@ static const struct file_operations htmstatus_fops = {
|
|||
static ssize_t htminfo_read(struct file *filp, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
void *htm_info_buf = filp->private_data;
|
||||
void *htm_info_data = filp->private_data;
|
||||
long rc, ret;
|
||||
u64 *num_entries;
|
||||
u64 to_copy;
|
||||
loff_t offset = 0;
|
||||
u64 info_offset = 0;
|
||||
|
||||
/*
|
||||
* Invoke H_HTM call with:
|
||||
* - operation as htm status (H_HTM_OP_STATUS)
|
||||
* - last three values as addr, size and offset
|
||||
* "offset" is value from output buffer header
|
||||
* that points to next entry to dump. 0 is the first
|
||||
* entry to dump. next entry is read from the output
|
||||
* bufferbyte offset 0x8.
|
||||
*/
|
||||
if (*ppos) {
|
||||
info_offset = *(u64 *)(htm_info_data + 0x8);
|
||||
if (info_offset == -1)
|
||||
return 0;
|
||||
}
|
||||
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
|
||||
htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_buf),
|
||||
PAGE_SIZE, 0);
|
||||
htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_data),
|
||||
PAGE_SIZE, be64_to_cpu(info_offset));
|
||||
|
||||
ret = htm_return_check(rc);
|
||||
if (ret <= 0) {
|
||||
|
|
@ -301,15 +386,17 @@ static ssize_t htminfo_read(struct file *filp, char __user *ubuf,
|
|||
* So total count to copy is:
|
||||
* 32 bytes (for first 5 fields) + (number of HTM entries * entry size)
|
||||
*/
|
||||
num_entries = htm_info_buf + 0x10;
|
||||
num_entries = htm_info_data + 0x10;
|
||||
to_copy = 32 + (be64_to_cpu(*num_entries) * 16);
|
||||
return simple_read_from_buffer(ubuf, count, ppos, htm_info_buf, to_copy);
|
||||
|
||||
*ppos += to_copy;
|
||||
return simple_read_from_buffer(ubuf, count, &offset, htm_info_data, to_copy);
|
||||
}
|
||||
|
||||
static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
void *htm_caps_buf = filp->private_data;
|
||||
void *htm_caps_data = filp->private_data;
|
||||
long rc, ret;
|
||||
|
||||
/*
|
||||
|
|
@ -319,7 +406,7 @@ static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
|
|||
* and zero
|
||||
*/
|
||||
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
|
||||
htmtype, H_HTM_OP_CAPABILITIES, virt_to_phys(htm_caps_buf),
|
||||
htmtype, H_HTM_OP_CAPABILITIES, virt_to_phys(htm_caps_data),
|
||||
0x80, 0);
|
||||
|
||||
ret = htm_return_check(rc);
|
||||
|
|
@ -328,7 +415,7 @@ static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
|
|||
return ret;
|
||||
}
|
||||
|
||||
return simple_read_from_buffer(ubuf, count, ppos, htm_caps_buf, 0x80);
|
||||
return simple_read_from_buffer(ubuf, count, ppos, htm_caps_data, 0x80);
|
||||
}
|
||||
|
||||
static const struct file_operations htminfo_fops = {
|
||||
|
|
@ -457,9 +544,17 @@ static int htmdump_init_debugfs(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Memory to present HTM system memory configuration */
|
||||
htm_mem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!htm_mem_buf) {
|
||||
pr_err("Failed to allocate htm mem buf\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops);
|
||||
debugfs_create_file("htminfo", 0400, htmdump_debugfs_dir, htm_info_buf, &htminfo_fops);
|
||||
debugfs_create_file("htmcaps", 0400, htmdump_debugfs_dir, htm_caps_buf, &htmcaps_fops);
|
||||
debugfs_create_file("htmsystem_mem", 0400, htmdump_debugfs_dir, htm_mem_buf, &htmsystem_mem_fops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -482,6 +577,10 @@ static void __exit htmdump_exit(void)
|
|||
{
|
||||
debugfs_remove_recursive(htmdump_debugfs_dir);
|
||||
kfree(htm_buf);
|
||||
kfree(htm_status_buf);
|
||||
kfree(htm_info_buf);
|
||||
kfree(htm_caps_buf);
|
||||
kfree(htm_mem_buf);
|
||||
}
|
||||
|
||||
module_init(htmdump_init);
|
||||
|
|
|
|||
|
|
@ -190,33 +190,34 @@ static int hvpipe_rtas_recv_msg(char __user *buf, int size)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID,
|
||||
&bytes_written);
|
||||
if (!ret) {
|
||||
/*
|
||||
* Recv HVPIPE RTAS is successful.
|
||||
* When releasing FD or no one is waiting on the
|
||||
* specific source, issue recv HVPIPE RTAS call
|
||||
* so that pipe is not blocked - this func is called
|
||||
* with NULL buf.
|
||||
*/
|
||||
if (buf) {
|
||||
if (size < bytes_written) {
|
||||
pr_err("Received the payload size = %d, but the buffer size = %d\n",
|
||||
bytes_written, size);
|
||||
bytes_written = size;
|
||||
}
|
||||
ret = copy_to_user(buf,
|
||||
rtas_work_area_raw_buf(work_area),
|
||||
bytes_written);
|
||||
if (!ret)
|
||||
ret = bytes_written;
|
||||
}
|
||||
} else {
|
||||
pr_err("ibm,receive-hvpipe-msg failed with %d\n",
|
||||
ret);
|
||||
/*
|
||||
* Recv HVPIPE RTAS is successful.
|
||||
* When releasing FD or no one is waiting on the
|
||||
* specific source, issue recv HVPIPE RTAS call
|
||||
* so that pipe is not blocked - this func is called
|
||||
* with NULL buf.
|
||||
*/
|
||||
ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID, &bytes_written);
|
||||
if (ret) {
|
||||
pr_err("ibm,receive-hvpipe-msg failed with %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!buf)
|
||||
goto out;
|
||||
|
||||
if (size < bytes_written) {
|
||||
pr_err("Received the payload size = %d, but the buffer size = %d\n",
|
||||
bytes_written, size);
|
||||
bytes_written = size;
|
||||
}
|
||||
|
||||
if (copy_to_user(buf, rtas_work_area_raw_buf(work_area), bytes_written))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = bytes_written;
|
||||
|
||||
out:
|
||||
rtas_work_area_free(work_area);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -327,8 +328,8 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
|
|||
{
|
||||
|
||||
struct hvpipe_source_info *src_info = file->private_data;
|
||||
struct papr_hvpipe_hdr hdr;
|
||||
long ret;
|
||||
struct papr_hvpipe_hdr hdr = {};
|
||||
ssize_t ret = 0;
|
||||
|
||||
/*
|
||||
* Return -ENXIO during migration
|
||||
|
|
@ -376,7 +377,7 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
|
|||
|
||||
ret = copy_to_user(buf, &hdr, HVPIPE_HDR_LEN);
|
||||
if (ret)
|
||||
return ret;
|
||||
return -EFAULT;
|
||||
|
||||
/*
|
||||
* Message event has payload, so get the payload with
|
||||
|
|
@ -385,19 +386,23 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
|
|||
if (hdr.flags & HVPIPE_MSG_AVAILABLE) {
|
||||
ret = hvpipe_rtas_recv_msg(buf + HVPIPE_HDR_LEN,
|
||||
size - HVPIPE_HDR_LEN);
|
||||
if (ret > 0) {
|
||||
/*
|
||||
* Always clear MSG_AVAILABLE once the RTAS call has drained
|
||||
* the message, regardless of whether copy_to_user succeeded.
|
||||
*/
|
||||
if (ret >= 0 || ret == -EFAULT)
|
||||
src_info->hvpipe_status &= ~HVPIPE_MSG_AVAILABLE;
|
||||
ret += HVPIPE_HDR_LEN;
|
||||
}
|
||||
} else if (hdr.flags & HVPIPE_LOST_CONNECTION) {
|
||||
/*
|
||||
* Hypervisor is closing the pipe for the specific
|
||||
* source. So notify user space.
|
||||
*/
|
||||
src_info->hvpipe_status &= ~HVPIPE_LOST_CONNECTION;
|
||||
ret = HVPIPE_HDR_LEN;
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
ret += HVPIPE_HDR_LEN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -444,16 +449,18 @@ static int papr_hvpipe_handle_release(struct inode *inode,
|
|||
struct file *file)
|
||||
{
|
||||
struct hvpipe_source_info *src_info;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Hold the lock, remove source from src_list, reset the
|
||||
* hvpipe status and release the lock to prevent any race
|
||||
* with message event IRQ.
|
||||
*/
|
||||
spin_lock(&hvpipe_src_list_lock);
|
||||
spin_lock_irqsave(&hvpipe_src_list_lock, flags);
|
||||
src_info = file->private_data;
|
||||
list_del(&src_info->list);
|
||||
file->private_data = NULL;
|
||||
spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
|
||||
/*
|
||||
* If the pipe for this specific source has any pending
|
||||
* payload, issue recv HVPIPE RTAS so that pipe will not
|
||||
|
|
@ -461,10 +468,8 @@ static int papr_hvpipe_handle_release(struct inode *inode,
|
|||
*/
|
||||
if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE) {
|
||||
src_info->hvpipe_status = 0;
|
||||
spin_unlock(&hvpipe_src_list_lock);
|
||||
hvpipe_rtas_recv_msg(NULL, 0);
|
||||
} else
|
||||
spin_unlock(&hvpipe_src_list_lock);
|
||||
}
|
||||
|
||||
kfree(src_info);
|
||||
return 0;
|
||||
|
|
@ -479,50 +484,53 @@ static const struct file_operations papr_hvpipe_handle_ops = {
|
|||
|
||||
static int papr_hvpipe_dev_create_handle(u32 srcID)
|
||||
{
|
||||
struct hvpipe_source_info *src_info __free(kfree) = NULL;
|
||||
|
||||
spin_lock(&hvpipe_src_list_lock);
|
||||
/*
|
||||
* Do not allow more than one process communicates with
|
||||
* each source.
|
||||
*/
|
||||
src_info = hvpipe_find_source(srcID);
|
||||
if (src_info) {
|
||||
spin_unlock(&hvpipe_src_list_lock);
|
||||
pr_err("pid(%d) is already using the source(%d)\n",
|
||||
src_info->tsk->pid, srcID);
|
||||
return -EALREADY;
|
||||
}
|
||||
spin_unlock(&hvpipe_src_list_lock);
|
||||
struct hvpipe_source_info *src_info;
|
||||
int fd;
|
||||
unsigned long flags;
|
||||
|
||||
src_info = kzalloc_obj(*src_info, GFP_KERNEL_ACCOUNT);
|
||||
if (!src_info)
|
||||
return -ENOMEM;
|
||||
|
||||
src_info->srcID = srcID;
|
||||
src_info->tsk = current;
|
||||
init_waitqueue_head(&src_info->recv_wqh);
|
||||
|
||||
FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC,
|
||||
anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops,
|
||||
(void *)src_info, O_RDWR));
|
||||
if (fdf.err)
|
||||
return fdf.err;
|
||||
|
||||
retain_and_null_ptr(src_info);
|
||||
spin_lock(&hvpipe_src_list_lock);
|
||||
/*
|
||||
* If two processes are executing ioctl() for the same
|
||||
* source ID concurrently, prevent the second process to
|
||||
* acquire FD.
|
||||
* Do not allow more than one process communicates with
|
||||
* each source.
|
||||
*/
|
||||
spin_lock_irqsave(&hvpipe_src_list_lock, flags);
|
||||
if (hvpipe_find_source(srcID)) {
|
||||
spin_unlock(&hvpipe_src_list_lock);
|
||||
spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
|
||||
pr_err("pid(%s:%d) could not get the source(%d)\n",
|
||||
current->comm, task_pid_nr(current), srcID);
|
||||
kfree(src_info);
|
||||
return -EALREADY;
|
||||
}
|
||||
list_add(&src_info->list, &hvpipe_src_list);
|
||||
spin_unlock(&hvpipe_src_list_lock);
|
||||
return fd_publish(fdf);
|
||||
spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
|
||||
|
||||
fd = FD_ADD(O_RDONLY | O_CLOEXEC,
|
||||
anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops,
|
||||
(void *)src_info, O_RDWR));
|
||||
if (fd < 0) {
|
||||
spin_lock_irqsave(&hvpipe_src_list_lock, flags);
|
||||
list_del(&src_info->list);
|
||||
spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
|
||||
/*
|
||||
* if we fail to add FD, that means no userspace program is
|
||||
* polling. In that case if there is a msg pending because the
|
||||
* interrupt was fired after the src_info was added to the
|
||||
* global list, then let's consume it here, to unblock the
|
||||
* hvpipe
|
||||
*/
|
||||
if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE)
|
||||
hvpipe_rtas_recv_msg(NULL, 0);
|
||||
kfree(src_info);
|
||||
return fd;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -685,20 +693,19 @@ static int __init enable_hvpipe_IRQ(void)
|
|||
struct device_node *np;
|
||||
|
||||
hvpipe_check_exception_token = rtas_function_token(RTAS_FN_CHECK_EXCEPTION);
|
||||
if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE)
|
||||
if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE)
|
||||
return -ENODEV;
|
||||
|
||||
/* hvpipe events */
|
||||
np = of_find_node_by_path("/event-sources/ibm,hvpipe-msg-events");
|
||||
if (np != NULL) {
|
||||
request_event_sources_irqs(np, hvpipe_event_interrupt,
|
||||
"HPIPE_EVENT");
|
||||
of_node_put(np);
|
||||
} else {
|
||||
pr_err("Can not enable hvpipe event IRQ\n");
|
||||
if (!np) {
|
||||
pr_err("No device node found, could not enable hvpipe event IRQ\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
request_event_sources_irqs(np, hvpipe_event_interrupt, "HPIPE_EVENT");
|
||||
of_node_put(np);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -775,23 +782,29 @@ static int __init papr_hvpipe_init(void)
|
|||
}
|
||||
|
||||
ret = enable_hvpipe_IRQ();
|
||||
if (!ret) {
|
||||
ret = set_hvpipe_sys_param(1);
|
||||
if (!ret)
|
||||
ret = misc_register(&papr_hvpipe_dev);
|
||||
}
|
||||
if (ret)
|
||||
goto out_wq;
|
||||
|
||||
if (!ret) {
|
||||
pr_info("hvpipe feature is enabled\n");
|
||||
hvpipe_feature = true;
|
||||
return 0;
|
||||
}
|
||||
ret = misc_register(&papr_hvpipe_dev);
|
||||
if (ret)
|
||||
goto out_wq;
|
||||
|
||||
pr_err("hvpipe feature is not enabled %d\n", ret);
|
||||
ret = set_hvpipe_sys_param(1);
|
||||
if (ret)
|
||||
goto out_misc;
|
||||
|
||||
pr_info("hvpipe feature is enabled\n");
|
||||
hvpipe_feature = true;
|
||||
return 0;
|
||||
|
||||
out_misc:
|
||||
misc_deregister(&papr_hvpipe_dev);
|
||||
out_wq:
|
||||
destroy_workqueue(papr_hvpipe_wq);
|
||||
out:
|
||||
kfree(papr_hvpipe_work);
|
||||
papr_hvpipe_work = NULL;
|
||||
pr_err("hvpipe feature is not enabled %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
machine_device_initcall(pseries, papr_hvpipe_init);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ struct hvpipe_source_info {
|
|||
u32 srcID;
|
||||
u32 hvpipe_status;
|
||||
wait_queue_head_t recv_wqh; /* wake up poll() waitq */
|
||||
struct task_struct *tsk;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1414,6 +1414,9 @@ static inline char *debug_get_user_string(const char __user *user_buf,
|
|||
{
|
||||
char *buffer;
|
||||
|
||||
if (!user_len)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
buffer = memdup_user_nul(user_buf, user_len);
|
||||
if (IS_ERR(buffer))
|
||||
return buffer;
|
||||
|
|
@ -1584,6 +1587,11 @@ static int debug_input_flush_fn(debug_info_t *id, struct debug_view *view,
|
|||
char input_buf[1];
|
||||
int rc = user_len;
|
||||
|
||||
if (!user_len) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (user_len > 0x10000)
|
||||
user_len = 0x10000;
|
||||
if (*offset != 0) {
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ void do_secure_storage_access(struct pt_regs *regs)
|
|||
panic("Unexpected PGM 0x3d with TEID bit 61=0");
|
||||
}
|
||||
if (is_kernel_fault(regs)) {
|
||||
folio = phys_to_folio(addr);
|
||||
folio = virt_to_folio((void *)addr);
|
||||
if (unlikely(!folio_try_get(folio)))
|
||||
return;
|
||||
rc = uv_convert_from_secure(folio_to_phys(folio));
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
/*
|
||||
* This is set up by the setup-routine at boot-time
|
||||
*/
|
||||
extern unsigned char *boot_params_page;
|
||||
extern unsigned char boot_params_page[];
|
||||
#define PARAM boot_params_page
|
||||
|
||||
#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000))
|
||||
|
|
|
|||
|
|
@ -1294,13 +1294,16 @@ int x86_perf_rdpmc_index(struct perf_event *event)
|
|||
return event->hw.event_base_rdpmc;
|
||||
}
|
||||
|
||||
static inline int match_prev_assignment(struct hw_perf_event *hwc,
|
||||
static inline int match_prev_assignment(struct perf_event *event,
|
||||
struct cpu_hw_events *cpuc,
|
||||
int i)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
|
||||
return hwc->idx == cpuc->assign[i] &&
|
||||
hwc->last_cpu == smp_processor_id() &&
|
||||
hwc->last_tag == cpuc->tags[i];
|
||||
hwc->last_cpu == smp_processor_id() &&
|
||||
hwc->last_tag == cpuc->tags[i] &&
|
||||
!is_acr_event_group(event);
|
||||
}
|
||||
|
||||
static void x86_pmu_start(struct perf_event *event, int flags);
|
||||
|
|
@ -1346,7 +1349,7 @@ static void x86_pmu_enable(struct pmu *pmu)
|
|||
* - no other event has used the counter since
|
||||
*/
|
||||
if (hwc->idx == -1 ||
|
||||
match_prev_assignment(hwc, cpuc, i))
|
||||
match_prev_assignment(event, cpuc, i))
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
|
@ -1367,7 +1370,7 @@ static void x86_pmu_enable(struct pmu *pmu)
|
|||
event = cpuc->event_list[i];
|
||||
hwc = &event->hw;
|
||||
|
||||
if (!match_prev_assignment(hwc, cpuc, i))
|
||||
if (!match_prev_assignment(event, cpuc, i))
|
||||
x86_assign_hw_event(event, cpuc, i);
|
||||
else if (i < n_running)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -3118,11 +3118,11 @@ static void intel_pmu_enable_fixed(struct perf_event *event)
|
|||
intel_set_masks(event, idx);
|
||||
|
||||
/*
|
||||
* Enable IRQ generation (0x8), if not PEBS,
|
||||
* and enable ring-3 counting (0x2) and ring-0 counting (0x1)
|
||||
* if requested:
|
||||
* Enable IRQ generation (0x8), if not PEBS or self-reloaded
|
||||
* ACR event, and enable ring-3 counting (0x2) and ring-0
|
||||
* counting (0x1) if requested:
|
||||
*/
|
||||
if (!event->attr.precise_ip)
|
||||
if (!event->attr.precise_ip && !is_acr_self_reload_event(event))
|
||||
bits |= INTEL_FIXED_0_ENABLE_PMI;
|
||||
if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
|
||||
bits |= INTEL_FIXED_0_USER;
|
||||
|
|
@ -3306,6 +3306,15 @@ static void intel_pmu_enable_event(struct perf_event *event)
|
|||
intel_set_masks(event, idx);
|
||||
static_call_cond(intel_pmu_enable_acr_event)(event);
|
||||
static_call_cond(intel_pmu_enable_event_ext)(event);
|
||||
/*
|
||||
* For self-reloaded ACR event, don't enable PMI since
|
||||
* HW won't set overflow bit in GLOBAL_STATUS. Otherwise,
|
||||
* the PMI would be recognized as a suspicious NMI.
|
||||
*/
|
||||
if (is_acr_self_reload_event(event))
|
||||
hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
|
||||
else if (!event->attr.precise_ip)
|
||||
hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
|
||||
__x86_pmu_enable_event(hwc, enable_mask);
|
||||
break;
|
||||
case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS - 1:
|
||||
|
|
@ -3332,23 +3341,41 @@ static void intel_pmu_enable_event(struct perf_event *event)
|
|||
static void intel_pmu_acr_late_setup(struct cpu_hw_events *cpuc)
|
||||
{
|
||||
struct perf_event *event, *leader;
|
||||
int i, j, idx;
|
||||
int i, j, k, bit, idx;
|
||||
|
||||
/*
|
||||
* FIXME: ACR mask parsing relies on cpuc->event_list[] (active events only).
|
||||
* Disabling an ACR event causes bit-shifting errors in the acr_mask of
|
||||
* remaining group members. As ACR sampling requires all events to be active,
|
||||
* this limitation is acceptable for now. Revisit if independent event toggling
|
||||
* is required.
|
||||
*/
|
||||
for (i = 0; i < cpuc->n_events; i++) {
|
||||
leader = cpuc->event_list[i];
|
||||
if (!is_acr_event_group(leader))
|
||||
continue;
|
||||
|
||||
/* The ACR events must be contiguous. */
|
||||
/* Find the last event of the ACR group. */
|
||||
for (j = i; j < cpuc->n_events; j++) {
|
||||
event = cpuc->event_list[j];
|
||||
if (event->group_leader != leader->group_leader)
|
||||
break;
|
||||
for_each_set_bit(idx, (unsigned long *)&event->attr.config2, X86_PMC_IDX_MAX) {
|
||||
if (i + idx >= cpuc->n_events ||
|
||||
!is_acr_event_group(cpuc->event_list[i + idx]))
|
||||
return;
|
||||
__set_bit(cpuc->assign[i + idx], (unsigned long *)&event->hw.config1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate the user-space ACR mask (attr.config2) into the physical
|
||||
* counter bitmask (hw.config1) for each ACR event in the group.
|
||||
* NOTE: ACR event contiguity is guaranteed by intel_pmu_hw_config().
|
||||
*/
|
||||
for (k = i; k < j; k++) {
|
||||
event = cpuc->event_list[k];
|
||||
event->hw.config1 = 0;
|
||||
for_each_set_bit(bit, (unsigned long *)&event->attr.config2, X86_PMC_IDX_MAX) {
|
||||
idx = i + bit;
|
||||
/* Event index of ACR group must locate in [i, j). */
|
||||
if (idx >= j || !is_acr_event_group(cpuc->event_list[idx]))
|
||||
continue;
|
||||
__set_bit(cpuc->assign[idx], (unsigned long *)&event->hw.config1);
|
||||
}
|
||||
}
|
||||
i = j - 1;
|
||||
|
|
@ -7504,6 +7531,7 @@ static __always_inline void intel_pmu_init_pnc(struct pmu *pmu)
|
|||
hybrid(pmu, event_constraints) = intel_pnc_event_constraints;
|
||||
hybrid(pmu, pebs_constraints) = intel_pnc_pebs_event_constraints;
|
||||
hybrid(pmu, extra_regs) = intel_pnc_extra_regs;
|
||||
static_call_update(intel_pmu_enable_acr_event, intel_pmu_enable_acr);
|
||||
}
|
||||
|
||||
static __always_inline void intel_pmu_init_skt(struct pmu *pmu)
|
||||
|
|
|
|||
|
|
@ -137,6 +137,16 @@ static inline bool is_acr_event_group(struct perf_event *event)
|
|||
return check_leader_group(event->group_leader, PERF_X86_EVENT_ACR);
|
||||
}
|
||||
|
||||
static inline bool is_acr_self_reload_event(struct perf_event *event)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
|
||||
if (hwc->idx < 0)
|
||||
return false;
|
||||
|
||||
return test_bit(hwc->idx, (unsigned long *)&hwc->config1);
|
||||
}
|
||||
|
||||
struct amd_nb {
|
||||
int nb_id; /* NorthBridge id */
|
||||
int refcnt; /* reference count */
|
||||
|
|
|
|||
|
|
@ -137,7 +137,8 @@ extern void __init efi_dump_pagetable(void);
|
|||
extern void __init efi_apply_memmap_quirks(void);
|
||||
extern int __init efi_reuse_config(u64 tables, int nr_tables);
|
||||
extern void efi_delete_dummy_variable(void);
|
||||
extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr);
|
||||
extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr,
|
||||
const struct pt_regs *regs);
|
||||
extern void efi_unmap_boot_services(void);
|
||||
|
||||
void arch_efi_call_virt_setup(void);
|
||||
|
|
|
|||
|
|
@ -450,6 +450,10 @@ __init static int append_e820_table(struct boot_e820_entry *entries, u32 nr_entr
|
|||
{
|
||||
struct boot_e820_entry *entry = entries;
|
||||
|
||||
/* If there aren't any entries, we'll want to fall back to another source: */
|
||||
if (!nr_entries)
|
||||
return -ENOENT;
|
||||
|
||||
while (nr_entries) {
|
||||
u64 start = entry->addr;
|
||||
u64 size = entry->size;
|
||||
|
|
@ -458,7 +462,7 @@ __init static int append_e820_table(struct boot_e820_entry *entries, u32 nr_entr
|
|||
|
||||
/* Ignore the remaining entries on 64-bit overflow: */
|
||||
if (start > end && likely(size))
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
|
||||
e820__range_add(start, size, type);
|
||||
|
||||
|
|
|
|||
|
|
@ -2040,7 +2040,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
|||
* flush). Translate the address here so the memory can be uniformly
|
||||
* read with kvm_read_guest().
|
||||
*/
|
||||
if (!hc->fast && is_guest_mode(vcpu)) {
|
||||
if (!hc->fast && mmu_is_nested(vcpu)) {
|
||||
hc->ingpa = translate_nested_gpa(vcpu, hc->ingpa, 0, NULL);
|
||||
if (unlikely(hc->ingpa == INVALID_GPA))
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
|
|
|
|||
|
|
@ -667,13 +667,15 @@ bool __kvm_apic_update_irr(unsigned long *pir, void *regs, int *max_irr)
|
|||
u32 *__pir = (void *)pir_vals;
|
||||
u32 i, vec;
|
||||
u32 irr_val, prev_irr_val;
|
||||
int max_updated_irr;
|
||||
int max_new_irr;
|
||||
|
||||
max_updated_irr = -1;
|
||||
*max_irr = -1;
|
||||
|
||||
if (!pi_harvest_pir(pir, pir_vals))
|
||||
if (!pi_harvest_pir(pir, pir_vals)) {
|
||||
*max_irr = apic_find_highest_vector(regs + APIC_IRR);
|
||||
return false;
|
||||
}
|
||||
|
||||
max_new_irr = -1;
|
||||
*max_irr = -1;
|
||||
|
||||
for (i = vec = 0; i <= 7; i++, vec += 32) {
|
||||
u32 *p_irr = (u32 *)(regs + APIC_IRR + i * 0x10);
|
||||
|
|
@ -688,25 +690,25 @@ bool __kvm_apic_update_irr(unsigned long *pir, void *regs, int *max_irr)
|
|||
!try_cmpxchg(p_irr, &prev_irr_val, irr_val));
|
||||
|
||||
if (prev_irr_val != irr_val)
|
||||
max_updated_irr = __fls(irr_val ^ prev_irr_val) + vec;
|
||||
max_new_irr = __fls(irr_val ^ prev_irr_val) + vec;
|
||||
}
|
||||
if (irr_val)
|
||||
*max_irr = __fls(irr_val) + vec;
|
||||
}
|
||||
|
||||
return ((max_updated_irr != -1) &&
|
||||
(max_updated_irr == *max_irr));
|
||||
return max_new_irr != -1 && max_new_irr == *max_irr;
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM_INTERNAL(__kvm_apic_update_irr);
|
||||
|
||||
bool kvm_apic_update_irr(struct kvm_vcpu *vcpu, unsigned long *pir, int *max_irr)
|
||||
{
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
bool irr_updated = __kvm_apic_update_irr(pir, apic->regs, max_irr);
|
||||
bool max_irr_is_from_pir;
|
||||
|
||||
if (unlikely(!apic->apicv_active && irr_updated))
|
||||
max_irr_is_from_pir = __kvm_apic_update_irr(pir, apic->regs, max_irr);
|
||||
if (unlikely(!apic->apicv_active && max_irr_is_from_pir))
|
||||
apic->irr_pending = true;
|
||||
return irr_updated;
|
||||
return max_irr_is_from_pir;
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_apic_update_irr);
|
||||
|
||||
|
|
|
|||
|
|
@ -182,6 +182,8 @@ static struct kmem_cache *pte_list_desc_cache;
|
|||
struct kmem_cache *mmu_page_header_cache;
|
||||
|
||||
static void mmu_spte_set(u64 *sptep, u64 spte);
|
||||
static int mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp,
|
||||
u64 *spte, struct list_head *invalid_list);
|
||||
|
||||
struct kvm_mmu_role_regs {
|
||||
const unsigned long cr0;
|
||||
|
|
@ -1287,19 +1289,6 @@ static void drop_spte(struct kvm *kvm, u64 *sptep)
|
|||
rmap_remove(kvm, sptep);
|
||||
}
|
||||
|
||||
static void drop_large_spte(struct kvm *kvm, u64 *sptep, bool flush)
|
||||
{
|
||||
struct kvm_mmu_page *sp;
|
||||
|
||||
sp = sptep_to_sp(sptep);
|
||||
WARN_ON_ONCE(sp->role.level == PG_LEVEL_4K);
|
||||
|
||||
drop_spte(kvm, sptep);
|
||||
|
||||
if (flush)
|
||||
kvm_flush_remote_tlbs_sptep(kvm, sptep);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write-protect on the specified @sptep, @pt_protect indicates whether
|
||||
* spte write-protection is caused by protecting shadow page table.
|
||||
|
|
@ -2466,7 +2455,8 @@ static struct kvm_mmu_page *kvm_mmu_get_child_sp(struct kvm_vcpu *vcpu,
|
|||
{
|
||||
union kvm_mmu_page_role role;
|
||||
|
||||
if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
|
||||
if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep) &&
|
||||
spte_to_child_sp(*sptep) && spte_to_child_sp(*sptep)->gfn == gfn)
|
||||
return ERR_PTR(-EEXIST);
|
||||
|
||||
role = kvm_mmu_child_role(sptep, direct, access);
|
||||
|
|
@ -2544,13 +2534,16 @@ static void __link_shadow_page(struct kvm *kvm,
|
|||
|
||||
BUILD_BUG_ON(VMX_EPT_WRITABLE_MASK != PT_WRITABLE_MASK);
|
||||
|
||||
/*
|
||||
* If an SPTE is present already, it must be a leaf and therefore
|
||||
* a large one. Drop it, and flush the TLB if needed, before
|
||||
* installing sp.
|
||||
*/
|
||||
if (is_shadow_present_pte(*sptep))
|
||||
drop_large_spte(kvm, sptep, flush);
|
||||
if (is_shadow_present_pte(*sptep)) {
|
||||
struct kvm_mmu_page *parent_sp;
|
||||
LIST_HEAD(invalid_list);
|
||||
|
||||
parent_sp = sptep_to_sp(sptep);
|
||||
WARN_ON_ONCE(parent_sp->role.level == PG_LEVEL_4K);
|
||||
|
||||
mmu_page_zap_pte(kvm, parent_sp, sptep, &invalid_list);
|
||||
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, true);
|
||||
}
|
||||
|
||||
spte = make_nonleaf_spte(sp->spt, sp_ad_disabled(sp));
|
||||
|
||||
|
|
|
|||
|
|
@ -7029,8 +7029,8 @@ static void vmx_set_rvi(int vector)
|
|||
int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_vt *vt = to_vt(vcpu);
|
||||
bool max_irr_is_from_pir;
|
||||
int max_irr;
|
||||
bool got_posted_interrupt;
|
||||
|
||||
if (KVM_BUG_ON(!enable_apicv, vcpu->kvm))
|
||||
return -EIO;
|
||||
|
|
@ -7042,17 +7042,22 @@ int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
|
|||
* But on x86 this is just a compiler barrier anyway.
|
||||
*/
|
||||
smp_mb__after_atomic();
|
||||
got_posted_interrupt =
|
||||
kvm_apic_update_irr(vcpu, vt->pi_desc.pir, &max_irr);
|
||||
max_irr_is_from_pir = kvm_apic_update_irr(vcpu, vt->pi_desc.pir,
|
||||
&max_irr);
|
||||
} else {
|
||||
max_irr = kvm_lapic_find_highest_irr(vcpu);
|
||||
got_posted_interrupt = false;
|
||||
max_irr_is_from_pir = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Newly recognized interrupts are injected via either virtual interrupt
|
||||
* delivery (RVI) or KVM_REQ_EVENT. Virtual interrupt delivery is
|
||||
* disabled in two cases:
|
||||
* If APICv is enabled and L2 is not active, then update the Requesting
|
||||
* Virtual Interrupt (RVI) portion of vmcs01.GUEST_INTR_STATUS with the
|
||||
* highest priority IRR to deliver the IRQ via Virtual Interrupt
|
||||
* Delivery. Note, this is required even if the highest priority IRQ
|
||||
* was already pending in the IRR, as RVI isn't updated in lockstep with
|
||||
* the IRR (unlike apic->irr_pending).
|
||||
*
|
||||
* For the cases where Virtual Interrupt Delivery can't be used:
|
||||
*
|
||||
* 1) If L2 is running and the vCPU has a new pending interrupt. If L1
|
||||
* wants to exit on interrupts, KVM_REQ_EVENT is needed to synthesize a
|
||||
|
|
@ -7063,10 +7068,29 @@ int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
|
|||
* 2) If APICv is disabled for this vCPU, assigned devices may still
|
||||
* attempt to post interrupts. The posted interrupt vector will cause
|
||||
* a VM-Exit and the subsequent entry will call sync_pir_to_irr.
|
||||
*
|
||||
* In both cases, set KVM_REQ_EVENT if and only if the highest priority
|
||||
* pending IRQ came from the PIR, as setting KVM_REQ_EVENT if any IRQ
|
||||
* is pending may put the vCPU into an infinite loop, e.g. if the IRQ
|
||||
* is blocked, then it will stay pending until an IRQ window is opened.
|
||||
*
|
||||
* Note! It's possible that one or more IRQs were moved from the PIR
|
||||
* to the IRR _without_ max_irr_is_from_pir being true! I.e. if there
|
||||
* was a higher priority IRQ already pending in the IRR. Not setting
|
||||
* KVM_REQ_EVENT in this case is intentional and safe. If APICv is
|
||||
* inactive, or L2 is running with exit-on-interrupt off (in vmcs12),
|
||||
* i.e. without nested virtual interrupt delivery, then there's no need
|
||||
* to request an IRQ window as the lower priority IRQ only needs to be
|
||||
* delivered when the higher priority IRQ is dismissed from the ISR,
|
||||
* i.e. on the next EOI, and EOIs are always intercepted if APICv is
|
||||
* disabled or if L2 is running without nested VID. If L2 is running
|
||||
* exit-on-interrupt on (in vmcs12), then the higher priority IRQ will
|
||||
* trigger a nested VM-Exit, at which point KVM will re-evaluate L1's
|
||||
* pending IRQs.
|
||||
*/
|
||||
if (!is_guest_mode(vcpu) && kvm_vcpu_apicv_active(vcpu))
|
||||
vmx_set_rvi(max_irr);
|
||||
else if (got_posted_interrupt)
|
||||
else if (max_irr_is_from_pir)
|
||||
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
||||
|
||||
return max_irr;
|
||||
|
|
|
|||
|
|
@ -686,7 +686,7 @@ page_fault_oops(struct pt_regs *regs, unsigned long error_code,
|
|||
* avoid hanging the system.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_EFI))
|
||||
efi_crash_gracefully_on_page_fault(address);
|
||||
efi_crash_gracefully_on_page_fault(address, regs);
|
||||
|
||||
/* Only not-present faults should be handled by KFENCE. */
|
||||
if (!(error_code & X86_PF_PROT) &&
|
||||
|
|
|
|||
|
|
@ -761,7 +761,8 @@ int efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff,
|
|||
* @return: Returns, if the page fault is not handled. This function
|
||||
* will never return if the page fault is handled successfully.
|
||||
*/
|
||||
void efi_crash_gracefully_on_page_fault(unsigned long phys_addr)
|
||||
void efi_crash_gracefully_on_page_fault(unsigned long phys_addr,
|
||||
const struct pt_regs *regs)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_X86_64))
|
||||
return;
|
||||
|
|
@ -770,7 +771,7 @@ void efi_crash_gracefully_on_page_fault(unsigned long phys_addr)
|
|||
* If we get an interrupt/NMI while processing an EFI runtime service
|
||||
* then this is a regular OOPS, not an EFI failure.
|
||||
*/
|
||||
if (in_interrupt())
|
||||
if (!in_task())
|
||||
return;
|
||||
|
||||
/*
|
||||
|
|
@ -810,6 +811,14 @@ void efi_crash_gracefully_on_page_fault(unsigned long phys_addr)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The API does not permit entering a kernel mode FPU section with
|
||||
* interrupts enabled and leaving it with interrupts disabled. So
|
||||
* re-enable interrupts now if they were enabled when the page fault
|
||||
* occurred.
|
||||
*/
|
||||
local_irq_restore(regs->flags);
|
||||
|
||||
/*
|
||||
* Before calling EFI Runtime Service, the kernel has switched the
|
||||
* calling process to efi_mm. Hence, switch back to task_mm.
|
||||
|
|
|
|||
|
|
@ -695,17 +695,22 @@ static void __init xen_e820_resolve_conflicts(phys_addr_t start,
|
|||
return;
|
||||
|
||||
end = start + size;
|
||||
entry = xen_e820_table.entries;
|
||||
mapcnt = 0;
|
||||
|
||||
for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
|
||||
while (mapcnt < xen_e820_table.nr_entries) {
|
||||
entry = xen_e820_table.entries + mapcnt;
|
||||
if (entry->addr >= end)
|
||||
return;
|
||||
|
||||
if (entry->addr + entry->size > start &&
|
||||
entry->type == E820_TYPE_NVS)
|
||||
entry->type == E820_TYPE_NVS) {
|
||||
xen_e820_swap_entry_with_ram(entry);
|
||||
/* E820 map has been changed, restart loop! */
|
||||
mapcnt = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
entry++;
|
||||
mapcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -857,6 +857,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
|||
#endif
|
||||
|
||||
struct blk_iou_cmd {
|
||||
u64 start;
|
||||
u64 len;
|
||||
int res;
|
||||
bool nowait;
|
||||
};
|
||||
|
|
@ -946,23 +948,27 @@ int blkdev_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
|
|||
{
|
||||
struct block_device *bdev = I_BDEV(cmd->file->f_mapping->host);
|
||||
struct blk_iou_cmd *bic = io_uring_cmd_to_pdu(cmd, struct blk_iou_cmd);
|
||||
const struct io_uring_sqe *sqe = cmd->sqe;
|
||||
u32 cmd_op = cmd->cmd_op;
|
||||
uint64_t start, len;
|
||||
|
||||
if (unlikely(sqe->ioprio || sqe->__pad1 || sqe->len ||
|
||||
sqe->rw_flags || sqe->file_index))
|
||||
return -EINVAL;
|
||||
/* Read what we need from the SQE on the first issue */
|
||||
if (!(issue_flags & IORING_URING_CMD_REISSUE)) {
|
||||
const struct io_uring_sqe *sqe = cmd->sqe;
|
||||
|
||||
if (unlikely(sqe->ioprio || sqe->__pad1 || sqe->len ||
|
||||
sqe->rw_flags || sqe->file_index))
|
||||
return -EINVAL;
|
||||
|
||||
bic->start = READ_ONCE(sqe->addr);
|
||||
bic->len = READ_ONCE(sqe->addr3);
|
||||
}
|
||||
|
||||
bic->res = 0;
|
||||
bic->nowait = issue_flags & IO_URING_F_NONBLOCK;
|
||||
|
||||
start = READ_ONCE(sqe->addr);
|
||||
len = READ_ONCE(sqe->addr3);
|
||||
|
||||
switch (cmd_op) {
|
||||
case BLOCK_URING_CMD_DISCARD:
|
||||
return blkdev_cmd_discard(cmd, bdev, start, len, bic->nowait);
|
||||
return blkdev_cmd_discard(cmd, bdev, bic->start, bic->len,
|
||||
bic->nowait);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -390,6 +390,11 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
|
|||
auth = crypto_spawn_ahash_alg(&ctx->auth);
|
||||
auth_base = &auth->base;
|
||||
|
||||
if (auth->digestsize > 0 && auth->digestsize < 4) {
|
||||
err = -EINVAL;
|
||||
goto err_free_inst;
|
||||
}
|
||||
|
||||
err = crypto_grab_skcipher(&ctx->enc, aead_crypto_instance(inst),
|
||||
crypto_attr_alg_name(tb[2]), 0, mask);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -537,6 +537,26 @@ static const struct file_operations ivpu_fops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static int ivpu_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv,
|
||||
u32 handle, u32 flags, int *prime_fd)
|
||||
{
|
||||
struct drm_gem_object *obj;
|
||||
|
||||
obj = drm_gem_object_lookup(file_priv, handle);
|
||||
if (!obj)
|
||||
return -ENOENT;
|
||||
|
||||
if (drm_gem_is_imported(obj)) {
|
||||
/* Do not allow re-exporting */
|
||||
drm_gem_object_put(obj);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
drm_gem_object_put(obj);
|
||||
|
||||
return drm_gem_prime_handle_to_fd(dev, file_priv, handle, flags, prime_fd);
|
||||
}
|
||||
|
||||
static const struct drm_driver driver = {
|
||||
.driver_features = DRIVER_GEM | DRIVER_COMPUTE_ACCEL,
|
||||
|
||||
|
|
@ -545,6 +565,7 @@ static const struct drm_driver driver = {
|
|||
|
||||
.gem_create_object = ivpu_gem_create_object,
|
||||
.gem_prime_import = ivpu_gem_prime_import,
|
||||
.prime_handle_to_fd = ivpu_gem_prime_handle_to_fd,
|
||||
|
||||
.ioctls = ivpu_drm_ioctls,
|
||||
.num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls),
|
||||
|
|
|
|||
|
|
@ -497,11 +497,11 @@ static void decode_ras_msg(struct qaic_device *qdev, struct ras_data *msg)
|
|||
qdev->ce_count++;
|
||||
break;
|
||||
case UE:
|
||||
if (qdev->ce_count != UINT_MAX)
|
||||
if (qdev->ue_count != UINT_MAX)
|
||||
qdev->ue_count++;
|
||||
break;
|
||||
case UE_NF:
|
||||
if (qdev->ce_count != UINT_MAX)
|
||||
if (qdev->ue_nf_count != UINT_MAX)
|
||||
qdev->ue_nf_count++;
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -605,15 +605,12 @@ static umode_t acpi_tad_attr_is_visible(struct kobject *kobj,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct attribute_group acpi_tad_attr_group = {
|
||||
static const struct attribute_group acpi_tad_group = {
|
||||
.attrs = acpi_tad_attrs,
|
||||
.is_visible = acpi_tad_attr_is_visible,
|
||||
};
|
||||
|
||||
static const struct attribute_group *acpi_tad_attr_groups[] = {
|
||||
&acpi_tad_attr_group,
|
||||
NULL,
|
||||
};
|
||||
__ATTRIBUTE_GROUPS(acpi_tad);
|
||||
|
||||
#ifdef CONFIG_RTC_CLASS
|
||||
/* RTC class device interface */
|
||||
|
|
@ -683,9 +680,8 @@ static int acpi_tad_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
|
||||
acpi_tad_rt_to_tm(&rt, &tm_now);
|
||||
|
||||
value = ktime_divns(ktime_sub(rtc_tm_to_ktime(t->time),
|
||||
rtc_tm_to_ktime(tm_now)), NSEC_PER_SEC);
|
||||
if (value <= 0 || value > U32_MAX)
|
||||
value = rtc_tm_to_time64(&t->time) - rtc_tm_to_time64(&tm_now);
|
||||
if (value <= 0 || value >= U32_MAX)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -748,8 +744,7 @@ static int acpi_tad_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
|
||||
if (retval != ACPI_TAD_WAKE_DISABLED) {
|
||||
t->enabled = 1;
|
||||
t->time = rtc_ktime_to_tm(ktime_add_ns(rtc_tm_to_ktime(tm_now),
|
||||
(u64)retval * NSEC_PER_SEC));
|
||||
rtc_time64_to_tm(rtc_tm_to_time64(&tm_now) + retval, &t->time);
|
||||
} else {
|
||||
t->enabled = 0;
|
||||
t->time = tm_now;
|
||||
|
|
@ -795,9 +790,9 @@ static int acpi_tad_disable_timer(struct device *dev, u32 timer_id)
|
|||
return acpi_tad_wake_set(dev, "_STV", timer_id, ACPI_TAD_WAKE_DISABLED);
|
||||
}
|
||||
|
||||
static void acpi_tad_remove(struct platform_device *pdev)
|
||||
static void acpi_tad_remove(void *data)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device *dev = data;
|
||||
struct acpi_tad_driver_data *dd = dev_get_drvdata(dev);
|
||||
|
||||
device_init_wakeup(dev, false);
|
||||
|
|
@ -824,6 +819,7 @@ static int acpi_tad_probe(struct platform_device *pdev)
|
|||
struct acpi_tad_driver_data *dd;
|
||||
acpi_status status;
|
||||
unsigned long long caps;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Initialization failure messages are mostly about firmware issues, so
|
||||
|
|
@ -863,13 +859,21 @@ static int acpi_tad_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/*
|
||||
* The platform bus type layer tells the ACPI PM domain powers up the
|
||||
* device, so set the runtime PM status of it to "active".
|
||||
* The platform bus type probe callback tells the ACPI PM domain to
|
||||
* power up the device, so set the runtime PM status of it to "active".
|
||||
*/
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_suspend(dev);
|
||||
|
||||
/*
|
||||
* acpi_tad_remove() needs to run after unregistering the RTC class
|
||||
* device to avoid racing with the latter's callbacks.
|
||||
*/
|
||||
ret = devm_add_action_or_reset(&pdev->dev, acpi_tad_remove, &pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (caps & ACPI_TAD_RT)
|
||||
acpi_tad_register_rtc(dev, caps);
|
||||
|
||||
|
|
@ -885,10 +889,9 @@ static struct platform_driver acpi_tad_driver = {
|
|||
.driver = {
|
||||
.name = "acpi-tad",
|
||||
.acpi_match_table = acpi_tad_ids,
|
||||
.dev_groups = acpi_tad_attr_groups,
|
||||
.dev_groups = acpi_tad_groups,
|
||||
},
|
||||
.probe = acpi_tad_probe,
|
||||
.remove = acpi_tad_remove,
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, acpi_tad_ids);
|
||||
|
||||
|
|
|
|||
|
|
@ -401,8 +401,18 @@ static struct acpi_generic_address *einj_get_trigger_parameter_region(
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool is_memory_injection(u32 type, u32 flags)
|
||||
{
|
||||
if (flags & SETWA_FLAGS_EINJV2)
|
||||
return !!(type & ACPI_EINJV2_MEMORY);
|
||||
if (type & ACPI5_VENDOR_BIT)
|
||||
return !!(vendor_flags & SETWA_FLAGS_MEM);
|
||||
return !!(type & MEM_ERROR_MASK) || !!(flags & SETWA_FLAGS_MEM);
|
||||
}
|
||||
|
||||
/* Execute instructions in trigger error action table */
|
||||
static int __einj_error_trigger(u64 trigger_paddr, u32 type,
|
||||
static int __einj_error_trigger(u64 trigger_paddr, u32 type, u32 flags,
|
||||
u64 param1, u64 param2)
|
||||
{
|
||||
struct acpi_einj_trigger trigger_tab;
|
||||
|
|
@ -480,7 +490,7 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
|
|||
* This will cause resource conflict with regular memory. So
|
||||
* remove it from trigger table resources.
|
||||
*/
|
||||
if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) {
|
||||
if ((param_extension || acpi5) && is_memory_injection(type, flags)) {
|
||||
struct apei_resources addr_resources;
|
||||
|
||||
apei_resources_init(&addr_resources);
|
||||
|
|
@ -660,7 +670,7 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
|
|||
return rc;
|
||||
trigger_paddr = apei_exec_ctx_get_output(&ctx);
|
||||
if (notrigger == 0) {
|
||||
rc = __einj_error_trigger(trigger_paddr, type, param1, param2);
|
||||
rc = __einj_error_trigger(trigger_paddr, type, flags, param1, param2);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -718,28 +728,6 @@ int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, u64 param3,
|
|||
SETWA_FLAGS_PCIE_SBDF | SETWA_FLAGS_EINJV2)))
|
||||
return -EINVAL;
|
||||
|
||||
/* check if type is a valid EINJv2 error type */
|
||||
if (is_v2) {
|
||||
if (!(type & available_error_type_v2))
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
* We need extra sanity checks for memory errors.
|
||||
* Other types leap directly to injection.
|
||||
*/
|
||||
|
||||
/* ensure param1/param2 existed */
|
||||
if (!(param_extension || acpi5))
|
||||
goto inject;
|
||||
|
||||
/* ensure injection is memory related */
|
||||
if (type & ACPI5_VENDOR_BIT) {
|
||||
if (vendor_flags != SETWA_FLAGS_MEM)
|
||||
goto inject;
|
||||
} else if (!(type & MEM_ERROR_MASK) && !(flags & SETWA_FLAGS_MEM)) {
|
||||
goto inject;
|
||||
}
|
||||
|
||||
/*
|
||||
* Injections targeting a CXL 1.0/1.1 port have to be injected
|
||||
* via the einj_cxl_rch_error_inject() path as that does the proper
|
||||
|
|
@ -748,6 +736,23 @@ int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, u64 param3,
|
|||
if (einj_is_cxl_error_type(type) && (flags & SETWA_FLAGS_MEM))
|
||||
return -EINVAL;
|
||||
|
||||
/* check if type is a valid EINJv2 error type */
|
||||
if (is_v2) {
|
||||
if (!(type & available_error_type_v2))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* ensure param1/param2 existed */
|
||||
if (!(param_extension || acpi5))
|
||||
goto inject;
|
||||
|
||||
/*
|
||||
* We need extra sanity checks for memory errors.
|
||||
* Other types leap directly to injection.
|
||||
*/
|
||||
if (!is_memory_injection(type, flags))
|
||||
goto inject;
|
||||
|
||||
/*
|
||||
* Disallow crazy address masks that give BIOS leeway to pick
|
||||
* injection address almost anywhere. Insist on page or
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
static int psci_acpi_cpu_init_idle(unsigned int cpu)
|
||||
{
|
||||
int i, count;
|
||||
int i;
|
||||
struct acpi_lpi_state *lpi;
|
||||
struct acpi_processor *pr = per_cpu(processors, cpu);
|
||||
|
||||
|
|
@ -30,14 +30,10 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
|
|||
if (!psci_ops.cpu_suspend)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
count = pr->power.count - 1;
|
||||
if (count <= 0)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
for (i = 1; i < pr->power.count; i++) {
|
||||
u32 state;
|
||||
|
||||
lpi = &pr->power.lpi_states[i + 1];
|
||||
lpi = &pr->power.lpi_states[i];
|
||||
/*
|
||||
* Only bits[31:0] represent a PSCI power_state while
|
||||
* bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
|
|||
end:
|
||||
if (cmd == CMD_WRITE) {
|
||||
if (unlikely(ret)) {
|
||||
for_each_online_cpu(i) {
|
||||
for_each_possible_cpu(i) {
|
||||
struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i);
|
||||
|
||||
if (!desc)
|
||||
|
|
@ -524,13 +524,13 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
|
|||
else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
|
||||
cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
for_each_possible_cpu(i) {
|
||||
if (i == cpu)
|
||||
continue;
|
||||
|
||||
match_cpc_ptr = per_cpu(cpc_desc_ptr, i);
|
||||
if (!match_cpc_ptr)
|
||||
goto err_fault;
|
||||
continue;
|
||||
|
||||
match_pdomain = &(match_cpc_ptr->domain_info);
|
||||
if (match_pdomain->domain != pdomain->domain)
|
||||
|
|
|
|||
|
|
@ -916,6 +916,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "82K8"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* HP OMEN Gaming Laptop 16-n0xxx */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-n0xxx"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* x86 android tablets which directly control the backlight through
|
||||
|
|
|
|||
|
|
@ -204,7 +204,6 @@ pub(crate) fn reservation_abort(&mut self, offset: usize) -> Result<FreedRange>
|
|||
// caller will mark them as unused, which means that they can be freed if the system comes
|
||||
// under memory pressure.
|
||||
let mut freed_range = FreedRange::interior_pages(offset, size);
|
||||
#[expect(clippy::collapsible_if)] // reads better like this
|
||||
if offset % PAGE_SIZE != 0 {
|
||||
if i == 0 || self.ranges[i - 1].endpoint() <= (offset & PAGE_MASK) {
|
||||
freed_range.start_page_idx -= 1;
|
||||
|
|
|
|||
|
|
@ -459,19 +459,11 @@ static void pata_parport_dev_release(struct device *dev)
|
|||
kfree(pi);
|
||||
}
|
||||
|
||||
static void pata_parport_bus_release(struct device *dev)
|
||||
{
|
||||
/* nothing to do here but required to avoid warning on device removal */
|
||||
}
|
||||
|
||||
static const struct bus_type pata_parport_bus_type = {
|
||||
.name = DRV_NAME,
|
||||
};
|
||||
|
||||
static struct device pata_parport_bus = {
|
||||
.init_name = DRV_NAME,
|
||||
.release = pata_parport_bus_release,
|
||||
};
|
||||
static struct device *pata_parport_bus;
|
||||
|
||||
static const struct scsi_host_template pata_parport_sht = {
|
||||
PATA_PARPORT_SHT("pata_parport")
|
||||
|
|
@ -518,7 +510,7 @@ static struct pi_adapter *pi_init_one(struct parport *parport,
|
|||
}
|
||||
|
||||
/* set up pi->dev before pi_probe_unit() so it can use dev_printk() */
|
||||
pi->dev.parent = &pata_parport_bus;
|
||||
pi->dev.parent = pata_parport_bus;
|
||||
pi->dev.bus = &pata_parport_bus_type;
|
||||
pi->dev.driver = &pr->driver;
|
||||
pi->dev.release = pata_parport_dev_release;
|
||||
|
|
@ -780,8 +772,9 @@ static __init int pata_parport_init(void)
|
|||
return error;
|
||||
}
|
||||
|
||||
error = device_register(&pata_parport_bus);
|
||||
if (error) {
|
||||
pata_parport_bus = root_device_register(DRV_NAME);
|
||||
if (IS_ERR(pata_parport_bus)) {
|
||||
error = PTR_ERR(pata_parport_bus);
|
||||
pr_err("failed to register pata_parport bus, error: %d\n", error);
|
||||
goto out_unregister_bus;
|
||||
}
|
||||
|
|
@ -811,7 +804,7 @@ static __init int pata_parport_init(void)
|
|||
out_remove_new:
|
||||
bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
|
||||
out_unregister_dev:
|
||||
device_unregister(&pata_parport_bus);
|
||||
root_device_unregister(pata_parport_bus);
|
||||
out_unregister_bus:
|
||||
bus_unregister(&pata_parport_bus_type);
|
||||
return error;
|
||||
|
|
@ -822,7 +815,7 @@ static __exit void pata_parport_exit(void)
|
|||
parport_unregister_driver(&pata_parport_driver);
|
||||
bus_remove_file(&pata_parport_bus_type, &bus_attr_new_device);
|
||||
bus_remove_file(&pata_parport_bus_type, &bus_attr_delete_device);
|
||||
device_unregister(&pata_parport_bus);
|
||||
root_device_unregister(pata_parport_bus);
|
||||
bus_unregister(&pata_parport_bus_type);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ static int regmap_sdw_mbq_read(void *context, unsigned int reg, unsigned int *va
|
|||
ret = regmap_sdw_mbq_read_impl(slave, reg, val, mbq_size);
|
||||
if (ret == -ENODATA) {
|
||||
if (!deferrable)
|
||||
dev_warn(dev, "Defer on undeferable control: %x\n", reg);
|
||||
dev_warn(dev, "Defer on undeferrable control: %x\n", reg);
|
||||
|
||||
ret = regmap_sdw_mbq_poll_busy(slave, reg, ctx);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -900,6 +900,20 @@ static int ublk_validate_params(const struct ublk_device *ub)
|
|||
if (p->logical_bs_shift > PAGE_SHIFT || p->logical_bs_shift < 9)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* 256M is a reasonable upper bound for physical block size,
|
||||
* io_min and io_opt; it aligns with the maximum physical
|
||||
* block size possible in NVMe.
|
||||
*/
|
||||
if (p->physical_bs_shift > ilog2(SZ_256M))
|
||||
return -EINVAL;
|
||||
|
||||
if (p->io_min_shift > ilog2(SZ_256M))
|
||||
return -EINVAL;
|
||||
|
||||
if (p->io_opt_shift > ilog2(SZ_256M))
|
||||
return -EINVAL;
|
||||
|
||||
if (p->logical_bs_shift > p->physical_bs_shift)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -2397,8 +2411,14 @@ static void ublk_reset_ch_dev(struct ublk_device *ub)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
|
||||
ublk_queue_reinit(ub, ublk_get_queue(ub, i));
|
||||
for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
|
||||
struct ublk_queue *ubq = ublk_get_queue(ub, i);
|
||||
|
||||
/* Sync with ublk_cancel_cmd() */
|
||||
spin_lock(&ubq->cancel_lock);
|
||||
ublk_queue_reinit(ub, ubq);
|
||||
spin_unlock(&ubq->cancel_lock);
|
||||
}
|
||||
|
||||
/* set to NULL, otherwise new tasks cannot mmap io_cmd_buf */
|
||||
ub->mm = NULL;
|
||||
|
|
@ -2739,6 +2759,7 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, unsigned tag,
|
|||
{
|
||||
struct ublk_io *io = &ubq->ios[tag];
|
||||
struct ublk_device *ub = ubq->dev;
|
||||
struct io_uring_cmd *cmd = NULL;
|
||||
struct request *req;
|
||||
bool done;
|
||||
|
||||
|
|
@ -2761,12 +2782,15 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, unsigned tag,
|
|||
|
||||
spin_lock(&ubq->cancel_lock);
|
||||
done = !!(io->flags & UBLK_IO_FLAG_CANCELED);
|
||||
if (!done)
|
||||
if (!done) {
|
||||
io->flags |= UBLK_IO_FLAG_CANCELED;
|
||||
cmd = io->cmd;
|
||||
io->cmd = NULL;
|
||||
}
|
||||
spin_unlock(&ubq->cancel_lock);
|
||||
|
||||
if (!done)
|
||||
io_uring_cmd_done(io->cmd, UBLK_IO_RES_ABORT, issue_flags);
|
||||
if (!done && cmd)
|
||||
io_uring_cmd_done(cmd, UBLK_IO_RES_ABORT, issue_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3496,8 +3520,10 @@ static void ublk_ch_uring_cmd_cb(struct io_tw_req tw_req, io_tw_token_t tw)
|
|||
{
|
||||
unsigned int issue_flags = IO_URING_CMD_TASK_WORK_ISSUE_FLAGS;
|
||||
struct io_uring_cmd *cmd = io_uring_cmd_from_tw(tw_req);
|
||||
int ret = ublk_ch_uring_cmd_local(cmd, issue_flags);
|
||||
int ret = -ECANCELED;
|
||||
|
||||
if (!tw.cancel)
|
||||
ret = ublk_ch_uring_cmd_local(cmd, issue_flags);
|
||||
if (ret != -EIOCBQUEUED)
|
||||
io_uring_cmd_done(cmd, ret, issue_flags);
|
||||
}
|
||||
|
|
@ -4990,13 +5016,15 @@ static int ublk_ctrl_set_params(struct ublk_device *ub,
|
|||
*/
|
||||
ret = -EACCES;
|
||||
} else if (copy_from_user(&ub->params, argp, ph.len)) {
|
||||
/* zero out partial copy so no stale params survive */
|
||||
memset(&ub->params, 0, sizeof(ub->params));
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
/* clear all we don't support yet */
|
||||
ub->params.types &= UBLK_PARAM_TYPE_ALL;
|
||||
ret = ublk_validate_params(ub);
|
||||
if (ret)
|
||||
ub->params.types = 0;
|
||||
memset(&ub->params, 0, sizeof(ub->params));
|
||||
}
|
||||
mutex_unlock(&ub->mutex);
|
||||
|
||||
|
|
|
|||
|
|
@ -289,6 +289,9 @@ static inline void btintel_pcie_dump_debug_registers(struct hci_dev *hdev)
|
|||
skb_put_data(skb, buf, strlen(buf));
|
||||
data->boot_stage_cache = reg;
|
||||
|
||||
if (reg & BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_WARNING)
|
||||
bt_dev_warn(hdev, "Controller device warning (boot_stage: 0x%8.8x)", reg);
|
||||
|
||||
reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_IPC_STATUS_REG);
|
||||
snprintf(buf, sizeof(buf), "ipc status: 0x%8.8x", reg);
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
|
@ -880,8 +883,11 @@ static inline bool btintel_pcie_in_lockdown(struct btintel_pcie_data *data)
|
|||
|
||||
static inline bool btintel_pcie_in_error(struct btintel_pcie_data *data)
|
||||
{
|
||||
return (data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_ERR) ||
|
||||
(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_ABORT_HANDLER);
|
||||
if (data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_WARNING)
|
||||
bt_dev_warn(data->hdev, "Controller device warning (boot_stage: 0x%8.8x)",
|
||||
data->boot_stage_cache);
|
||||
|
||||
return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_ABORT_HANDLER;
|
||||
}
|
||||
|
||||
static void btintel_pcie_msix_gp1_handler(struct btintel_pcie_data *data)
|
||||
|
|
@ -914,7 +920,8 @@ static void btintel_pcie_msix_gp0_handler(struct btintel_pcie_data *data)
|
|||
data->img_resp_cache = reg;
|
||||
|
||||
if (btintel_pcie_in_error(data)) {
|
||||
bt_dev_err(data->hdev, "Controller in error state");
|
||||
bt_dev_err(data->hdev, "Controller in error state (boot_stage: 0x%8.8x)",
|
||||
data->boot_stage_cache);
|
||||
btintel_pcie_dump_debug_registers(data->hdev);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
#define BTINTEL_PCIE_CSR_BOOT_STAGE_OPFW (BIT(2))
|
||||
#define BTINTEL_PCIE_CSR_BOOT_STAGE_ROM_LOCKDOWN (BIT(10))
|
||||
#define BTINTEL_PCIE_CSR_BOOT_STAGE_IML_LOCKDOWN (BIT(11))
|
||||
#define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_ERR (BIT(12))
|
||||
#define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_WARNING (BIT(12))
|
||||
#define BTINTEL_PCIE_CSR_BOOT_STAGE_ABORT_HANDLER (BIT(13))
|
||||
#define BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_HALTED (BIT(14))
|
||||
#define BTINTEL_PCIE_CSR_BOOT_STAGE_MAC_ACCESS_ON (BIT(16))
|
||||
|
|
|
|||
|
|
@ -695,8 +695,13 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
|
|||
if (data->evt_skb == NULL)
|
||||
goto err_free_wc;
|
||||
|
||||
/* Parse and handle the return WMT event */
|
||||
wmt_evt = (struct btmtk_hci_wmt_evt *)data->evt_skb->data;
|
||||
wmt_evt = skb_pull_data(data->evt_skb, sizeof(*wmt_evt));
|
||||
if (!wmt_evt) {
|
||||
bt_dev_err(hdev, "WMT event too short (%u bytes)",
|
||||
data->evt_skb->len);
|
||||
err = -EINVAL;
|
||||
goto err_free_skb;
|
||||
}
|
||||
if (wmt_evt->whdr.op != hdr->op) {
|
||||
bt_dev_err(hdev, "Wrong op received %d expected %d",
|
||||
wmt_evt->whdr.op, hdr->op);
|
||||
|
|
@ -712,6 +717,12 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
|
|||
status = BTMTK_WMT_PATCH_DONE;
|
||||
break;
|
||||
case BTMTK_WMT_FUNC_CTRL:
|
||||
if (!skb_pull_data(data->evt_skb,
|
||||
sizeof(wmt_evt_funcc->status))) {
|
||||
err = -EINVAL;
|
||||
goto err_free_skb;
|
||||
}
|
||||
|
||||
wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
|
||||
if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
|
||||
status = BTMTK_WMT_ON_DONE;
|
||||
|
|
|
|||
|
|
@ -191,6 +191,9 @@ static int ath_recv(struct hci_uart *hu, const void *data, int count)
|
|||
{
|
||||
struct ath_struct *ath = hu->priv;
|
||||
|
||||
if (!ath)
|
||||
return -ENODEV;
|
||||
|
||||
ath->rx_skb = h4_recv_buf(hu, ath->rx_skb, data, count,
|
||||
ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts));
|
||||
if (IS_ERR(ath->rx_skb)) {
|
||||
|
|
|
|||
|
|
@ -585,6 +585,9 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count)
|
|||
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
|
||||
return -EUNATCH;
|
||||
|
||||
if (!bcsp)
|
||||
return -ENODEV;
|
||||
|
||||
BT_DBG("hu %p count %d rx_state %d rx_count %ld",
|
||||
hu, count, bcsp->rx_state, bcsp->rx_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