mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
KVM/vfio: Use file-based reference counting for KVM
This series switches the KVM-VFIO interface and external consumers over to standard file-based reference counting, eliminating all external KVM symbol exports. Currently, VFIO integrates with KVM by looking up kvm_get_kvm_safe() and kvm_put_kvm() dynamically using symbol_get(), manually tracking module reference counts and storing a put_kvm function pointer in struct vfio_device. In the ARM64-on-s390 architecture, a second concurrent KVM module (kvm-arm64) is introduced alongside native KVM to host hardware-accelerated ARM64 guests. Having exported global symbols (like kvm_get_kvm/kvm_put_kvm) creates symbol conflicts and prevents clean coexistence of two KVM modules. Additionally, the file based counting simplifies the code and reuses the existing fs refcounting. Instead of passing raw KVM pointers and managing module symbols manually, the interface now passes the underlying VM file descriptor throughout VFIO and associated architecture subsystems. To safely extract the KVM instance from a file, an architecture-namespaced helper mechanism is introduced that verifies the file belongs to the expected KVM implementation before accessing its internal state. A back-pointer from the KVM instance to its associated file is maintained across its lifecycle so subsystems can safely acquire file references on demand. Finally, with VFIO, architecture page tracking, and device hooks converted to use file references, the remaining KVM reference- counting exports are restricted strictly to internal KVM modules. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE+SKTgaM0CPnbq/vKEXu8gLWmHHwFAmrI9TcACgkQEXu8gLWm HHwSXg//V6Y5RgHTTJ9dien606XXVEVv+bI2zb3OJGGmrDxSAAQCrBgqGEOYlZk2 4h/iZFJeMLbJScTyi8NqkWpS3WJzjxXt8jUwwFxCOPBgWvbk0zRmc7J9kio/3EwD h8NL4Y5aKxuncBQxiSc2AblEIEl4Zcv4sF+WgY0VzCQTNa1siUTBmSvYBl+/R5gR PZ/Aj4jt5ROVVMAtaTJE0U+wCaQqy37iz3NcLaOIvUFNv9yMoLJ2BbtuESac8Fiv JOT5jppKgFxIGkIyWM1SBajGbMN4QQdv2j3zz3Z9YY6bONEzQmVIxC7qm3Aa/PXH DPAHezjIitmBBU+0D/1QfJAk5w7Qkkg1PbrJzcxM45FUTaQuJQTaFe5Gov7uYLnu GZImPlcRZru7wOrkV8VIpzXszMfD32h4sRkcSYGpyl7glREy4o9DbfJ8PBHd29oF 6HVGp3xO2NBSGutp654gFZpmjCpO8EW2b6f9kLM75C2wY48V0tu0Rb43WXzcPbba SZygJW02s1G6OfSKf3U2QiUvT9c7ppYJ1OGOolLSFYtREjDrEQnkWFHbeK/lEzZK HsHMHsoOCLFaRL82flE+atqKfSHb2ocjB61VjPiDZRejDkekU26DmRJkSD4w/KVa IDq9NwfYNBrjsClqiHGOi0fgPZNhm0OhvchQkkA+x+MgaYIYV0M= =ggf4 -----END PGP SIGNATURE----- Merge tag 'kvm-s390-next-7.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD KVM/vfio: Use file-based reference counting for KVM This series switches the KVM-VFIO interface and external consumers over to standard file-based reference counting, eliminating all external KVM symbol exports. Currently, VFIO integrates with KVM by looking up kvm_get_kvm_safe() and kvm_put_kvm() dynamically using symbol_get(), manually tracking module reference counts and storing a put_kvm function pointer in struct vfio_device. In the ARM64-on-s390 architecture, a second concurrent KVM module (kvm-arm64) is introduced alongside native KVM to host hardware-accelerated ARM64 guests. Having exported global symbols (like kvm_get_kvm/kvm_put_kvm) creates symbol conflicts and prevents clean coexistence of two KVM modules. Additionally, the file based counting simplifies the code and reuses the existing fs refcounting. Instead of passing raw KVM pointers and managing module symbols manually, the interface now passes the underlying VM file descriptor throughout VFIO and associated architecture subsystems. To safely extract the KVM instance from a file, an architecture-namespaced helper mechanism is introduced that verifies the file belongs to the expected KVM implementation before accessing its internal state. A back-pointer from the KVM instance to its associated file is maintained across its lifecycle so subsystems can safely acquire file references on demand. Finally, with VFIO, architecture page tracking, and device hooks converted to use file references, the remaining KVM reference- counting exports are restricted strictly to internal KVM modules.
This commit is contained in:
commit
4e0ab192f2
7
.mailmap
7
.mailmap
|
|
@ -19,7 +19,8 @@ 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>
|
||||
Aditya Garg <aditya.garg@linux.dev> <gargaditya08@live.com>
|
||||
Aditya Garg <aditya.garg@linux.dev> <gargaditya08@proton.me>
|
||||
Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com>
|
||||
Adrian Bunk <bunk@stusta.de>
|
||||
Ajay Kaher <ajay.kaher@broadcom.com> <akaher@vmware.com>
|
||||
|
|
@ -699,6 +700,7 @@ Oliver Hartkopp <socketcan@hartkopp.net> <oliver.hartkopp@volkswagen.de>
|
|||
Oliver Hartkopp <socketcan@hartkopp.net> <oliver@hartkopp.net>
|
||||
Oliver Upton <oupton@kernel.org> <oupton@google.com>
|
||||
Oliver Upton <oupton@kernel.org> <oliver.upton@linux.dev>
|
||||
Ondrej Mosnáček <omosnacek@gmail.com> <omosnace@redhat.com>
|
||||
Ondřej Jirman <megi@xff.cz> <megous@megous.com>
|
||||
Oza Pawandeep <quic_poza@quicinc.com> <poza@codeaurora.org>
|
||||
Pali Rohár <pali@kernel.org> <pali.rohar@gmail.com>
|
||||
|
|
@ -898,7 +900,8 @@ Thomas Graf <tgraf@suug.ch>
|
|||
Thomas Gleixner <tglx@kernel.org> <tglx@linutronix.de>
|
||||
Thomas Körper <socketcan@esd.eu> <thomas.koerper@esd.eu>
|
||||
Thomas Pedersen <twp@codeaurora.org>
|
||||
Thorsten Blum <thorsten.blum@linux.dev> <thorsten.blum@toblux.com>
|
||||
Thorsten Blum <blum@kernel.org> <thorsten.blum@toblux.com>
|
||||
Thorsten Blum <blum@kernel.org> <thorsten.blum@linux.dev>
|
||||
Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com>
|
||||
Tingwei Zhang <quic_tingwei@quicinc.com> <tingwei@codeaurora.org>
|
||||
Tirupathi Reddy <quic_tirupath@quicinc.com> <tirupath@codeaurora.org>
|
||||
|
|
|
|||
4
CREDITS
4
CREDITS
|
|
@ -4309,6 +4309,10 @@ N: Juergen Weigert
|
|||
E: jnweiger@immd4.informatik.uni-erlangen.de
|
||||
D: The Linux Support Team Erlangen
|
||||
|
||||
N: Russ Weight
|
||||
E: russ.weight@gmail.com
|
||||
D: Added support for Firmware Upload to the Firmware Loader
|
||||
|
||||
N: David Weinehall
|
||||
E: tao@acc.umu.se
|
||||
P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16
|
||||
|
|
|
|||
|
|
@ -108,6 +108,9 @@ Description:
|
|||
# NSFS_MAGIC
|
||||
dont_measure fsmagic=0x6e736673
|
||||
dont_appraise fsmagic=0x6e736673
|
||||
# CONFIGFS_MAGIC
|
||||
dont_measure fsmagic=0x62656570
|
||||
dont_appraise fsmagic=0x62656570
|
||||
|
||||
measure func=BPRM_CHECK
|
||||
measure func=FILE_MMAP mask=MAY_EXEC
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
What: /sys/class/firmware/.../data
|
||||
Date: July 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Russ Weight <russ.weight@linux.dev>
|
||||
Contact: driver-core@lists.linux.dev
|
||||
Description: The data sysfs file is used for firmware-fallback and for
|
||||
firmware uploads. Cat a firmware image to this sysfs file
|
||||
after you echo 1 to the loading sysfs file. When the firmware
|
||||
|
|
@ -13,7 +13,7 @@ Description: The data sysfs file is used for firmware-fallback and for
|
|||
What: /sys/class/firmware/.../cancel
|
||||
Date: July 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Russ Weight <russ.weight@linux.dev>
|
||||
Contact: driver-core@lists.linux.dev
|
||||
Description: Write-only. For firmware uploads, write a "1" to this file to
|
||||
request that the transfer of firmware data to the lower-level
|
||||
device be canceled. This request will be rejected (EBUSY) if
|
||||
|
|
@ -23,7 +23,7 @@ Description: Write-only. For firmware uploads, write a "1" to this file to
|
|||
What: /sys/class/firmware/.../error
|
||||
Date: July 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Russ Weight <russ.weight@linux.dev>
|
||||
Contact: driver-core@lists.linux.dev
|
||||
Description: Read-only. Returns a string describing a failed firmware
|
||||
upload. This string will be in the form of <STATUS>:<ERROR>,
|
||||
where <STATUS> will be one of the status strings described
|
||||
|
|
@ -37,7 +37,7 @@ Description: Read-only. Returns a string describing a failed firmware
|
|||
What: /sys/class/firmware/.../loading
|
||||
Date: July 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Russ Weight <russ.weight@linux.dev>
|
||||
Contact: driver-core@lists.linux.dev
|
||||
Description: The loading sysfs file is used for both firmware-fallback and
|
||||
for firmware uploads. Echo 1 onto the loading file to indicate
|
||||
you are writing a firmware file to the data sysfs node. Echo
|
||||
|
|
@ -49,7 +49,7 @@ Description: The loading sysfs file is used for both firmware-fallback and
|
|||
What: /sys/class/firmware/.../remaining_size
|
||||
Date: July 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Russ Weight <russ.weight@linux.dev>
|
||||
Contact: driver-core@lists.linux.dev
|
||||
Description: Read-only. For firmware upload, this file contains the size
|
||||
of the firmware data that remains to be transferred to the
|
||||
lower-level device driver. The size value is initialized to
|
||||
|
|
@ -62,7 +62,7 @@ Description: Read-only. For firmware upload, this file contains the size
|
|||
What: /sys/class/firmware/.../status
|
||||
Date: July 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Russ Weight <russ.weight@linux.dev>
|
||||
Contact: driver-core@lists.linux.dev
|
||||
Description: Read-only. Returns a string describing the current status of
|
||||
a firmware upload. The string will be one of the following:
|
||||
idle, "receiving", "preparing", "transferring", "programming".
|
||||
|
|
@ -70,7 +70,7 @@ Description: Read-only. Returns a string describing the current status of
|
|||
What: /sys/class/firmware/.../timeout
|
||||
Date: July 2022
|
||||
KernelVersion: 5.19
|
||||
Contact: Russ Weight <russ.weight@linux.dev>
|
||||
Contact: driver-core@lists.linux.dev
|
||||
Description: This file supports the timeout mechanism for firmware
|
||||
fallback. This file has no affect on firmware uploads. For
|
||||
more information on timeouts please see the documentation
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ Features:
|
|||
- pages are linked to per-memcg LRU exclusively, and there is no global LRU.
|
||||
- optionally, memory+swap usage can be accounted and limited.
|
||||
- hierarchical accounting
|
||||
- soft limit
|
||||
- moving (recharging) account at moving a task is selectable.
|
||||
- usage threshold notifier
|
||||
- memory pressure notifier
|
||||
|
|
@ -76,10 +75,9 @@ Brief summary of control files.
|
|||
memory.memsw.failcnt show the number of memory+Swap hits limits
|
||||
memory.max_usage_in_bytes show max memory usage recorded
|
||||
memory.memsw.max_usage_in_bytes show max memory+Swap usage recorded
|
||||
memory.soft_limit_in_bytes set/show soft limit of memory usage
|
||||
This knob is not available on CONFIG_PREEMPT_RT systems.
|
||||
This knob is deprecated and shouldn't be
|
||||
used.
|
||||
memory.soft_limit_in_bytes This knob is deprecated and has no effect.
|
||||
Writes are ignored and reads always
|
||||
return the maximum value.
|
||||
memory.stat show various statistics
|
||||
memory.use_hierarchy set/show hierarchical account enabled
|
||||
This knob is deprecated and shouldn't be
|
||||
|
|
@ -340,9 +338,6 @@ memory.kmem.usage_in_bytes, or in a separate counter when it makes sense.
|
|||
The main "kmem" counter is fed into the main counter, so kmem charges will
|
||||
also be visible from the user counter.
|
||||
|
||||
Currently no soft limit is implemented for kernel memory. It is future work
|
||||
to trigger slab reclaim when those limits are reached.
|
||||
|
||||
2.7.1 Current Kernel Memory resources accounted
|
||||
-----------------------------------------------
|
||||
|
||||
|
|
@ -710,42 +705,10 @@ For compatibility reasons writing 1 to memory.use_hierarchy will always pass::
|
|||
|
||||
THIS IS DEPRECATED!
|
||||
|
||||
Soft limits allow for greater sharing of memory. The idea behind soft limits
|
||||
is to allow control groups to use as much of the memory as needed, provided
|
||||
Writing to memory.soft_limit_in_bytes has no effect and reading it will
|
||||
always return the maximum value.
|
||||
|
||||
a. There is no memory contention
|
||||
b. They do not exceed their hard limit
|
||||
|
||||
When the system detects memory contention or low memory, control groups
|
||||
are pushed back to their soft limits. If the soft limit of each control
|
||||
group is very high, they are pushed back as much as possible to make
|
||||
sure that one control group does not starve the others of memory.
|
||||
|
||||
Please note that soft limits is a best-effort feature; it comes with
|
||||
no guarantees, but it does its best to make sure that when memory is
|
||||
heavily contended for, memory is allocated based on the soft limit
|
||||
hints/setup. Currently soft limit based reclaim is set up such that
|
||||
it gets invoked from balance_pgdat (kswapd).
|
||||
|
||||
7.1 Interface
|
||||
-------------
|
||||
|
||||
Soft limits can be setup by using the following commands (in this example we
|
||||
assume a soft limit of 256 MiB)::
|
||||
|
||||
# echo 256M > memory.soft_limit_in_bytes
|
||||
|
||||
If we want to change this to 1G, we can at any time use::
|
||||
|
||||
# echo 1G > memory.soft_limit_in_bytes
|
||||
|
||||
.. note::
|
||||
Soft limits take effect over a long period of time, since they involve
|
||||
reclaiming memory for balancing between memory cgroups
|
||||
|
||||
.. note::
|
||||
It is recommended to set the soft limit always below the hard limit,
|
||||
otherwise the hard limit will take precedence.
|
||||
Use memory.low and memory.min in cgroup v2 instead.
|
||||
|
||||
.. _cgroup-v1-memory-move-charges:
|
||||
|
||||
|
|
|
|||
|
|
@ -176,3 +176,68 @@ Message from dmesg::
|
|||
secondary_startup_64+0xa4/0xb0
|
||||
nvme nvme0: Could not set queue count (16385)
|
||||
nvme nvme0: IO queues not created
|
||||
|
||||
Example 4: Inject an error into the first write command
|
||||
-------------------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
echo 0x01 > /sys/kernel/debug/nvme0n1/fault_inject/opcode
|
||||
echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times
|
||||
echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability
|
||||
dd if=/dev/zero of=/dev/nvme0n1 oflag=direct bs=512 count=1
|
||||
|
||||
Expected Result::
|
||||
|
||||
The first write command sent to nvme0n1 fails
|
||||
|
||||
Message from dmesg::
|
||||
|
||||
FAULT_INJECTION: forcing a failure.
|
||||
name fault_inject, interval 1, probability 100, space 0, times 1
|
||||
CPU: 4 UID: 0 PID: 0 Comm: swapper/4 Not tainted 7.1.0+ #5 PREEMPT(full)
|
||||
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-20240910_120124-localhost 04/01/2014
|
||||
Call Trace:
|
||||
<IRQ>
|
||||
dump_stack_lvl+0x6e/0xa0
|
||||
dump_stack+0x10/0x16
|
||||
should_fail_ex+0x461/0x510
|
||||
should_fail+0xb/0x20
|
||||
nvme_should_fail+0x11b/0x240 [nvme_core]
|
||||
nvme_poll_cq+0x6ad/0xb30 [nvme]
|
||||
nvme_irq+0x84/0xe0 [nvme]
|
||||
? __pfx_nvme_irq+0x10/0x10 [nvme]
|
||||
? rcu_core+0xa40/0xa90
|
||||
? __pfx_sched_balance_softirq+0x10/0x10
|
||||
? debug_smp_processor_id+0x17/0x20
|
||||
? rcu_is_watching+0x13/0xa0
|
||||
__handle_irq_event_percpu+0x396/0x610
|
||||
handle_irq_event_percpu+0xf/0x90
|
||||
handle_irq_event+0xab/0x110
|
||||
handle_edge_irq+0x1a3/0x210
|
||||
__common_interrupt+0xff/0x170
|
||||
common_interrupt+0x90/0xc0
|
||||
</IRQ>
|
||||
<TASK>
|
||||
asm_common_interrupt+0x27/0x40
|
||||
RIP: 0010:pv_native_safe_halt+0x13/0x20
|
||||
Code: 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 8b 05 0a 2a 58 01 85 c0 7e 07 0f 00 2d ff cc 0d 00 fb f4 <c3> cc 0
|
||||
RSP: 0018:ffff888100a67e40 EFLAGS: 00000242
|
||||
RAX: 0000000000000001 RBX: ffff888100a49c40 RCX: ffffed102b6c645b
|
||||
RDX: ffffed102b6c645b RSI: ffffffff82a0d3c0 RDI: ffffffff81428b9b
|
||||
RBP: ffff888100a67e48 R08: ffffed102b6c645b R09: 0000000000000004
|
||||
R10: ffffed102b6c645a R11: 0000000000000001 R12: 0000000000000000
|
||||
R13: 0000000000000000 R14: ffffed1020149388 R15: dffffc0000000000
|
||||
? do_idle+0x19b/0x2c0
|
||||
? default_idle+0x9/0x20
|
||||
arch_cpu_idle+0x9/0x10
|
||||
default_idle_call+0x6b/0xa0
|
||||
do_idle+0x19b/0x2c0
|
||||
? __pfx_do_idle+0x10/0x10
|
||||
? complete_with_flags+0x63/0x70
|
||||
cpu_startup_entry+0x55/0x60
|
||||
start_secondary+0x1df/0x1e0
|
||||
common_startup_64+0x13e/0x158
|
||||
</TASK>
|
||||
nvme0n1: Write(0x1) @ LBA 0, 1 blocks, Invalid Command Opcode (sct 0x0 / sc 0x1) DNR
|
||||
operation not supported error, dev nvme0n1, sector 0 op 0x1:(WRITE) flags 0x8800 phys_seg 1 prio class 2
|
||||
|
|
|
|||
|
|
@ -360,6 +360,17 @@ attribute-sets:
|
|||
name: tsoff
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: filter-attrs
|
||||
attributes:
|
||||
-
|
||||
name: orig-flags
|
||||
type: u32
|
||||
doc: bitmask of tuple fields to filter on, original direction
|
||||
-
|
||||
name: reply-flags
|
||||
type: u32
|
||||
doc: bitmask of tuple fields to filter on, reply direction
|
||||
-
|
||||
name: conntrack-attrs
|
||||
attributes:
|
||||
|
|
@ -466,7 +477,7 @@ attribute-sets:
|
|||
-
|
||||
name: filter
|
||||
type: nest
|
||||
nested-attributes: tuple-attrs
|
||||
nested-attributes: filter-attrs
|
||||
-
|
||||
name: status-mask
|
||||
type: u32
|
||||
|
|
@ -591,10 +602,14 @@ operations:
|
|||
request:
|
||||
value: 0x101
|
||||
attributes:
|
||||
- mark
|
||||
- filter
|
||||
- tuple-orig
|
||||
- tuple-reply
|
||||
- status
|
||||
- mark
|
||||
- zone
|
||||
- mark-mask
|
||||
- filter
|
||||
- status-mask
|
||||
reply:
|
||||
value: 0x100
|
||||
attributes:
|
||||
|
|
|
|||
|
|
@ -90,10 +90,6 @@ irq_domain映射的类型
|
|||
映射的优点是固定时间查找IRQ号,而且irq_descs只分配给在用的IRQ。 缺点是该表
|
||||
必须尽可能大的hwirq号。
|
||||
|
||||
irq_domain_add_linear()和irq_domain_create_linear()在功能上是等价的,
|
||||
除了第一个参数不同--前者接受一个Open Firmware特定的 'struct device_node' 而
|
||||
后者接受一个更通用的抽象 'struct fwnode_handle' 。
|
||||
|
||||
大多数驱动应该使用线性映射
|
||||
|
||||
树状映射
|
||||
|
|
|
|||
24
MAINTAINERS
24
MAINTAINERS
|
|
@ -5671,8 +5671,8 @@ W: http://bu3sch.de/btgpio.php
|
|||
F: drivers/gpio/gpio-bt8xx.c
|
||||
|
||||
BTRFS FILE SYSTEM
|
||||
M: Chris Mason <clm@fb.com>
|
||||
M: David Sterba <dsterba@suse.com>
|
||||
R: Chris Mason <mason@kernel.org>
|
||||
L: linux-btrfs@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://btrfs.readthedocs.io
|
||||
|
|
@ -8039,7 +8039,7 @@ F: drivers/gpu/drm/sun4i/sun8i*
|
|||
|
||||
DRM DRIVER FOR APPLE TOUCH BARS
|
||||
M: Aun-Ali Zaidi <admin@kodeit.net>
|
||||
M: Aditya Garg <gargaditya08@proton.me>
|
||||
M: Aditya Garg <aditya.garg@linux.dev>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
|
|
@ -10190,7 +10190,6 @@ F: include/linux/arm_ffa.h
|
|||
|
||||
FIRMWARE LOADER (request_firmware)
|
||||
M: Luis Chamberlain <mcgrof@kernel.org>
|
||||
M: Russ Weight <russ.weight@linux.dev>
|
||||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
L: driver-core@lists.linux.dev
|
||||
S: Maintained
|
||||
|
|
@ -12221,7 +12220,7 @@ F: drivers/tty/hvc/
|
|||
|
||||
HUNG TASK DETECTOR
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
R: Lance Yang <lance.yang@linux.dev>
|
||||
M: Lance Yang <lance.yang@linux.dev>
|
||||
R: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
R: Petr Mladek <pmladek@suse.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
|
|
@ -14236,8 +14235,6 @@ F: tools/testing/selftests/
|
|||
KERNEL SMB3 SERVER (KSMBD)
|
||||
M: Namjae Jeon <linkinjeon@kernel.org>
|
||||
M: Namjae Jeon <linkinjeon@samba.org>
|
||||
M: Steve French <smfrench@gmail.com>
|
||||
M: Steve French <sfrench@samba.org>
|
||||
R: Sergey Senozhatsky <senozhatsky@chromium.org>
|
||||
R: Tom Talpey <tom@talpey.com>
|
||||
R: ChenXiaoSong <chenxiaosong@chenxiaosong.com>
|
||||
|
|
@ -17412,7 +17409,6 @@ F: mm/swapfile.c
|
|||
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
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@infradead.org>
|
||||
|
|
@ -17422,6 +17418,7 @@ R: Dev Jain <dev.jain@arm.com>
|
|||
R: Barry Song <baohua@kernel.org>
|
||||
R: Lance Yang <lance.yang@linux.dev>
|
||||
R: Usama Arif <usama.arif@linux.dev>
|
||||
R: Kiryl Shutsemau <kas@kernel.org>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
W: http://www.linux-mm.org
|
||||
|
|
@ -17694,7 +17691,7 @@ F: Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
|
|||
F: drivers/spi/spi-at91-usart.c
|
||||
|
||||
MICROCHIP ATSHA204A DRIVER
|
||||
M: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
M: Thorsten Blum <blum@kernel.org>
|
||||
L: linux-crypto@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/crypto/atmel-sha204a.c
|
||||
|
|
@ -17718,7 +17715,7 @@ F: Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
|
|||
F: drivers/media/platform/microchip/microchip-csi2dc.c
|
||||
|
||||
MICROCHIP ECC DRIVER
|
||||
M: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
M: Thorsten Blum <blum@kernel.org>
|
||||
L: linux-crypto@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/crypto/atmel-ecc.c
|
||||
|
|
@ -19565,7 +19562,7 @@ F: include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h
|
|||
|
||||
NVM EXPRESS DRIVER
|
||||
M: Keith Busch <kbusch@kernel.org>
|
||||
M: Jens Axboe <axboe@fb.com>
|
||||
M: Jens Axboe <axboe@kernel.dk>
|
||||
M: Christoph Hellwig <hch@lst.de>
|
||||
M: Sagi Grimberg <sagi@grimberg.me>
|
||||
L: linux-nvme@lists.infradead.org
|
||||
|
|
@ -24774,7 +24771,7 @@ K: \bsecurity_[a-z_0-9]\+\b
|
|||
SELINUX SECURITY MODULE
|
||||
M: Paul Moore <paul@paul-moore.com>
|
||||
M: Stephen Smalley <stephen.smalley.work@gmail.com>
|
||||
R: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
R: Ondrej Mosnáček <omosnacek@gmail.com>
|
||||
L: selinux@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://github.com/SELinuxProject
|
||||
|
|
@ -25232,10 +25229,9 @@ F: Documentation/admin-guide/LSM/Smack.rst
|
|||
F: security/smack/
|
||||
|
||||
SMBDIRECT (RDMA Stream Transport with Read/Write-Offload, MS-SMBD)
|
||||
M: Steve French <smfrench@gmail.com>
|
||||
M: Steve French <sfrench@samba.org>
|
||||
M: Namjae Jeon <linkinjeon@kernel.org>
|
||||
M: Namjae Jeon <linkinjeon@samba.org>
|
||||
M: Paulo Alcantara <pc@manguebit.org>
|
||||
R: Stefan Metzmacher <metze@samba.org>
|
||||
R: Tom Talpey <tom@talpey.com>
|
||||
L: linux-cifs@vger.kernel.org
|
||||
|
|
@ -25406,7 +25402,7 @@ F: drivers/md/md*
|
|||
F: drivers/md/raid*
|
||||
F: include/linux/raid/
|
||||
F: include/uapi/linux/raid/
|
||||
F: lib/raid/raid6/
|
||||
F: lib/raid/
|
||||
|
||||
SOLIDRUN CLEARFOG SUPPORT
|
||||
M: Russell King <linux@armlinux.org.uk>
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
VERSION = 7
|
||||
PATCHLEVEL = 3
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ static int aesbs_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
|
|||
struct crypto_aes_ctx *rk;
|
||||
int err;
|
||||
|
||||
rk = kmalloc(sizeof(*rk), GFP_KERNEL);
|
||||
rk = kmalloc_obj(*rk);
|
||||
if (!rk)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ static int aesbs_cbc_ctr_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
|
|||
struct crypto_aes_ctx *rk;
|
||||
int err;
|
||||
|
||||
rk = kmalloc(sizeof(*rk), GFP_KERNEL);
|
||||
rk = kmalloc_obj(*rk);
|
||||
if (!rk)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,5 +78,6 @@ void __init cpuinfo_store_boot_cpu(void);
|
|||
void __init init_cpu_features(struct cpuinfo_arm64 *info);
|
||||
void update_cpu_features(int cpu, struct cpuinfo_arm64 *info,
|
||||
struct cpuinfo_arm64 *boot);
|
||||
bool gmid_el1_accessible(const struct cpuinfo_arm64 *info);
|
||||
|
||||
#endif /* __ASM_CPU_H */
|
||||
|
|
|
|||
|
|
@ -627,13 +627,6 @@ static inline bool id_aa64pfr1_mpamfrac(u64 pfr1)
|
|||
return val > 0;
|
||||
}
|
||||
|
||||
static inline bool id_aa64pfr1_mte(u64 pfr1)
|
||||
{
|
||||
u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_EL1_MTE_SHIFT);
|
||||
|
||||
return val >= ID_AA64PFR1_EL1_MTE_MTE2;
|
||||
}
|
||||
|
||||
void __init setup_boot_cpu_features(void);
|
||||
void __init setup_system_features(void);
|
||||
void __init setup_user_features(void);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
|
|||
|
||||
for (i = 0; i < target_impl_cpu_num; i++) {
|
||||
if (__is_affected_midr_range(entry, target_impl_cpus[i].midr,
|
||||
target_impl_cpus[i].midr))
|
||||
target_impl_cpus[i].revidr))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1178,6 +1178,33 @@ static bool detect_ftr_has_mpam(void)
|
|||
return id_aa64pfr0_mpam(pfr0) || id_aa64pfr1_mpamfrac(pfr1);
|
||||
}
|
||||
|
||||
bool gmid_el1_accessible(const struct cpuinfo_arm64 *info)
|
||||
{
|
||||
const struct arm64_ftr_bits *ftrp;
|
||||
s64 mte, ovr;
|
||||
u64 ftr_mask;
|
||||
|
||||
/* No ID register reflects CONFIG_ARM64_MTE. */
|
||||
if (!IS_ENABLED(CONFIG_ARM64_MTE))
|
||||
return false;
|
||||
|
||||
for (ftrp = ftr_id_aa64pfr1; ftrp->width; ftrp++) {
|
||||
if (ftrp->shift == ID_AA64PFR1_EL1_MTE_SHIFT)
|
||||
break;
|
||||
}
|
||||
|
||||
ftr_mask = arm64_ftr_mask(ftrp);
|
||||
mte = arm64_ftr_value(ftrp, info->reg_id_aa64pfr1);
|
||||
|
||||
/* The boot CPU runs before init_cpu_ftr_reg() strips unsafe overrides. */
|
||||
if ((id_aa64pfr1_override.mask & ftr_mask) == ftr_mask) {
|
||||
ovr = arm64_ftr_value(ftrp, id_aa64pfr1_override.val);
|
||||
mte = arm64_ftr_safe_value(ftrp, ovr, mte);
|
||||
}
|
||||
|
||||
return mte >= ID_AA64PFR1_EL1_MTE_MTE2;
|
||||
}
|
||||
|
||||
void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||
{
|
||||
/* Before we start using the tables, make sure it is sorted */
|
||||
|
|
@ -1230,7 +1257,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
|||
init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr);
|
||||
}
|
||||
|
||||
if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
|
||||
if (gmid_el1_accessible(info))
|
||||
init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);
|
||||
}
|
||||
|
||||
|
|
@ -1492,11 +1519,9 @@ void update_cpu_features(int cpu,
|
|||
* they read/write depends on the GMID_EL1.BS field. Check that the
|
||||
* value is the same on all CPUs.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_ARM64_MTE) &&
|
||||
id_aa64pfr1_mte(info->reg_id_aa64pfr1)) {
|
||||
if (gmid_el1_accessible(info))
|
||||
taint |= check_update_ftr_reg(SYS_GMID_EL1, cpu,
|
||||
info->reg_gmid, boot->reg_gmid);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't have AArch32 at all then skip the checks entirely
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
|
|||
info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1);
|
||||
info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1);
|
||||
|
||||
if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
|
||||
if (gmid_el1_accessible(info))
|
||||
info->reg_gmid = read_cpuid(GMID_EL1);
|
||||
|
||||
if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
|
||||
|
|
|
|||
|
|
@ -129,7 +129,8 @@ int machine_kexec_post_load(struct kimage *kimage)
|
|||
}
|
||||
|
||||
/* Create a copy of the linear map */
|
||||
rc = trans_pgd_create_copy(&info, &trans_pgd, PAGE_OFFSET, PAGE_END);
|
||||
rc = trans_pgd_create_copy(&info, &trans_pgd,
|
||||
_PAGE_OFFSET(vabits_actual), PAGE_END);
|
||||
if (rc)
|
||||
return rc;
|
||||
kimage->arch.ttbr1 = __pa(trans_pgd);
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
|
|||
num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU;
|
||||
|
||||
if (num_mmus > kvm->arch.nested_mmus_size) {
|
||||
tmp = kvcalloc(num_mmus, sizeof(*tmp), GFP_KERNEL_ACCOUNT);
|
||||
tmp = kvzalloc_objs(*tmp, num_mmus, GFP_KERNEL_ACCOUNT);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irqflags.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
|
@ -154,6 +155,9 @@ static void show_pte(unsigned long addr)
|
|||
pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n",
|
||||
mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
|
||||
vabits_actual, mm_to_pgd_phys(mm));
|
||||
|
||||
guard(irqsave)();
|
||||
|
||||
pgdp = pgd_offset(mm, addr);
|
||||
pgd = READ_ONCE(*pgdp);
|
||||
pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
|
||||
|
|
@ -167,25 +171,25 @@ static void show_pte(unsigned long addr)
|
|||
if (pgd_none(pgd) || pgd_bad(pgd))
|
||||
break;
|
||||
|
||||
p4dp = p4d_offset(pgdp, addr);
|
||||
p4dp = p4d_offset_lockless(pgdp, pgd, addr);
|
||||
p4d = READ_ONCE(*p4dp);
|
||||
pr_cont(", p4d=%016llx", p4d_val(p4d));
|
||||
if (p4d_none(p4d) || p4d_bad(p4d))
|
||||
break;
|
||||
|
||||
pudp = pud_offset(p4dp, addr);
|
||||
pudp = pud_offset_lockless(p4dp, p4d, addr);
|
||||
pud = READ_ONCE(*pudp);
|
||||
pr_cont(", pud=%016llx", pud_val(pud));
|
||||
if (pud_none(pud) || pud_bad(pud))
|
||||
break;
|
||||
|
||||
pmdp = pmd_offset(pudp, addr);
|
||||
pmdp = pmd_offset_lockless(pudp, pud, addr);
|
||||
pmd = READ_ONCE(*pmdp);
|
||||
pr_cont(", pmd=%016llx", pmd_val(pmd));
|
||||
if (pmd_none(pmd) || pmd_bad(pmd))
|
||||
break;
|
||||
|
||||
ptep = pte_offset_map(pmdp, addr);
|
||||
ptep = pte_offset_map(&pmd, addr);
|
||||
if (!ptep)
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ config LOONGARCH
|
|||
select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC
|
||||
select HAVE_RETHOOK
|
||||
select HAVE_RSEQ
|
||||
select HAVE_RUST
|
||||
select HAVE_RUST if !KASAN
|
||||
select HAVE_SAMPLE_FTRACE_DIRECT
|
||||
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
|
||||
select HAVE_SETUP_PER_CPU_AREA if NUMA
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct dmsintc_state {
|
|||
};
|
||||
|
||||
int kvm_loongarch_register_dmsintc_device(void);
|
||||
void kvm_loongarch_unregister_dmsintc_device(void);
|
||||
void dmsintc_inject_irq(struct kvm_vcpu *vcpu);
|
||||
int dmsintc_set_irq(struct kvm *kvm, u64 addr, int data, int level);
|
||||
int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 vector, int level);
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ struct loongarch_eiointc {
|
|||
};
|
||||
|
||||
int kvm_loongarch_register_eiointc_device(void);
|
||||
void kvm_loongarch_unregister_eiointc_device(void);
|
||||
void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level);
|
||||
|
||||
#endif /* __ASM_KVM_EIOINTC_H */
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ struct kvm_arch {
|
|||
unsigned int pte_shifts[MAX_PGTABLE_LEVELS];
|
||||
unsigned int root_level;
|
||||
spinlock_t phyid_map_lock;
|
||||
spinlock_t pv_setting_lock;
|
||||
struct kvm_phyid_map *phyid_map;
|
||||
/* Enabled PV features */
|
||||
unsigned long pv_features;
|
||||
|
|
@ -350,7 +351,6 @@ static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
|
|||
static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {}
|
||||
void kvm_check_vpid(struct kvm_vcpu *vcpu);
|
||||
enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer);
|
||||
void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm, const struct kvm_memory_slot *memslot);
|
||||
void kvm_init_vmcs(struct kvm *kvm);
|
||||
void kvm_exc_entry(void);
|
||||
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
|
|
|
|||
|
|
@ -41,5 +41,6 @@ struct ipi_state {
|
|||
#define IOCSR_ANY_SEND 0x158
|
||||
|
||||
int kvm_loongarch_register_ipi_device(void);
|
||||
void kvm_loongarch_unregister_ipi_device(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ struct loongarch_pch_pic {
|
|||
|
||||
struct kvm_kernel_irq_routing_entry;
|
||||
int kvm_loongarch_register_pch_pic_device(void);
|
||||
void kvm_loongarch_unregister_pch_pic_device(void);
|
||||
void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level);
|
||||
int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int level);
|
||||
|
||||
|
|
|
|||
|
|
@ -275,6 +275,9 @@ bool kprobe_singlestep_handler(struct pt_regs *regs)
|
|||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
unsigned long addr = instruction_pointer(regs);
|
||||
|
||||
if (!cur)
|
||||
return false;
|
||||
|
||||
if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
|
||||
((unsigned long)&cur->ainsn.insn[1] == addr)) {
|
||||
restore_local_irqflag(kcb, regs);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
cfi_st t6, PT_R18
|
||||
cfi_st t7, PT_R19
|
||||
cfi_st t8, PT_R20
|
||||
cfi_st u0, PT_R21
|
||||
cfi_st fp, PT_R22
|
||||
cfi_st s0, PT_R23
|
||||
cfi_st s1, PT_R24
|
||||
|
|
@ -59,7 +58,6 @@
|
|||
cfi_ld t6, PT_R18
|
||||
cfi_ld t7, PT_R19
|
||||
cfi_ld t8, PT_R20
|
||||
cfi_ld u0, PT_R21
|
||||
cfi_ld fp, PT_R22
|
||||
cfi_ld s0, PT_R23
|
||||
cfi_ld s1, PT_R24
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/threads.h>
|
||||
|
|
@ -716,13 +715,6 @@ void smp_send_stop(void)
|
|||
smp_call_function(stop_this_cpu, NULL, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROFILING
|
||||
int setup_profiling_timer(unsigned int multiplier)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void flush_tlb_all_ipi(void *info)
|
||||
{
|
||||
local_flush_tlb_all();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include "image-vars.h"
|
||||
|
||||
/*
|
||||
* Max avaliable Page Size is 64K, so we set SectionAlignment
|
||||
* Max available Page Size is 64K, so we set SectionAlignment
|
||||
* field of EFI application to 64K.
|
||||
*/
|
||||
PECOFF_FILE_ALIGN = 0x200;
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ static int kvm_dmsintc_create(struct kvm_device *dev, u32 type)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
s = kzalloc(sizeof(struct loongarch_dmsintc), GFP_KERNEL);
|
||||
s = kzalloc_obj(struct loongarch_dmsintc);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -180,3 +180,8 @@ int kvm_loongarch_register_dmsintc_device(void)
|
|||
{
|
||||
return kvm_register_device_ops(&kvm_dmsintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DMSINTC);
|
||||
}
|
||||
|
||||
void kvm_loongarch_unregister_dmsintc_device(void)
|
||||
{
|
||||
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_DMSINTC);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -695,3 +695,8 @@ int kvm_loongarch_register_eiointc_device(void)
|
|||
{
|
||||
return kvm_register_device_ops(&kvm_eiointc_dev_ops, KVM_DEV_TYPE_LOONGARCH_EIOINTC);
|
||||
}
|
||||
|
||||
void kvm_loongarch_unregister_eiointc_device(void)
|
||||
{
|
||||
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_EIOINTC);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -463,3 +463,8 @@ int kvm_loongarch_register_ipi_device(void)
|
|||
{
|
||||
return kvm_register_device_ops(&kvm_ipi_dev_ops, KVM_DEV_TYPE_LOONGARCH_IPI);
|
||||
}
|
||||
|
||||
void kvm_loongarch_unregister_ipi_device(void)
|
||||
{
|
||||
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_IPI);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int
|
|||
return dmsintc_set_irq(kvm, msg_addr, e->msi.data, level);
|
||||
}
|
||||
|
||||
if (e->msi.data >= EIOINTC_IRQS)
|
||||
return -EINVAL;
|
||||
|
||||
eiointc_set_irq(kvm->arch.eiointc, e->msi.data, level);
|
||||
|
||||
return 0;
|
||||
|
|
@ -500,3 +503,8 @@ int kvm_loongarch_register_pch_pic_device(void)
|
|||
{
|
||||
return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC);
|
||||
}
|
||||
|
||||
void kvm_loongarch_unregister_pch_pic_device(void)
|
||||
{
|
||||
kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_PCHPIC);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -385,27 +385,52 @@ static int kvm_loongarch_env_init(void)
|
|||
/* Register LoongArch IPI interrupt controller interface. */
|
||||
ret = kvm_loongarch_register_ipi_device();
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_env;
|
||||
|
||||
/* Register LoongArch EIOINTC interrupt controller interface. */
|
||||
ret = kvm_loongarch_register_eiointc_device();
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_ipi;
|
||||
|
||||
/* Register LoongArch PCH-PIC interrupt controller interface. */
|
||||
ret = kvm_loongarch_register_pch_pic_device();
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_eiointc;
|
||||
|
||||
/* Register LoongArch DMSINTC interrupt contrroller interface */
|
||||
if (cpu_has_msgint)
|
||||
if (cpu_has_msgint) {
|
||||
ret = kvm_loongarch_register_dmsintc_device();
|
||||
if (ret)
|
||||
goto err_pch_pic;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_pch_pic:
|
||||
kvm_loongarch_unregister_pch_pic_device();
|
||||
err_eiointc:
|
||||
kvm_loongarch_unregister_eiointc_device();
|
||||
err_ipi:
|
||||
kvm_loongarch_unregister_ipi_device();
|
||||
err_env:
|
||||
kvm_unregister_perf_callbacks();
|
||||
kfree(kvm_loongarch_ops);
|
||||
kvm_loongarch_ops = NULL;
|
||||
free_percpu(vmcs);
|
||||
vmcs = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void kvm_loongarch_env_exit(void)
|
||||
{
|
||||
if (cpu_has_msgint)
|
||||
kvm_loongarch_unregister_dmsintc_device();
|
||||
|
||||
kvm_loongarch_unregister_pch_pic_device();
|
||||
kvm_loongarch_unregister_eiointc_device();
|
||||
kvm_loongarch_unregister_ipi_device();
|
||||
|
||||
if (vmcs)
|
||||
free_percpu(vmcs);
|
||||
|
||||
|
|
@ -428,7 +453,11 @@ static int kvm_loongarch_init(void)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
return kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
||||
r = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
|
||||
if (r)
|
||||
kvm_loongarch_env_exit();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void kvm_loongarch_exit(void)
|
||||
|
|
|
|||
|
|
@ -383,6 +383,16 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, const struct kvm_memory_slot
|
|||
hva_t hva_start;
|
||||
size_t size, gpa_offset, hva_offset;
|
||||
|
||||
/*
|
||||
* The generic code allocates a fresh, zeroed memslot for every change,
|
||||
* so the arch flags computed below must be carried over when only the
|
||||
* userspace flags change, e.g. when dirty logging is toggled.
|
||||
*/
|
||||
if (change == KVM_MR_FLAGS_ONLY) {
|
||||
new->arch = old->arch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((change != KVM_MR_MOVE) && (change != KVM_MR_CREATE))
|
||||
return 0;
|
||||
/*
|
||||
|
|
@ -939,9 +949,3 @@ int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long gpa, bool write, in
|
|||
void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
|
||||
{
|
||||
}
|
||||
|
||||
void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm,
|
||||
const struct kvm_memory_slot *memslot)
|
||||
{
|
||||
kvm_flush_remote_tlbs(kvm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1165,10 +1165,14 @@ static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu,
|
|||
return -EINVAL;
|
||||
|
||||
/* All vCPUs need set the same PV features */
|
||||
spin_lock(&kvm->arch.pv_setting_lock);
|
||||
if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED)
|
||||
&& ((kvm->arch.pv_features & valid) != val))
|
||||
&& ((kvm->arch.pv_features & valid) != val)) {
|
||||
spin_unlock(&kvm->arch.pv_setting_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED;
|
||||
spin_unlock(&kvm->arch.pv_setting_lock);
|
||||
return 0;
|
||||
default:
|
||||
return -ENXIO;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
return -ENOMEM;
|
||||
}
|
||||
spin_lock_init(&kvm->arch.phyid_map_lock);
|
||||
spin_lock_init(&kvm->arch.pv_setting_lock);
|
||||
|
||||
kvm_init_vmcs(kvm);
|
||||
kvm_vm_init_features(kvm);
|
||||
|
|
|
|||
|
|
@ -717,7 +717,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
|||
move_reg(ctx, t1, src);
|
||||
emit_zext_32(ctx, t1, true);
|
||||
move_imm(ctx, dst, (ctx->user_vm_start >> 32) << 32, false);
|
||||
emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 1);
|
||||
emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 2);
|
||||
emit_insn(ctx, or, t1, dst, t1);
|
||||
move_reg(ctx, dst, t1);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -523,24 +523,24 @@ bcm47xx_buttons_add(const struct bcm47xx_gpio_key *buttons, int nbuttons)
|
|||
|
||||
/* 1 node for gpio-keys device, 1 node for each button, 1 terminator */
|
||||
const struct software_node **node_group __free(kfree) =
|
||||
kcalloc(1 + nbuttons + 1, sizeof(*node_group), GFP_KERNEL);
|
||||
kzalloc_objs(*node_group, 1 + nbuttons + 1);
|
||||
if (!node_group)
|
||||
return -ENOMEM;
|
||||
|
||||
/* 1 code property, 1 gpio property, 1 terminator */
|
||||
struct property_entry *props __free(kfree) =
|
||||
kcalloc(nbuttons * 3, sizeof(*props), GFP_KERNEL);
|
||||
kzalloc_objs(*props, nbuttons * 3);
|
||||
if (!props)
|
||||
return -ENOMEM;
|
||||
|
||||
/* 1 node for gpio-keys device, 1 node for each button */
|
||||
struct software_node *nodes __free(kfree) =
|
||||
kcalloc(1 + nbuttons, sizeof(*nodes), GFP_KERNEL);
|
||||
kzalloc_objs(*nodes, 1 + nbuttons);
|
||||
if (!nodes)
|
||||
return -ENOMEM;
|
||||
|
||||
struct software_node_ref_args *ref_args __free(kfree) =
|
||||
kcalloc(nbuttons, sizeof(*ref_args), GFP_KERNEL);
|
||||
kzalloc_objs(*ref_args, nbuttons);
|
||||
if (!ref_args)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -1134,7 +1134,7 @@ static int __init xive_init_ipis(void)
|
|||
if (!ipi_domain)
|
||||
goto out_free_fwnode;
|
||||
|
||||
xive_ipis = kzalloc_objs(*xive_ipis, nr_node_ids, GFP_KERNEL);
|
||||
xive_ipis = kzalloc_objs(*xive_ipis, nr_node_ids);
|
||||
if (!xive_ipis)
|
||||
goto out_free_domain;
|
||||
|
||||
|
|
|
|||
|
|
@ -503,8 +503,8 @@ int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low
|
|||
}
|
||||
}
|
||||
|
||||
einfo = kvcalloc(num_events, sizeof(*einfo),
|
||||
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
|
||||
einfo = kvzalloc_objs(*einfo, num_events,
|
||||
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
|
||||
if (!einfo) {
|
||||
ret = SBI_ERR_FAILURE;
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -2128,7 +2128,15 @@ bool bpf_jit_supports_ptr_xchg(void)
|
|||
|
||||
bool bpf_jit_supports_arena(void)
|
||||
{
|
||||
return true;
|
||||
/*
|
||||
* The arena range tree uses kmalloc_nolock(), which needs
|
||||
* cmpxchg128, provided by ZACAS on riscv.
|
||||
*/
|
||||
#ifdef system_has_cmpxchg128
|
||||
return system_has_cmpxchg128();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
|
||||
|
|
|
|||
|
|
@ -45,11 +45,12 @@ static void alt_debug_modify(int type, unsigned int nr, bool clear)
|
|||
|
||||
static char *alt_debug_parse(int type, char *str)
|
||||
{
|
||||
unsigned long val, endval;
|
||||
unsigned long val, endval, limit;
|
||||
char *endp;
|
||||
bool clear;
|
||||
int i;
|
||||
|
||||
limit = type == ALT_TYPE_FACILITY ? MAX_FACILITY_BIT : MAX_MFEATURE_BIT;
|
||||
if (*str == ':') {
|
||||
str++;
|
||||
} else {
|
||||
|
|
@ -73,7 +74,7 @@ static char *alt_debug_parse(int type, char *str)
|
|||
if (str == endp)
|
||||
break;
|
||||
str = endp;
|
||||
while (val <= endval) {
|
||||
while (val <= endval && val < limit) {
|
||||
alt_debug_modify(type, val, clear);
|
||||
val++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ struct parmarea parmarea __section(".parmarea") = {
|
|||
};
|
||||
|
||||
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
|
||||
static char command_line_buf[COMMAND_LINE_SIZE];
|
||||
|
||||
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
|
||||
struct ipl_parameter_block __bootdata_preserved(ipl_block);
|
||||
|
|
@ -135,31 +136,29 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
|
|||
|
||||
static void append_ipl_block_parm(void)
|
||||
{
|
||||
char *parm, *delim;
|
||||
size_t len, rc = 0;
|
||||
size_t len, extra = 0;
|
||||
char *delim;
|
||||
|
||||
len = strlen(early_command_line);
|
||||
|
||||
delim = early_command_line + len; /* '\0' character position */
|
||||
parm = early_command_line + len + 1; /* append right after '\0' */
|
||||
delim = early_command_line + len; /* '\0' character position */
|
||||
|
||||
switch (ipl_block.pb0_hdr.pbt) {
|
||||
case IPL_PBT_CCW:
|
||||
rc = ipl_block_get_ascii_vmparm(
|
||||
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
|
||||
extra = ipl_block_get_ascii_vmparm(command_line_buf, sizeof(command_line_buf), &ipl_block);
|
||||
break;
|
||||
case IPL_PBT_FCP:
|
||||
case IPL_PBT_NVME:
|
||||
case IPL_PBT_ECKD:
|
||||
rc = ipl_block_get_ascii_scpdata(
|
||||
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
|
||||
extra = ipl_block_get_ascii_scpdata(command_line_buf, sizeof(command_line_buf), &ipl_block);
|
||||
break;
|
||||
}
|
||||
if (rc) {
|
||||
if (*parm == '=')
|
||||
memmove(early_command_line, parm + 1, rc);
|
||||
else
|
||||
if (extra) {
|
||||
if (command_line_buf[0] == '=') {
|
||||
memmove(early_command_line, command_line_buf + 1, extra);
|
||||
} else if (len < COMMAND_LINE_SIZE - 2) {
|
||||
*delim = ' '; /* replace '\0' with space */
|
||||
sized_strscpy(delim + 1, command_line_buf, COMMAND_LINE_SIZE - len - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +230,7 @@ static void modify_fac_list(char *str)
|
|||
if (str == endp)
|
||||
break;
|
||||
str = endp;
|
||||
while (val <= endval) {
|
||||
while (val <= endval && val < MAX_FACILITY_BIT) {
|
||||
modify_facility(val, clear);
|
||||
val++;
|
||||
}
|
||||
|
|
@ -245,7 +244,6 @@ static void modify_fac_list(char *str)
|
|||
check_cleared_facilities();
|
||||
}
|
||||
|
||||
static char command_line_buf[COMMAND_LINE_SIZE];
|
||||
void parse_boot_command_line(void)
|
||||
{
|
||||
char *param, *val;
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ static int tprot(unsigned long addr)
|
|||
|
||||
static unsigned long search_mem_end(void)
|
||||
{
|
||||
unsigned long range = 1 << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
|
||||
unsigned long range = 1UL << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
|
||||
unsigned long offset = 0;
|
||||
unsigned long pivot;
|
||||
|
||||
|
|
|
|||
|
|
@ -301,6 +301,7 @@ static __always_inline void __cpacf_query(unsigned int opcode,
|
|||
cpacf_mask_t *mask)
|
||||
{
|
||||
__cpacf_query_insn(opcode, mask, CPACF_FC_QUERY);
|
||||
kmsan_unpoison_memory(mask, sizeof(*mask));
|
||||
}
|
||||
|
||||
static __always_inline int __cpacf_check_opcode(unsigned int opcode)
|
||||
|
|
@ -370,6 +371,7 @@ static __always_inline int cpacf_query_func(unsigned int opcode,
|
|||
static __always_inline void __cpacf_qai(unsigned int opcode, cpacf_qai_t *qai)
|
||||
{
|
||||
__cpacf_query_insn(opcode, qai, CPACF_FC_QUERY_AUTH_INFO);
|
||||
kmsan_unpoison_memory(qai, sizeof(*qai));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -422,6 +424,7 @@ static inline int cpacf_km(unsigned long func, void *param,
|
|||
[opc] "i" (CPACF_KM)
|
||||
: "cc", "memory", "0", "1");
|
||||
|
||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
||||
return src_len - s.odd;
|
||||
}
|
||||
|
||||
|
|
@ -454,6 +457,7 @@ static inline int cpacf_kmc(unsigned long func, void *param,
|
|||
[opc] "i" (CPACF_KMC)
|
||||
: "cc", "memory", "0", "1");
|
||||
|
||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
||||
return src_len - s.odd;
|
||||
}
|
||||
|
||||
|
|
@ -587,6 +591,7 @@ static inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
|
|||
[opc] "i" (CPACF_KMCTR)
|
||||
: "cc", "memory", "0", "1");
|
||||
|
||||
kmsan_unpoison_memory(dest, src_len - s.odd);
|
||||
return src_len - s.odd;
|
||||
}
|
||||
|
||||
|
|
@ -619,6 +624,7 @@ static inline void cpacf_prno(unsigned long func, void *param,
|
|||
: [fc] "d" (func), [pba] "d" ((unsigned long)param),
|
||||
[seed] "d" (s.pair), [opc] "i" (CPACF_PRNO)
|
||||
: "cc", "memory", "0", "1");
|
||||
kmsan_unpoison_memory(dest, dest_len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include <asm/isc.h>
|
||||
#include <asm/guarded_storage.h>
|
||||
|
||||
#define kvm_file_to_kvm_arch s390
|
||||
|
||||
#define KVM_HAVE_MMU_RWLOCK
|
||||
#define KVM_MAX_VCPUS 255
|
||||
|
||||
|
|
@ -720,7 +722,7 @@ static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
|
|||
void kvm_arch_free_vm(struct kvm *kvm);
|
||||
|
||||
struct zpci_kvm_hook {
|
||||
int (*kvm_register)(void *opaque, struct kvm *kvm);
|
||||
int (*kvm_register)(void *opaque, struct file *kvm_file);
|
||||
void (*kvm_unregister)(void *opaque);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ struct pcpu {
|
|||
unsigned long ec_mask; /* bit mask for ec_xxx functions */
|
||||
unsigned long ec_clk; /* sigp timestamp for ec_xxx */
|
||||
unsigned long flags; /* per CPU flags */
|
||||
unsigned long capacity; /* cpu capacity for scheduler */
|
||||
signed char state; /* physical cpu state */
|
||||
signed char polarization; /* physical polarization */
|
||||
u16 address; /* physical cpu address */
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static __always_inline unsigned int raw_smp_processor_id(void)
|
|||
return cpu;
|
||||
}
|
||||
|
||||
#define arch_scale_cpu_capacity smp_cpu_get_capacity
|
||||
#define arch_scale_cpu_capacity topology_get_cpu_scale
|
||||
|
||||
extern struct mutex smp_cpu_state_mutex;
|
||||
extern unsigned int smp_cpu_mt_shift;
|
||||
|
|
@ -53,9 +53,7 @@ extern void smp_save_dump_secondary_cpus(void);
|
|||
extern void smp_yield_cpu(int cpu);
|
||||
extern void smp_cpu_set_polarization(int cpu, int val);
|
||||
extern int smp_cpu_get_polarization(int cpu);
|
||||
extern void smp_cpu_set_capacity(int cpu, unsigned long val);
|
||||
extern void smp_set_core_capacity(int cpu, unsigned long val);
|
||||
extern unsigned long smp_cpu_get_capacity(int cpu);
|
||||
extern int smp_cpu_get_cpu_address(int cpu);
|
||||
extern void smp_fill_possible_mask(void);
|
||||
extern void smp_detect_cpus(void);
|
||||
|
|
|
|||
|
|
@ -182,8 +182,7 @@ long diag324_pibbuf(unsigned long arg)
|
|||
goto out;
|
||||
rc = copy_to_user((void __user *)address, data->pib, data->pib->len);
|
||||
rc |= put_user(data->sequence, &udata->sequence);
|
||||
if (rc)
|
||||
rc = -EFAULT;
|
||||
rc = rc ? -EFAULT : data->rc;
|
||||
out:
|
||||
mutex_unlock(&pibmutex);
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -1157,6 +1157,8 @@ static struct attribute_group reipl_nss_attr_group = {
|
|||
|
||||
void set_os_info_reipl_block(void)
|
||||
{
|
||||
if (!reipl_block_actual)
|
||||
return;
|
||||
os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
|
||||
reipl_block_actual->hdr.len);
|
||||
}
|
||||
|
|
@ -1927,7 +1929,8 @@ static struct shutdown_action __refdata dump_action = {
|
|||
static void dump_reipl_run(struct shutdown_trigger *trigger)
|
||||
{
|
||||
struct lowcore *abs_lc;
|
||||
unsigned int csum;
|
||||
unsigned long ipib = 0;
|
||||
unsigned int csum = 0;
|
||||
|
||||
/*
|
||||
* Set REIPL_CLEAR flag in os_info flags entry indicating
|
||||
|
|
@ -1943,9 +1946,12 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
|
|||
reipl_type == IPL_TYPE_UNKNOWN)
|
||||
os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
|
||||
os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
|
||||
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
|
||||
if (reipl_block_actual) {
|
||||
ipib = __pa(reipl_block_actual);
|
||||
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
|
||||
}
|
||||
abs_lc = get_abs_lowcore();
|
||||
abs_lc->ipib = __pa(reipl_block_actual);
|
||||
abs_lc->ipib = ipib;
|
||||
abs_lc->ipib_checksum = csum;
|
||||
put_abs_lowcore(abs_lc);
|
||||
dump_run(trigger);
|
||||
|
|
|
|||
|
|
@ -464,6 +464,7 @@ static void pai_start(struct perf_event *event, int flags,
|
|||
cpump->event = event;
|
||||
}
|
||||
}
|
||||
event->hw.state &= ~PERF_HES_STOPPED;
|
||||
}
|
||||
|
||||
static void paicrypt_start(struct perf_event *event, int flags)
|
||||
|
|
@ -510,6 +511,13 @@ static void pai_stop(struct perf_event *event, int flags)
|
|||
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
|
||||
struct pai_map *cpump = mp->mapptr;
|
||||
|
||||
/* Cope with multiple invocations:
|
||||
* 1. perf_event_throttle() --> PMU->stop()
|
||||
* 2. task schedules out --> PMU->stop()
|
||||
* Check for event already stopped.
|
||||
*/
|
||||
if (event->hw.state & PERF_HES_STOPPED)
|
||||
return;
|
||||
if (!event->attr.sample_period) { /* Counting */
|
||||
pai_pmu[idx].pmu->read(event);
|
||||
} else { /* Sampling */
|
||||
|
|
@ -672,9 +680,9 @@ static void pai_have_samples(int idx)
|
|||
{
|
||||
struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr);
|
||||
struct pai_map *cpump = mp->mapptr;
|
||||
struct perf_event *event;
|
||||
struct perf_event *event, *e2;
|
||||
|
||||
list_for_each_entry(event, &cpump->syswide_list, hw.tp_list)
|
||||
list_for_each_entry_safe(event, e2, &cpump->syswide_list, hw.tp_list)
|
||||
pai_have_sample(event, cpump);
|
||||
}
|
||||
|
||||
|
|
@ -691,6 +699,17 @@ static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx,
|
|||
pai_have_samples(PAI_PMU_CRYPTO);
|
||||
}
|
||||
|
||||
/* Prevent ioctl(fd, PERF_EVENT_IOC_PERIOD, ...) call.
|
||||
* It sets perf_event::event_limit to a positive value and causes
|
||||
* perf_event_overflow() to invoke pai_stop() call back function when
|
||||
* perf_event::event_limit hits zero. This is not supported because the
|
||||
* sample events CRYPTO_ALL and NNPA_ALL are always taken at schedule out
|
||||
* of a task.
|
||||
*/
|
||||
static int pai_check_period(struct perf_event *event, u64 value)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
/* ============================= paiext ====================================*/
|
||||
|
||||
static void paiext_event_destroy(struct perf_event *event)
|
||||
|
|
@ -804,6 +823,7 @@ static struct pmu paicrypt = {
|
|||
.stop = paicrypt_stop,
|
||||
.read = paicrypt_read,
|
||||
.sched_task = paicrypt_sched_task,
|
||||
.check_period = pai_check_period,
|
||||
.attr_groups = paicrypt_attr_groups
|
||||
};
|
||||
|
||||
|
|
@ -1015,6 +1035,7 @@ static struct pmu paiext = {
|
|||
.stop = paiext_stop,
|
||||
.read = paiext_read,
|
||||
.sched_task = paiext_sched_task,
|
||||
.check_period = pai_check_period,
|
||||
.attr_groups = paiext_attr_groups,
|
||||
};
|
||||
|
||||
|
|
@ -1221,7 +1242,7 @@ static int __init paipmu_setup(void)
|
|||
static int __init pai_init(void)
|
||||
{
|
||||
/* Setup s390dbf facility */
|
||||
paidbg = debug_register("pai", 32, 256, 128);
|
||||
paidbg = debug_register("pai", 1, 1, 128);
|
||||
if (!paidbg) {
|
||||
pr_err("Registration of s390dbf pai failed\n");
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -659,23 +659,13 @@ int smp_cpu_get_polarization(int cpu)
|
|||
return per_cpu(pcpu_devices, cpu).polarization;
|
||||
}
|
||||
|
||||
void smp_cpu_set_capacity(int cpu, unsigned long val)
|
||||
{
|
||||
per_cpu(pcpu_devices, cpu).capacity = val;
|
||||
}
|
||||
|
||||
unsigned long smp_cpu_get_capacity(int cpu)
|
||||
{
|
||||
return per_cpu(pcpu_devices, cpu).capacity;
|
||||
}
|
||||
|
||||
void smp_set_core_capacity(int cpu, unsigned long val)
|
||||
{
|
||||
int i;
|
||||
|
||||
cpu = smp_get_base_cpu(cpu);
|
||||
for (i = cpu; (i <= cpu + smp_cpu_mtid) && (i < nr_cpu_ids); i++)
|
||||
smp_cpu_set_capacity(i, val);
|
||||
topology_set_cpu_scale(i, val);
|
||||
}
|
||||
|
||||
int smp_cpu_get_cpu_address(int cpu)
|
||||
|
|
@ -727,7 +717,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail,
|
|||
else
|
||||
pcpu->state = CPU_STATE_STANDBY;
|
||||
smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
|
||||
smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
|
||||
topology_set_cpu_scale(cpu, CPU_CAPACITY_HIGH);
|
||||
set_cpu_present(cpu, true);
|
||||
if (!early && arch_register_cpu(cpu))
|
||||
set_cpu_present(cpu, false);
|
||||
|
|
@ -967,7 +957,7 @@ void __init smp_prepare_boot_cpu(void)
|
|||
ipl_pcpu->state = CPU_STATE_CONFIGURED;
|
||||
lc->pcpu = (unsigned long)ipl_pcpu;
|
||||
smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
|
||||
smp_cpu_set_capacity(0, CPU_CAPACITY_HIGH);
|
||||
topology_set_cpu_scale(0, CPU_CAPACITY_HIGH);
|
||||
}
|
||||
|
||||
void __init smp_setup_processor_id(void)
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ static void add_cpus_to_mask(struct topology_core *tl_core,
|
|||
cpumask_set_cpu(cpu, &book->mask);
|
||||
cpumask_set_cpu(cpu, &socket->mask);
|
||||
smp_cpu_set_polarization(cpu, tl_core->pp);
|
||||
smp_cpu_set_capacity(cpu, CPU_CAPACITY_HIGH);
|
||||
topology_set_cpu_scale(cpu, CPU_CAPACITY_HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ static atomic64_t virt_timer_elapsed;
|
|||
DEFINE_PER_CPU(u64, mt_cycles[8]);
|
||||
static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
|
||||
static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
|
||||
static DEFINE_PER_CPU(u64, mt_scaling_jiffies);
|
||||
static DEFINE_PER_CPU(unsigned long, mt_scaling_jiffies);
|
||||
|
||||
static inline void set_vtimer(u64 expires)
|
||||
{
|
||||
|
|
@ -81,7 +81,7 @@ static void update_mt_scaling(void)
|
|||
memcpy(cycles_old, cycles_new,
|
||||
sizeof(u64) * (smp_cpu_mtid + 1));
|
||||
}
|
||||
__this_cpu_write(mt_scaling_jiffies, jiffies_64);
|
||||
__this_cpu_write(mt_scaling_jiffies, jiffies);
|
||||
}
|
||||
|
||||
static inline u64 update_tsk_timer(unsigned long *tsk_vtime, u64 new)
|
||||
|
|
@ -144,7 +144,7 @@ static int do_account_vtime(struct task_struct *tsk)
|
|||
lc->system_timer += timer;
|
||||
|
||||
/* Update MT utilization calculation */
|
||||
if (smp_cpu_mtid && time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies)))
|
||||
if (smp_cpu_mtid && time_after(jiffies, __this_cpu_read(mt_scaling_jiffies)))
|
||||
update_mt_scaling();
|
||||
|
||||
/* Calculate cputime delta */
|
||||
|
|
|
|||
|
|
@ -498,17 +498,22 @@ static void kvm_s390_pci_dev_release(struct zpci_dev *zdev)
|
|||
* available, enable them and let userspace indicate whether or not they will
|
||||
* be used (specify SHM bit to disable).
|
||||
*/
|
||||
static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
|
||||
static int kvm_s390_pci_register_kvm(void *opaque, struct file *kvm_file)
|
||||
{
|
||||
struct zpci_dev *zdev = opaque;
|
||||
struct kvm *kvm;
|
||||
int rc;
|
||||
|
||||
if (!zdev)
|
||||
return -EINVAL;
|
||||
|
||||
kvm = file_to_kvm_s390(kvm_file);
|
||||
if (!kvm)
|
||||
return -ENOENT;
|
||||
|
||||
mutex_lock(&zdev->kzdev_lock);
|
||||
|
||||
if (zdev->kzdev || zdev->gisa != 0 || !kvm) {
|
||||
if (zdev->kzdev || zdev->gisa != 0) {
|
||||
mutex_unlock(&zdev->kzdev_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2168,7 +2168,7 @@ static int kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
|
|||
if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
keys = kvmalloc_array(args->count, sizeof(*keys), GFP_KERNEL_ACCOUNT);
|
||||
keys = kvmalloc_objs(*keys, args->count, GFP_KERNEL_ACCOUNT);
|
||||
if (!keys)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -2205,7 +2205,7 @@ static int kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
|
|||
if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
keys = kvmalloc_array(args->count, sizeof(*keys), GFP_KERNEL_ACCOUNT);
|
||||
keys = kvmalloc_objs(*keys, args->count, GFP_KERNEL_ACCOUNT);
|
||||
if (!keys)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,63 +55,46 @@ static void __crst_table_upgrade(void *arg)
|
|||
|
||||
int crst_table_upgrade(struct mm_struct *mm, unsigned long end)
|
||||
{
|
||||
unsigned long *pgd = NULL, *p4d = NULL, *__pgd;
|
||||
unsigned long asce_limit = mm->context.asce_limit;
|
||||
unsigned long *table, *pgd;
|
||||
int rc, notify;
|
||||
|
||||
mmap_assert_write_locked(mm);
|
||||
|
||||
/* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */
|
||||
VM_BUG_ON(asce_limit < _REGION2_SIZE);
|
||||
|
||||
if (end <= asce_limit)
|
||||
return 0;
|
||||
|
||||
if (asce_limit == _REGION2_SIZE) {
|
||||
p4d = crst_table_alloc(mm);
|
||||
if (unlikely(!p4d))
|
||||
goto err_p4d;
|
||||
crst_table_init(p4d, _REGION2_ENTRY_EMPTY);
|
||||
pagetable_p4d_ctor(virt_to_ptdesc(p4d));
|
||||
VM_BUG_ON(mm->context.asce_limit < _REGION2_SIZE);
|
||||
rc = 0;
|
||||
notify = 0;
|
||||
while (mm->context.asce_limit < end) {
|
||||
table = crst_table_alloc(mm);
|
||||
if (!table) {
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
spin_lock_bh(&mm->page_table_lock);
|
||||
pgd = (unsigned long *)mm->pgd;
|
||||
if (mm->context.asce_limit == _REGION2_SIZE) {
|
||||
crst_table_init(table, _REGION2_ENTRY_EMPTY);
|
||||
p4d_populate(mm, (p4d_t *)table, (pud_t *)pgd);
|
||||
pagetable_p4d_ctor(virt_to_ptdesc(table));
|
||||
mm->pgd = (pgd_t *)table;
|
||||
mm->context.asce_limit = _REGION1_SIZE;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
||||
mm_inc_nr_puds(mm);
|
||||
} else {
|
||||
crst_table_init(table, _REGION1_ENTRY_EMPTY);
|
||||
pgd_populate(mm, (pgd_t *)table, (p4d_t *)pgd);
|
||||
pagetable_pgd_ctor(virt_to_ptdesc(table));
|
||||
mm->pgd = (pgd_t *)table;
|
||||
mm->context.asce_limit = TASK_SIZE_MAX;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
|
||||
}
|
||||
notify = 1;
|
||||
spin_unlock_bh(&mm->page_table_lock);
|
||||
}
|
||||
if (end > _REGION1_SIZE) {
|
||||
pgd = crst_table_alloc(mm);
|
||||
if (unlikely(!pgd))
|
||||
goto err_pgd;
|
||||
crst_table_init(pgd, _REGION1_ENTRY_EMPTY);
|
||||
pagetable_pgd_ctor(virt_to_ptdesc(pgd));
|
||||
}
|
||||
|
||||
spin_lock_bh(&mm->page_table_lock);
|
||||
|
||||
if (p4d) {
|
||||
__pgd = (unsigned long *) mm->pgd;
|
||||
p4d_populate(mm, (p4d_t *) p4d, (pud_t *) __pgd);
|
||||
mm->pgd = (pgd_t *) p4d;
|
||||
mm->context.asce_limit = _REGION1_SIZE;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
||||
mm_inc_nr_puds(mm);
|
||||
}
|
||||
if (pgd) {
|
||||
__pgd = (unsigned long *) mm->pgd;
|
||||
pgd_populate(mm, (pgd_t *) pgd, (p4d_t *) __pgd);
|
||||
mm->pgd = (pgd_t *) pgd;
|
||||
mm->context.asce_limit = TASK_SIZE_MAX;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&mm->page_table_lock);
|
||||
|
||||
on_each_cpu(__crst_table_upgrade, mm, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
err_pgd:
|
||||
pagetable_dtor(virt_to_ptdesc(p4d));
|
||||
crst_table_free(mm, p4d);
|
||||
err_p4d:
|
||||
return -ENOMEM;
|
||||
if (notify)
|
||||
on_each_cpu(__crst_table_upgrade, mm, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
unsigned long *page_table_alloc_noprof(struct mm_struct *mm)
|
||||
|
|
|
|||
|
|
@ -153,6 +153,9 @@ static ssize_t report_error_write(struct file *filp, struct kobject *kobj,
|
|||
if (off || (count < sizeof(*report)))
|
||||
return -EINVAL;
|
||||
|
||||
if (count < (report->length + sizeof(*report)))
|
||||
return -EINVAL;
|
||||
|
||||
ret = sclp_pci_report(report, zdev->fh, zdev->fid);
|
||||
|
||||
return ret ? ret : count;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@
|
|||
|
||||
#include <hyperv/hvhdk.h>
|
||||
|
||||
#define kvm_file_to_kvm_arch x86
|
||||
|
||||
#define __KVM_HAVE_ARCH_VCPU_DEBUGFS
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -44,13 +44,15 @@ struct kvm_page_track_notifier_node {
|
|||
struct kvm_page_track_notifier_node *node);
|
||||
};
|
||||
|
||||
int kvm_page_track_register_notifier(struct kvm *kvm,
|
||||
struct file;
|
||||
|
||||
int kvm_page_track_register_notifier(struct file *file,
|
||||
struct kvm_page_track_notifier_node *n);
|
||||
void kvm_page_track_unregister_notifier(struct kvm *kvm,
|
||||
void kvm_page_track_unregister_notifier(struct file *file,
|
||||
struct kvm_page_track_notifier_node *n);
|
||||
|
||||
int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn);
|
||||
int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn);
|
||||
int kvm_write_track_add_gfn(struct file *file, gfn_t gfn);
|
||||
int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn);
|
||||
#else
|
||||
/*
|
||||
* Allow defining a node in a structure even if page tracking is disabled, e.g.
|
||||
|
|
|
|||
|
|
@ -110,18 +110,14 @@ int sched_set_itmt_support(void)
|
|||
arch_debugfs_dir,
|
||||
&sysctl_sched_itmt_enabled,
|
||||
&dfs_sched_itmt_fops);
|
||||
if (IS_ERR_OR_NULL(dfs_sched_itmt)) {
|
||||
if (IS_ERR(dfs_sched_itmt))
|
||||
dfs_sched_itmt = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dfs_sched_core_prio = debugfs_create_file("sched_core_priority", 0644,
|
||||
arch_debugfs_dir, NULL,
|
||||
&sched_core_priority_fops);
|
||||
if (IS_ERR_OR_NULL(dfs_sched_core_prio)) {
|
||||
if (IS_ERR(dfs_sched_core_prio))
|
||||
dfs_sched_core_prio = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sched_itmt_capable = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -61,9 +61,7 @@ exports_grep_trailer := --include='*.[ch]' -nrw $(srctree)/virt/kvm $(srctree)/a
|
|||
-e kvm_page_track_unregister_notifier \
|
||||
-e kvm_write_track_add_gfn \
|
||||
-e kvm_write_track_remove_gfn \
|
||||
-e kvm_get_kvm \
|
||||
-e kvm_get_kvm_safe \
|
||||
-e kvm_put_kvm
|
||||
-e kvm_file_to_kvm_fn
|
||||
|
||||
# Force grep to emit a goofy group separator that can in turn be replaced with
|
||||
# the above newline macro (newlines in Make are a nightmare). Note, grep only
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#include <linux/kvm_host.h>
|
||||
#include <linux/rculist.h>
|
||||
|
||||
#include <asm/kvm_page_track.h>
|
||||
|
||||
#include "mmu.h"
|
||||
#include "mmu_internal.h"
|
||||
#include "page_track.h"
|
||||
|
|
@ -237,10 +239,11 @@ static int kvm_enable_external_write_tracking(struct kvm *kvm)
|
|||
* register the notifier so that event interception for the tracked guest
|
||||
* pages can be received.
|
||||
*/
|
||||
int kvm_page_track_register_notifier(struct kvm *kvm,
|
||||
int kvm_page_track_register_notifier(struct file *file,
|
||||
struct kvm_page_track_notifier_node *n)
|
||||
{
|
||||
struct kvm_page_track_notifier_head *head;
|
||||
struct kvm *kvm = file_to_kvm_x86(file);
|
||||
int r;
|
||||
|
||||
if (!kvm || kvm->mm != current->mm)
|
||||
|
|
@ -252,7 +255,7 @@ int kvm_page_track_register_notifier(struct kvm *kvm,
|
|||
return r;
|
||||
}
|
||||
|
||||
kvm_get_kvm(kvm);
|
||||
get_file(file);
|
||||
|
||||
head = &kvm->arch.track_notifier_head;
|
||||
|
||||
|
|
@ -267,10 +270,11 @@ EXPORT_SYMBOL_GPL(kvm_page_track_register_notifier);
|
|||
* stop receiving the event interception. It is the opposed operation of
|
||||
* kvm_page_track_register_notifier().
|
||||
*/
|
||||
void kvm_page_track_unregister_notifier(struct kvm *kvm,
|
||||
void kvm_page_track_unregister_notifier(struct file *file,
|
||||
struct kvm_page_track_notifier_node *n)
|
||||
{
|
||||
struct kvm_page_track_notifier_head *head;
|
||||
struct kvm *kvm = file_to_kvm_x86(file);
|
||||
|
||||
head = &kvm->arch.track_notifier_head;
|
||||
|
||||
|
|
@ -279,7 +283,7 @@ void kvm_page_track_unregister_notifier(struct kvm *kvm,
|
|||
write_unlock(&kvm->mmu_lock);
|
||||
synchronize_srcu(&head->track_srcu);
|
||||
|
||||
kvm_put_kvm(kvm);
|
||||
fput(file);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_page_track_unregister_notifier);
|
||||
|
||||
|
|
@ -336,11 +340,12 @@ void kvm_page_track_delete_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
|
|||
* add guest page to the tracking pool so that corresponding access on that
|
||||
* page will be intercepted.
|
||||
*
|
||||
* @kvm: the guest instance we are interested in.
|
||||
* @file: the VM file of the guest instance we are interested in.
|
||||
* @gfn: the guest page.
|
||||
*/
|
||||
int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn)
|
||||
int kvm_write_track_add_gfn(struct file *file, gfn_t gfn)
|
||||
{
|
||||
struct kvm *kvm = file_to_kvm_x86(file);
|
||||
struct kvm_memory_slot *slot;
|
||||
int idx;
|
||||
|
||||
|
|
@ -366,11 +371,12 @@ EXPORT_SYMBOL_GPL(kvm_write_track_add_gfn);
|
|||
* remove the guest page from the tracking pool which stops the interception
|
||||
* of corresponding access on that page.
|
||||
*
|
||||
* @kvm: the guest instance we are interested in.
|
||||
* @file: the VM file of the guest instance we are interested in.
|
||||
* @gfn: the guest page.
|
||||
*/
|
||||
int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn)
|
||||
int kvm_write_track_remove_gfn(struct file *file, gfn_t gfn)
|
||||
{
|
||||
struct kvm *kvm = file_to_kvm_x86(file);
|
||||
struct kvm_memory_slot *slot;
|
||||
int idx;
|
||||
|
||||
|
|
|
|||
|
|
@ -2145,10 +2145,10 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
|
|||
if (fd_empty(f))
|
||||
return -EBADF;
|
||||
|
||||
if (!file_is_kvm(fd_file(f)))
|
||||
source_kvm = file_to_kvm_x86(fd_file(f));
|
||||
if (!source_kvm)
|
||||
return -EBADF;
|
||||
|
||||
source_kvm = fd_file(f)->private_data;
|
||||
ret = sev_lock_two_vms(kvm, source_kvm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -2866,10 +2866,10 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
|
|||
if (fd_empty(f))
|
||||
return -EBADF;
|
||||
|
||||
if (!file_is_kvm(fd_file(f)))
|
||||
source_kvm = file_to_kvm_x86(fd_file(f));
|
||||
if (!source_kvm)
|
||||
return -EBADF;
|
||||
|
||||
source_kvm = fd_file(f)->private_data;
|
||||
ret = sev_lock_two_vms(kvm, source_kvm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/bpf_verifier.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/execmem.h>
|
||||
#include <asm/extable.h>
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/set_memory.h>
|
||||
|
|
@ -3818,15 +3819,16 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
|
|||
*
|
||||
* We cannot use kvmalloc here, because we need image to be in
|
||||
* module memory range.
|
||||
* Since it must be writable use bpf_jit_alloc_exec_rw().
|
||||
* Since it must be writable use execmem_alloc(EXECMEM_MODULE_DATA)
|
||||
* that returns writable memory in the module address space.
|
||||
*/
|
||||
image = bpf_jit_alloc_exec_rw(PAGE_SIZE);
|
||||
image = execmem_alloc(EXECMEM_MODULE_DATA, PAGE_SIZE);
|
||||
if (!image)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = __arch_prepare_bpf_trampoline(&im, image, image + PAGE_SIZE, image,
|
||||
m, flags, tnodes, func_addr);
|
||||
bpf_jit_free_exec(image);
|
||||
execmem_free(image);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -859,6 +859,7 @@ static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
|
|||
bio->bi_ioprio = bio_src->bi_ioprio;
|
||||
bio->bi_write_hint = bio_src->bi_write_hint;
|
||||
bio->bi_write_stream = bio_src->bi_write_stream;
|
||||
bio->bi_bvec_gap_bit = bio_src->bi_bvec_gap_bit;
|
||||
bio->bi_iter = bio_src->bi_iter;
|
||||
bio->bi_io_vec = bio_src->bi_io_vec;
|
||||
|
||||
|
|
@ -1972,6 +1973,14 @@ struct bio *bio_split(struct bio *bio, int sectors,
|
|||
|
||||
bio_advance(bio, split->bi_iter.bi_size);
|
||||
|
||||
/*
|
||||
* The gap bit is set when splitting to limits and only applies to the
|
||||
* front bio that was split off. The remaining bio will calcualte its
|
||||
* gap value when it is subsequently split to limits, so it is safe to
|
||||
* re-initialize the value back to 0.
|
||||
*/
|
||||
bio->bi_bvec_gap_bit = 0;
|
||||
|
||||
if (bio_flagged(bio, BIO_TRACE_COMPLETION))
|
||||
bio_set_flag(split, BIO_TRACE_COMPLETION);
|
||||
|
||||
|
|
|
|||
|
|
@ -447,6 +447,13 @@ static int __add_disk(struct device *parent, struct gendisk *disk,
|
|||
bdev_set_flag(disk->part0, BD_HAS_SUBMIT_BIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not support partitions with zoned block devices, so do not try
|
||||
* to scan the partitions table.
|
||||
*/
|
||||
if (blk_queue_is_zoned(disk->queue))
|
||||
disk->flags |= GENHD_FL_NO_PART;
|
||||
|
||||
/*
|
||||
* If the driver provides an explicit major number it also must provide
|
||||
* the number of minors numbers supported, and those will be used to
|
||||
|
|
|
|||
|
|
@ -994,7 +994,7 @@ int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx,
|
|||
}
|
||||
|
||||
ccnt = payload->command_count;
|
||||
if (payload_len < struct_size(payload, data, ccnt)) {
|
||||
if (!ccnt || payload_len < struct_size(payload, data, ccnt)) {
|
||||
XDNA_DBG(xdna, "Invalid command count %d", ccnt);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,8 +183,10 @@ int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo,
|
|||
if (!abo)
|
||||
return -EINVAL;
|
||||
cmd = amdxdna_gem_vmap(abo);
|
||||
if (!cmd)
|
||||
if (!cmd) {
|
||||
amdxdna_gem_put_obj(abo);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
memset(cmd->data, 0xff, abo->mem.size - sizeof(*cmd));
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ struct amdxdna_cmd_chain {
|
|||
u32 submit_index;
|
||||
u32 error_index;
|
||||
u32 reserved[3];
|
||||
u64 data[] __counted_by(command_count);
|
||||
u64 data[];
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1246,6 +1246,9 @@ static int amdxdna_flush_bo(struct amdxdna_gem_obj *abo, u64 offset, u64 size)
|
|||
{
|
||||
u64 end;
|
||||
|
||||
if (is_import_bo(abo))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (offset >= abo->mem.size)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -1253,9 +1256,10 @@ static int amdxdna_flush_bo(struct amdxdna_gem_obj *abo, u64 offset, u64 size)
|
|||
return -EINVAL;
|
||||
|
||||
size = min(abo->mem.size, end) - offset;
|
||||
if (is_import_bo(abo))
|
||||
drm_clflush_sg(abo->base.sgt);
|
||||
else if (amdxdna_gem_vmap(abo))
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
if (amdxdna_gem_vmap(abo))
|
||||
drm_clflush_virt_range(amdxdna_gem_vmap(abo) + offset, size);
|
||||
else if (abo->base.pages)
|
||||
drm_clflush_pages(abo->base.pages, abo->mem.size >> PAGE_SHIFT);
|
||||
|
|
|
|||
|
|
@ -356,6 +356,8 @@ static int ethosu_probe(struct platform_device *pdev)
|
|||
dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40));
|
||||
|
||||
ethosudev->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ethosudev->regs))
|
||||
return PTR_ERR(ethosudev->regs);
|
||||
ethosudev->pmu_regs = ethosudev->regs;
|
||||
|
||||
ethosudev->num_clks = devm_clk_bulk_get_all(&pdev->dev, ðosudev->clks);
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ static u64 feat_matrix_length(struct ethosu_device *edev,
|
|||
struct feat_matrix *fm,
|
||||
u32 x, u32 y, u32 c, bool ofm)
|
||||
{
|
||||
u32 element_size, storage = fm->precision >> 14;
|
||||
u32 element_size, storage = ethosu_is_u65(edev) ? 0 : fm->precision >> 14;
|
||||
int tile = 0;
|
||||
u64 addr;
|
||||
|
||||
|
|
|
|||
|
|
@ -154,6 +154,13 @@ static void ethosu_job_err_cleanup(struct ethosu_job *job)
|
|||
|
||||
drm_gem_object_put(job->cmd_bo);
|
||||
|
||||
if (job->done_fence) {
|
||||
if (dma_fence_was_initialized(job->done_fence))
|
||||
dma_fence_put(job->done_fence);
|
||||
else
|
||||
dma_fence_free(job->done_fence);
|
||||
}
|
||||
|
||||
kfree(job);
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +171,6 @@ static void ethosu_job_cleanup(struct kref *ref)
|
|||
|
||||
pm_runtime_put_autosuspend(job->dev->base.dev);
|
||||
|
||||
dma_fence_put(job->done_fence);
|
||||
dma_fence_put(job->inference_done_fence);
|
||||
|
||||
ethosu_job_err_cleanup(job);
|
||||
|
|
@ -415,7 +421,7 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file
|
|||
ejob->done_fence = kzalloc_obj(*ejob->done_fence);
|
||||
if (!ejob->done_fence) {
|
||||
ret = -ENOMEM;
|
||||
goto out_cleanup_job;
|
||||
goto out_put_job;
|
||||
}
|
||||
|
||||
ret = drm_sched_job_init(&ejob->base,
|
||||
|
|
|
|||
|
|
@ -963,11 +963,13 @@ static int decode_status(struct qaic_device *qdev, void *trans, struct manage_ms
|
|||
|
||||
static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
|
||||
struct wire_msg *msg, struct ioctl_resources *resources,
|
||||
struct qaic_user *usr)
|
||||
struct qaic_user *usr, bool orphaned_deactivate)
|
||||
{
|
||||
u32 msg_hdr_count = le32_to_cpu(msg->hdr.count);
|
||||
u32 msg_hdr_len = le32_to_cpu(msg->hdr.len);
|
||||
struct wire_trans_hdr *trans_hdr;
|
||||
u32 msg_len = 0;
|
||||
int trans_type;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
|
@ -975,10 +977,12 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
|
|||
msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)
|
||||
return -EINVAL;
|
||||
|
||||
user_msg->len = 0;
|
||||
user_msg->count = le32_to_cpu(msg->hdr.count);
|
||||
if (user_msg) {
|
||||
user_msg->len = 0;
|
||||
user_msg->count = msg_hdr_count;
|
||||
}
|
||||
|
||||
for (i = 0; i < user_msg->count; ++i) {
|
||||
for (i = 0; i < msg_hdr_count; ++i) {
|
||||
u32 hdr_len;
|
||||
|
||||
if (msg_len > msg_hdr_len - sizeof(*trans_hdr))
|
||||
|
|
@ -990,7 +994,20 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
|
|||
size_add(msg_len, hdr_len) > msg_hdr_len)
|
||||
return -EINVAL;
|
||||
|
||||
switch (le32_to_cpu(trans_hdr->type)) {
|
||||
trans_type = le32_to_cpu(trans_hdr->type);
|
||||
/*
|
||||
* orphaned_deactivate is the case where a deactivate response
|
||||
* is received from the device after the user owning the DBC,
|
||||
* and the message requesting deactivation, has gone away.
|
||||
* In this case, only process QAIC_TRANS_DEACTIVATE_FROM_DEV
|
||||
* transaction and skip the others.
|
||||
*/
|
||||
if (orphaned_deactivate && trans_type != QAIC_TRANS_DEACTIVATE_FROM_DEV) {
|
||||
msg_len += hdr_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (trans_type) {
|
||||
case QAIC_TRANS_PASSTHROUGH_FROM_DEV:
|
||||
ret = decode_passthrough(qdev, trans_hdr, user_msg, &msg_len);
|
||||
break;
|
||||
|
|
@ -1281,7 +1298,7 @@ static int qaic_manage(struct qaic_device *qdev, struct qaic_user *usr, struct m
|
|||
goto dma_cont_failed;
|
||||
}
|
||||
|
||||
ret = decode_message(qdev, user_msg, rsp, &resources, usr);
|
||||
ret = decode_message(qdev, user_msg, rsp, &resources, usr, false);
|
||||
|
||||
dma_cont_failed:
|
||||
free_dbc_buf(qdev, &resources);
|
||||
|
|
@ -1446,22 +1463,7 @@ static void resp_worker(struct work_struct *work)
|
|||
* response to the QAIC_TRANS_TERMINATE_TO_DEV transaction,
|
||||
* otherwise, the user can issue an soc_reset to the device.
|
||||
*/
|
||||
u32 msg_count = le32_to_cpu(msg->hdr.count);
|
||||
u32 msg_len = le32_to_cpu(msg->hdr.len);
|
||||
u32 len = 0;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < msg_count && len < msg_len; ++j) {
|
||||
struct wire_trans_hdr *trans_hdr;
|
||||
|
||||
trans_hdr = (struct wire_trans_hdr *)(msg->data + len);
|
||||
if (le32_to_cpu(trans_hdr->type) == QAIC_TRANS_DEACTIVATE_FROM_DEV) {
|
||||
if (decode_deactivate(qdev, trans_hdr, &len, NULL))
|
||||
len += le32_to_cpu(trans_hdr->len);
|
||||
} else {
|
||||
len += le32_to_cpu(trans_hdr->len);
|
||||
}
|
||||
}
|
||||
decode_message(qdev, NULL, msg, NULL, NULL, true);
|
||||
/* request must have timed out, drop packet */
|
||||
kfree(msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ static int rocket_job_push(struct rocket_job *job)
|
|||
if (check_add_overflow(job->in_bo_count, job->out_bo_count, &bo_count))
|
||||
return -EINVAL;
|
||||
|
||||
bos = kvmalloc_array(bo_count, sizeof(*bos), GFP_KERNEL);
|
||||
bos = kvmalloc_objs(*bos, bo_count);
|
||||
if (!bos)
|
||||
return -ENOMEM;
|
||||
memcpy(bos, job->in_bos, job->in_bo_count * sizeof(void *));
|
||||
|
|
|
|||
|
|
@ -486,7 +486,8 @@ static u32 acpi_add_prt_dep(acpi_handle handle)
|
|||
if (ACPI_FAILURE(status))
|
||||
continue;
|
||||
dep_devices.count = 1;
|
||||
dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL);
|
||||
dep_devices.handles = kzalloc_objs(*dep_devices.handles,
|
||||
1);
|
||||
if (!dep_devices.handles) {
|
||||
acpi_handle_err(handle, "failed to allocate memory\n");
|
||||
continue;
|
||||
|
|
@ -499,7 +500,8 @@ static u32 acpi_add_prt_dep(acpi_handle handle)
|
|||
if (!gsi_handle)
|
||||
continue;
|
||||
dep_devices.count = 1;
|
||||
dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL);
|
||||
dep_devices.handles = kzalloc_objs(*dep_devices.handles,
|
||||
1);
|
||||
if (!dep_devices.handles) {
|
||||
acpi_handle_err(handle, "failed to allocate memory\n");
|
||||
continue;
|
||||
|
|
@ -526,7 +528,7 @@ static u32 acpi_add_irq_dep(acpi_handle handle)
|
|||
continue;
|
||||
|
||||
dep_devices.count = 1;
|
||||
dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL);
|
||||
dep_devices.handles = kzalloc_objs(*dep_devices.handles, 1);
|
||||
if (!dep_devices.handles) {
|
||||
acpi_handle_err(handle, "failed to allocate memory\n");
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@
|
|||
#include "internal.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#define ACPI_BUS_CLASS "system_bus"
|
||||
#define ACPI_BUS_HID "LNXSYBUS"
|
||||
#define ACPI_BUS_DEVICE_NAME "System Bus"
|
||||
|
||||
#define INVALID_ACPI_HANDLE ((acpi_handle)ZERO_PAGE(0))
|
||||
|
||||
|
|
@ -1450,8 +1448,6 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
|
|||
acpi_object_is_system_bus(handle)) {
|
||||
/* \_SB, \_TZ, LNXSYBUS */
|
||||
acpi_add_id(pnp, ACPI_BUS_HID);
|
||||
strscpy(pnp->device_name, ACPI_BUS_DEVICE_NAME);
|
||||
strscpy(pnp->device_class, ACPI_BUS_CLASS);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2614,6 +2614,51 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The Marvell 88SE6111/6121/6145 ("Thor") family stops reporting interrupts
|
||||
* for a port when HOST_IRQ_STAT is cleared while PxIS still holds bits: PxIS
|
||||
* keeps its content, HOST_IRQ_STAT reads back as 0, the port is never looked
|
||||
* at again and the command in flight only ends in a timeout. On a 88SE6121
|
||||
* this makes every SATA-2 or SATA-3 disk fail to IDENTIFY, while SATA-1 disks
|
||||
* happen to win the race often enough to work.
|
||||
*
|
||||
* Clearing the host status before servicing the ports avoids it. Marvell's
|
||||
* own driver for these chips does the same and says so ("clear global before
|
||||
* channel"), and ahci_xgene handles its broken edge latch the same way. The
|
||||
* price is at most one spurious interrupt per valid one, which is why this is
|
||||
* not the generic behaviour - see AHCI 1.1 section 10.6.2.
|
||||
*
|
||||
* Link: https://bugzilla.kernel.org/show_bug.cgi?id=216094
|
||||
*/
|
||||
static irqreturn_t ahci_mv_irq_handler(int irq, void *dev_instance)
|
||||
{
|
||||
struct ata_host *host = dev_instance;
|
||||
struct ahci_host_priv *hpriv = host->private_data;
|
||||
void __iomem *mmio = hpriv->mmio;
|
||||
unsigned int rc;
|
||||
u32 irq_stat, irq_masked;
|
||||
|
||||
irq_stat = readl(mmio + HOST_IRQ_STAT);
|
||||
if (!irq_stat)
|
||||
return IRQ_NONE;
|
||||
|
||||
irq_masked = irq_stat & hpriv->port_map;
|
||||
|
||||
spin_lock(&host->lock);
|
||||
|
||||
/*
|
||||
* Use the unmasked value to clear the interrupt, as a spurious pending
|
||||
* event on a dummy port might cause a screaming IRQ.
|
||||
*/
|
||||
writel(irq_stat, mmio + HOST_IRQ_STAT);
|
||||
|
||||
rc = ahci_handle_port_intr(host, irq_masked);
|
||||
|
||||
spin_unlock(&host->lock);
|
||||
|
||||
return IRQ_RETVAL(rc);
|
||||
}
|
||||
|
||||
static void ahci_remap_check(struct pci_dev *pdev, int bar,
|
||||
struct ahci_host_priv *hpriv)
|
||||
{
|
||||
|
|
@ -2917,6 +2962,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
return -ENOMEM;
|
||||
hpriv->flags |= (unsigned long)pi.private_data;
|
||||
|
||||
/* the Marvell "Thor" family needs HOST_IRQ_STAT cleared first */
|
||||
if (board_id == board_ahci_mv)
|
||||
hpriv->irq_handler = ahci_mv_irq_handler;
|
||||
|
||||
/* MCP65 revision A1 and A2 can't do MSI */
|
||||
if (board_id == board_ahci_mcp65 &&
|
||||
(pdev->revision == 0xa1 || pdev->revision == 0xa2))
|
||||
|
|
|
|||
|
|
@ -4823,28 +4823,6 @@ ata_scsi_get_phys_element_status_xlat(struct ata_queued_cmd *qc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ata_scsi_depop_ua_cap_changed_complete(struct ata_queued_cmd *qc)
|
||||
{
|
||||
struct scsi_cmnd *scmd = qc->scsicmd;
|
||||
u8 *cdb = scmd->cmnd;
|
||||
bool is_ata_passthru = cdb[0] == ATA_16 || cdb[0] == ATA_12;
|
||||
bool is_success = qc->err_mask == 0;
|
||||
|
||||
/*
|
||||
* For successful non-passthrough commands, raise a UNIT ATTENTION with
|
||||
* the additional sense code set to CAPACITY DATA HAS CHANGED to be
|
||||
* raised. Note that this should be done only if the capacity has
|
||||
* actually changed, which may not be the case if the element that was
|
||||
* specified for depopulation was already depopulated, or we did not
|
||||
* restore any removed element. But a capacity change unit attention is
|
||||
* harmless, so always raise the unit attention.
|
||||
*/
|
||||
if (is_success && !is_ata_passthru)
|
||||
ata_scsi_set_sense(qc->dev, scmd, UNIT_ATTENTION,
|
||||
UA_CHANGED_ASC, CAPACITY_CHANGED_ASCQ);
|
||||
ata_scsi_qc_complete(qc);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ata_scsi_remove_element_and_truncate_xlat(struct ata_queued_cmd *qc)
|
||||
{
|
||||
|
|
@ -4884,7 +4862,6 @@ ata_scsi_remove_element_and_truncate_xlat(struct ata_queued_cmd *qc)
|
|||
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
|
||||
|
||||
qc->flags |= ATA_QCFLAG_RESULT_TF;
|
||||
qc->complete_fn = ata_scsi_depop_ua_cap_changed_complete;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4937,7 +4914,6 @@ ata_scsi_restore_elements_and_rebuild_xlat(struct ata_queued_cmd *qc)
|
|||
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
|
||||
|
||||
qc->flags |= ATA_QCFLAG_RESULT_TF;
|
||||
qc->complete_fn = ata_scsi_depop_ua_cap_changed_complete;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ int fwnode_property_match_string(const struct fwnode_handle *fwnode,
|
|||
if (nval == 0)
|
||||
return -ENODATA;
|
||||
|
||||
const char **values __free(kfree) = kcalloc(nval, sizeof(*values), GFP_KERNEL);
|
||||
const char **values __free(kfree) = kzalloc_objs(*values, nval);
|
||||
if (!values)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ config DM_KUNIT_TEST
|
|||
config DRIVER_PE_KUNIT_TEST
|
||||
tristate "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
select OF
|
||||
default KUNIT_ALL_TESTS
|
||||
|
||||
config DRIVER_SWNODE_KUNIT_TEST
|
||||
|
|
|
|||
|
|
@ -523,6 +523,9 @@ static void pe_test_child_iteration(struct kunit *test)
|
|||
struct fwnode_handle *child;
|
||||
int error, i, num;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_OF))
|
||||
kunit_skip(test, "requires CONFIG_OF");
|
||||
|
||||
static const struct software_node node = { .name = "sw" };
|
||||
static const struct software_node node1 = { .name = "sw-1", .parent = &node};
|
||||
static const struct software_node node2 = { .name = "sw-2", .parent = &node};
|
||||
|
|
|
|||
|
|
@ -656,7 +656,7 @@ static int __drbd_cfg_context_from_attrs(struct drbd_cfg_context *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_drbd_cfg_context_nl_policy, NULL);
|
||||
|
|
@ -714,7 +714,7 @@ static int __disk_conf_from_attrs(struct disk_conf *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_DISK_CONF_DISABLE_WRITE_SAME + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_DISK_CONF_DISABLE_WRITE_SAME + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_disk_conf_nl_policy, NULL);
|
||||
|
|
@ -871,7 +871,7 @@ static int __res_opts_from_attrs(struct res_opts *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_RES_OPTS_ON_NO_DATA + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_RES_OPTS_ON_NO_DATA + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_res_opts_nl_policy, NULL);
|
||||
|
|
@ -921,7 +921,7 @@ static int __net_conf_from_attrs(struct net_conf *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_NET_CONF_SOCK_CHECK_TIMEO + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_NET_CONF_SOCK_CHECK_TIMEO + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_net_conf_nl_policy, NULL);
|
||||
|
|
@ -1087,7 +1087,7 @@ static int __set_role_parms_from_attrs(struct set_role_parms *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_set_role_parms_nl_policy, NULL);
|
||||
|
|
@ -1133,7 +1133,7 @@ static int __resize_parms_from_attrs(struct resize_parms *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_resize_parms_nl_policy, NULL);
|
||||
|
|
@ -1195,7 +1195,7 @@ static int __start_ov_parms_from_attrs(struct start_ov_parms *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_START_OV_PARMS_OV_STOP_SECTOR + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_START_OV_PARMS_OV_STOP_SECTOR + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_start_ov_parms_nl_policy, NULL);
|
||||
|
|
@ -1245,7 +1245,7 @@ static int __new_c_uuid_parms_from_attrs(struct new_c_uuid_parms *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_new_c_uuid_parms_nl_policy, NULL);
|
||||
|
|
@ -1291,7 +1291,7 @@ static int __disconnect_parms_from_attrs(struct disconnect_parms *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_disconnect_parms_nl_policy, NULL);
|
||||
|
|
@ -1337,7 +1337,7 @@ static int __detach_parms_from_attrs(struct detach_parms *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_DETACH_PARMS_FORCE_DETACH + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_DETACH_PARMS_FORCE_DETACH + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_detach_parms_nl_policy, NULL);
|
||||
|
|
@ -1383,7 +1383,7 @@ static int __resource_info_from_attrs(struct resource_info *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_RESOURCE_INFO_RES_SUSP_FEN + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_RESOURCE_INFO_RES_SUSP_FEN + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_resource_info_nl_policy, NULL);
|
||||
|
|
@ -1441,7 +1441,7 @@ static int __device_info_from_attrs(struct device_info *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_DEVICE_INFO_DEV_DISK_STATE + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_DEVICE_INFO_DEV_DISK_STATE + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_device_info_nl_policy, NULL);
|
||||
|
|
@ -1487,7 +1487,7 @@ static int __connection_info_from_attrs(struct connection_info *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_CONNECTION_INFO_CONN_ROLE + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_CONNECTION_INFO_CONN_ROLE + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_connection_info_nl_policy, NULL);
|
||||
|
|
@ -1537,7 +1537,8 @@ static int __peer_device_info_from_attrs(struct peer_device_info *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb,
|
||||
DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_peer_device_info_nl_policy, NULL);
|
||||
|
|
@ -1599,7 +1600,8 @@ static int __resource_statistics_from_attrs(struct resource_statistics *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb,
|
||||
DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_resource_statistics_nl_policy, NULL);
|
||||
|
|
@ -1645,7 +1647,7 @@ static int __device_statistics_from_attrs(struct device_statistics *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb, DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_device_statistics_nl_policy, NULL);
|
||||
|
|
@ -1743,7 +1745,8 @@ static int __connection_statistics_from_attrs(struct connection_statistics *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb,
|
||||
DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_connection_statistics_nl_policy, NULL);
|
||||
|
|
@ -1789,7 +1792,8 @@ static int __peer_device_statistics_from_attrs(struct peer_device_statistics *s,
|
|||
*ret_nested_attribute_table = NULL;
|
||||
if (!tla)
|
||||
return -ENOMSG;
|
||||
ntb = kcalloc(DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS + 1, sizeof(*ntb), GFP_KERNEL);
|
||||
ntb = kzalloc_objs(*ntb,
|
||||
DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS + 1);
|
||||
if (!ntb)
|
||||
return -ENOMEM;
|
||||
err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_peer_device_statistics_nl_policy, NULL);
|
||||
|
|
|
|||
|
|
@ -458,12 +458,14 @@ static void loop_update_dio_alignment(struct loop_device *lo)
|
|||
* Use the dio alignment of the file system if provided. The incomoing
|
||||
* request's bio_vec is forwarded to the backing file unchanged, so its
|
||||
* required memory alignment becomes the device's dma_alignment when
|
||||
* used for direct-io.
|
||||
* used for direct-io. The file system reports zeroed alignments if the
|
||||
* file can't be used for direct-io at all, so fall back to the block
|
||||
* device limits in that case.
|
||||
*/
|
||||
if (!vfs_getattr(&file->f_path, &st, STATX_DIOALIGN, 0) &&
|
||||
(st.result_mask & STATX_DIOALIGN)) {
|
||||
(st.result_mask & STATX_DIOALIGN) && st.dio_mem_align) {
|
||||
lo->lo_min_dio_size = st.dio_offset_align;
|
||||
lo->lo_dio_mem_align = st.dio_mem_align - 1;
|
||||
lo->lo_dio_mem_align = min(st.dio_mem_align - 1, PAGE_SIZE - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2653,6 +2653,12 @@ static int ublk_ch_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
if (vma->vm_flags & VM_WRITE)
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
* The per-queue command buffer is kernel-written ABI; prevent
|
||||
* the daemon from upgrading to writable via mprotect().
|
||||
*/
|
||||
vm_flags_clear(vma, VM_MAYWRITE);
|
||||
|
||||
end = UBLKSRV_CMD_BUF_OFFSET + ub->dev_info.nr_hw_queues * max_sz;
|
||||
if (phys_off < UBLKSRV_CMD_BUF_OFFSET || phys_off >= end)
|
||||
return -EINVAL;
|
||||
|
|
@ -5390,7 +5396,7 @@ static int __ublk_ctrl_reg_buf(struct ublk_device *ub,
|
|||
page_to_pfn(pages[i + 1]) == pfn + (i - start) + 1)
|
||||
i++;
|
||||
|
||||
range = kzalloc(sizeof(*range), GFP_KERNEL);
|
||||
range = kzalloc_obj(*range);
|
||||
if (!range) {
|
||||
ret = -ENOMEM;
|
||||
goto unwind;
|
||||
|
|
@ -5453,7 +5459,7 @@ static int ublk_ctrl_reg_buf(struct ublk_device *ub,
|
|||
nr_pages = buf_reg.len >> PAGE_SHIFT;
|
||||
|
||||
/* Pin pages before any locks (may sleep) */
|
||||
pages = kvmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL);
|
||||
pages = kvmalloc_objs(*pages, nr_pages);
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -1042,12 +1042,14 @@ static int zloop_get_block_size(struct zloop_device *zlo,
|
|||
* Use the dio alignment of the file system if provided. The incoming
|
||||
* request's bio_vec is forwarded to the backing file unchanged, so its
|
||||
* required memory alignment becomes the device's dma_alignment when
|
||||
* used for direct-io.
|
||||
* used for direct-io. The file system reports zeroed alignments if the
|
||||
* file can't be used for direct-io at all, so fall back to the block
|
||||
* device limits in that case.
|
||||
*/
|
||||
if (!vfs_getattr(&zone->file->f_path, &st, STATX_DIOALIGN, 0) &&
|
||||
(st.result_mask & STATX_DIOALIGN)) {
|
||||
(st.result_mask & STATX_DIOALIGN) && st.dio_mem_align) {
|
||||
zlo->block_size = st.dio_offset_align;
|
||||
zlo->dio_mem_align = st.dio_mem_align - 1;
|
||||
zlo->dio_mem_align = min(st.dio_mem_align - 1, PAGE_SIZE - 1);
|
||||
} else if (sb_bdev) {
|
||||
zlo->block_size = bdev_physical_block_size(sb_bdev);
|
||||
zlo->dio_mem_align = bdev_dma_alignment(sb_bdev);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ static int lz4_setup_params(struct zcomp_params *params)
|
|||
if (!params->dict || !params->dict_sz)
|
||||
return 0;
|
||||
|
||||
dict_stream = kzalloc_obj(*dict_stream, GFP_KERNEL);
|
||||
dict_stream = kzalloc_obj(*dict_stream);
|
||||
if (!dict_stream)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -571,12 +571,44 @@ int btintel_version_info_tlv(struct hci_dev *hdev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(btintel_version_info_tlv);
|
||||
|
||||
static u8 btintel_version_tlv_min_len(u8 type)
|
||||
{
|
||||
switch (type) {
|
||||
case INTEL_TLV_CNVI_TOP:
|
||||
case INTEL_TLV_CNVR_TOP:
|
||||
case INTEL_TLV_CNVI_BT:
|
||||
case INTEL_TLV_CNVR_BT:
|
||||
case INTEL_TLV_BUILD_NUM:
|
||||
case INTEL_TLV_GIT_SHA1:
|
||||
return sizeof(u32);
|
||||
case INTEL_TLV_DEV_REV_ID:
|
||||
case INTEL_TLV_TIME_STAMP:
|
||||
return sizeof(u16);
|
||||
case INTEL_TLV_IMAGE_TYPE:
|
||||
case INTEL_TLV_BUILD_TYPE:
|
||||
case INTEL_TLV_SECURE_BOOT:
|
||||
case INTEL_TLV_OTP_LOCK:
|
||||
case INTEL_TLV_API_LOCK:
|
||||
case INTEL_TLV_DEBUG_LOCK:
|
||||
case INTEL_TLV_LIMITED_CCE:
|
||||
case INTEL_TLV_SBE_TYPE:
|
||||
return sizeof(u8);
|
||||
case INTEL_TLV_MIN_FW:
|
||||
return 3;
|
||||
case INTEL_TLV_OTP_BDADDR:
|
||||
return sizeof(bdaddr_t);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int btintel_parse_version_tlv(struct hci_dev *hdev,
|
||||
struct intel_version_tlv *version,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
/* Consume Command Complete Status field */
|
||||
skb_pull(skb, 1);
|
||||
if (!skb_pull(skb, 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* Event parameters contain multiple TLVs. Read each of them
|
||||
* and only keep the required data. Also, it use existing legacy
|
||||
|
|
@ -596,6 +628,9 @@ int btintel_parse_version_tlv(struct hci_dev *hdev,
|
|||
if (skb->len < tlv->len + sizeof(*tlv))
|
||||
return -EINVAL;
|
||||
|
||||
if (tlv->len < btintel_version_tlv_min_len(tlv->type))
|
||||
return -EINVAL;
|
||||
|
||||
switch (tlv->type) {
|
||||
case INTEL_TLV_CNVI_TOP:
|
||||
version->cnvi_top = get_unaligned_le32(tlv->val);
|
||||
|
|
@ -667,7 +702,7 @@ int btintel_parse_version_tlv(struct hci_dev *hdev,
|
|||
break;
|
||||
case INTEL_TLV_FW_ID:
|
||||
snprintf(version->fw_id, sizeof(version->fw_id),
|
||||
"%s", tlv->val);
|
||||
"%.*s", tlv->len, tlv->val);
|
||||
break;
|
||||
default:
|
||||
/* Ignore rest of information */
|
||||
|
|
@ -686,6 +721,7 @@ static int btintel_read_version_tlv(struct hci_dev *hdev,
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
const u8 param[1] = { 0xFF };
|
||||
int err;
|
||||
|
||||
if (!version)
|
||||
return -EINVAL;
|
||||
|
|
@ -704,10 +740,10 @@ static int btintel_read_version_tlv(struct hci_dev *hdev,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
btintel_parse_version_tlv(hdev, version, skb);
|
||||
err = btintel_parse_version_tlv(hdev, version, skb);
|
||||
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ------- REGMAP IBT SUPPORT ------- */
|
||||
|
|
|
|||
|
|
@ -1696,6 +1696,9 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
|
|||
|
||||
if (unlikely(!(intr_fh | intr_hw))) {
|
||||
/* Ignore interrupt, inta == 0 */
|
||||
bt_warn_ratelimited("Bluetooth: btintel_pcie: Received spurious interrupt\n");
|
||||
btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_AUTOMASK_ST,
|
||||
BIT(entry->entry));
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -307,9 +307,8 @@ static int mrvl_load_firmware(struct hci_dev *hdev, const char *name)
|
|||
err = wait_on_bit_timeout(&mrvl->flags, STATE_FW_REQ_PENDING,
|
||||
TASK_INTERRUPTIBLE,
|
||||
msecs_to_jiffies(2000));
|
||||
if (err == 1) {
|
||||
if (err == -EINTR) {
|
||||
bt_dev_err(hdev, "Firmware load interrupted");
|
||||
err = -EINTR;
|
||||
break;
|
||||
} else if (err) {
|
||||
bt_dev_err(hdev, "Firmware request timeout");
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
|
|||
* Allocate buffer and the sg list. The sg list array is allocated
|
||||
* directly after the port_buffer struct.
|
||||
*/
|
||||
buf = kmalloc_flex(*buf, sg, pages);
|
||||
buf = kmalloc_flex(*buf, sg, pages, gfp);
|
||||
if (!buf)
|
||||
goto fail;
|
||||
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
parent_data = kcalloc(num_parents, sizeof(*parent_data), GFP_KERNEL);
|
||||
parent_data = kzalloc_objs(*parent_data, num_parents);
|
||||
if (!parent_data)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ static void of_mux_clk_setup(struct device_node *node)
|
|||
pr_err("mux-clock %pOFn must have parents\n", node);
|
||||
return;
|
||||
}
|
||||
parent_data = kcalloc(num_parents, sizeof(*parent_data), GFP_KERNEL);
|
||||
parent_data = kzalloc_objs(*parent_data, num_parents);
|
||||
if (!parent_data)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1624,7 +1624,7 @@ static struct freq_attr **get_freq_attrs(void)
|
|||
/* amd_pstate_{max_freq, lowest_nonlinear_freq, highest_perf} should always be visible */
|
||||
BUG_ON(!count);
|
||||
|
||||
attrs = kcalloc(count + 1, sizeof(struct freq_attr *), GFP_KERNEL);
|
||||
attrs = kzalloc_objs(struct freq_attr *, count + 1);
|
||||
if (!attrs)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/device/faux.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/psci.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
|
@ -428,14 +428,14 @@ static int psci_idle_init_cpu(struct device *dev, int cpu)
|
|||
* to register cpuidle driver then rollback to cancel all CPUs
|
||||
* registration.
|
||||
*/
|
||||
static int psci_cpuidle_probe(struct faux_device *fdev)
|
||||
static int psci_cpuidle_probe(struct platform_device *pdev)
|
||||
{
|
||||
int cpu, ret;
|
||||
struct cpuidle_driver *drv;
|
||||
struct cpuidle_device *dev;
|
||||
|
||||
for_each_present_cpu(cpu) {
|
||||
ret = psci_idle_init_cpu(&fdev->dev, cpu);
|
||||
ret = psci_idle_init_cpu(&pdev->dev, cpu);
|
||||
if (ret)
|
||||
goto out_fail;
|
||||
}
|
||||
|
|
@ -455,36 +455,26 @@ static int psci_cpuidle_probe(struct faux_device *fdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct faux_device_ops psci_cpuidle_ops = {
|
||||
static struct platform_driver psci_cpuidle_driver = {
|
||||
.probe = psci_cpuidle_probe,
|
||||
.driver = {
|
||||
.name = "psci-cpuidle",
|
||||
},
|
||||
};
|
||||
|
||||
static bool __init dt_idle_state_present(void)
|
||||
{
|
||||
struct device_node *cpu_node __free(device_node) =
|
||||
of_cpu_device_node_get(cpumask_first(cpu_possible_mask));
|
||||
if (!cpu_node)
|
||||
return false;
|
||||
|
||||
struct device_node *state_node __free(device_node) =
|
||||
of_get_cpu_state_node(cpu_node, 0);
|
||||
if (!state_node)
|
||||
return false;
|
||||
|
||||
return !!of_match_node(psci_idle_state_match, state_node);
|
||||
}
|
||||
|
||||
static int __init psci_idle_init(void)
|
||||
{
|
||||
struct faux_device *fdev;
|
||||
struct platform_device *pdev;
|
||||
int ret;
|
||||
|
||||
if (!dt_idle_state_present())
|
||||
return 0;
|
||||
ret = platform_driver_register(&psci_cpuidle_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fdev = faux_device_create("psci-cpuidle", NULL, &psci_cpuidle_ops);
|
||||
if (!fdev) {
|
||||
pr_err("Failed to create psci-cpuidle device\n");
|
||||
return -ENODEV;
|
||||
pdev = platform_device_register_simple("psci-cpuidle", -1, NULL, 0);
|
||||
if (IS_ERR(pdev)) {
|
||||
platform_driver_unregister(&psci_cpuidle_driver);
|
||||
return PTR_ERR(pdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np,
|
|||
if (!pd)
|
||||
goto out;
|
||||
|
||||
pd->name = kasprintf(GFP_KERNEL, "%pOF", np);
|
||||
pd->name = kstrdup(kbasename(of_node_full_name(np)), GFP_KERNEL);
|
||||
if (!pd->name)
|
||||
goto free_pd;
|
||||
|
||||
|
|
@ -112,7 +112,6 @@ struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np,
|
|||
goto free_name;
|
||||
|
||||
pd->free_states = pd_free_states;
|
||||
pd->name = kbasename(pd->name);
|
||||
pd->states = states;
|
||||
pd->state_count = state_count;
|
||||
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ int eip93_send_req(struct crypto_async_request *async,
|
|||
|
||||
memcpy(iv, reqiv, rctx->ivsize);
|
||||
|
||||
rctx->sa_state = kzalloc(sizeof(*rctx->sa_state), GFP_KERNEL);
|
||||
rctx->sa_state = kzalloc_obj(*rctx->sa_state);
|
||||
if (!rctx->sa_state)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -561,8 +561,7 @@ int eip93_send_req(struct crypto_async_request *async,
|
|||
iv[3] = 0xffffffff;
|
||||
crypto_inc((u8 *)iv, AES_BLOCK_SIZE);
|
||||
|
||||
rctx->sa_state_ctr = kzalloc(sizeof(*rctx->sa_state_ctr),
|
||||
GFP_KERNEL);
|
||||
rctx->sa_state_ctr = kzalloc_obj(*rctx->sa_state_ctr);
|
||||
if (!rctx->sa_state_ctr) {
|
||||
err = -ENOMEM;
|
||||
goto free_sa_state;
|
||||
|
|
|
|||
|
|
@ -59,8 +59,7 @@ static void *qat_zstd_alloc_scratch(void)
|
|||
if (!scratch->literals)
|
||||
goto error;
|
||||
|
||||
scratch->out_seqs = kvcalloc(QAT_MAX_SEQUENCES, sizeof(ZSTD_Sequence),
|
||||
GFP_KERNEL);
|
||||
scratch->out_seqs = kvzalloc_objs(ZSTD_Sequence, QAT_MAX_SEQUENCES);
|
||||
if (!scratch->out_seqs)
|
||||
goto error;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user